как вывести младший байт в порт
- novarobotix
- Опытный кот
- Сообщения: 759
- Зарегистрирован: Пн май 12, 2014 06:13:33
как вывести младший байт в порт
надо уменьшить время выполнения операции в программе. есть код:
PORTD.0=0;
PORTD.1=1;
PORTD.2=1;
PORTD.3=0;
можно ли эти 4 операции свести к одной? типа:
PORTDL=6;
то есть вывести одной командой первые 4 ноги порта а вторые 4 не трогать
PORTD.0=0;
PORTD.1=1;
PORTD.2=1;
PORTD.3=0;
можно ли эти 4 операции свести к одной? типа:
PORTDL=6;
то есть вывести одной командой первые 4 ноги порта а вторые 4 не трогать
Глупый не задает вопросы. Глупый и так все знает.
Re: как вывести младший байт в порт
Если у контроллера есть такой "регистр", то можно. В даташите не описано? Значит нельзя.novarobotix писал(а):PORTDL=6;
Тут только вариант "чтение - модификация - запись".
Читаешь из порта в регистр, накладываешь маску по AND, добавляешь биты по OR и пишешь обратно в порт.
Либо переделываешь схему! Так чтобы старший полубайт (не байт, как в топике!) ничем не использовался или использовался как вход, или как альтернативная функция.
И тогда пиши смело в PORTD что угодно от 0x00 до 0x0F - одной командой поменяешь все 4 бита.
-
uk8amk
- Поставщик валерьянки для Кота
- Сообщения: 2222
- Зарегистрирован: Вт ноя 27, 2007 11:32:06
- Откуда: Tashkent
Re: как вывести младший байт в порт
Очень сомнительная экономия.
Поразрядный вывод, 4 инструкции:
Жертвуем старшей тетрадой, 2 инструкции:
Чтение-модификация-запись, ещё хуже:
Что выиграли?
Поразрядный вывод, 4 инструкции:
Код: Выделить всё
CBI 0x12,0
; 48 PORTD.1=1;
SBI 0x12,1
; 49 PORTD.2=1;
SBI 0x12,2
; 50 PORTD.3=0;
CBI 0x12,3Жертвуем старшей тетрадой, 2 инструкции:
Код: Выделить всё
; 52 PORTD = 0x06;
LDI R30,LOW(6)
OUT 0x12,R30Чтение-модификация-запись, ещё хуже:
Код: Выделить всё
; 54 PORTD &= ~0x0F;
IN R30,0x12
ANDI R30,LOW(0xF0)
OUT 0x12,R30
; 55 PORTD |= 0x06;
IN R30,0x12
ORI R30,LOW(0x6)
OUT 0x12,R30Что выиграли?
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: как вывести младший байт в порт
uk8amk писал(а):Что выиграли?
ну, если бы вы написали действительно корректную запись чтения-модификации, то результат был бы чуток получше:
Код: Выделить всё
PORTD = PORTD & 0xF0 | 0x06;
результат:
Код: Выделить всё
IN R24,0x12 In from I/O location
ANDI R24,0xF0 Logical AND with immediate
ORI R24,0x06 Logical OR with immediate
OUT 0x12,R24 P.S. и вообще, речь фактически идет о выводе младшей тетрады, а не младшего байта
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- novarobotix
- Опытный кот
- Сообщения: 759
- Зарегистрирован: Пн май 12, 2014 06:13:33
Re: как вывести младший байт в порт
у меня сейчас такой код
хочу заменить на предварительную запись 8 чисел в массив к примеру a[1]=6 a[2]=8 и так 8 раз для каждого шага соответствующая цифра
и потом вызывать в программе вместо всей той бандуры что привёл сверху
одной строкой:
Спойлер
Код: Выделить всё
//начало обработки шагов
if (step==1 & go_step==1)
{
go_step=0;
PORTC.1=1;
PORTC.2=0;
PORTC.3=0;
PORTC.4=0;
}
if (step==2 & go_step==1)
{ go_step=0;
PORTC.1=1;
PORTC.2=1;
PORTC.3=0;
PORTC.4=0;
}
if (step==3 & go_step==1)
{go_step=0;
PORTC.1=0;
PORTC.2=1;
PORTC.3=0;
PORTC.4=0;
}
if (step==4 & go_step==1)
{go_step=0;
PORTC.1=0;
PORTC.2=1;
PORTC.3=1;
PORTC.4=0;
}
if (step==5 & go_step==1)
{ go_step=0;
PORTC.1=0;
PORTC.2=0;
PORTC.3=1;
PORTC.4=0;
}
if (step==6 & go_step==1)
{ go_step=0;
PORTC.1=0;
PORTC.2=0;
PORTC.3=1;
PORTC.4=1;
}
if (step==7 & go_step==1)
{ go_step=0;
PORTC.1=0;
PORTC.2=0;
PORTC.3=0;
PORTC.4=1;
}
if (step==8 & go_step==1)
{ go_step=0;
PORTC.1=1;
PORTC.2=0;
PORTC.3=0;
PORTC.4=1;
} хочу заменить на предварительную запись 8 чисел в массив к примеру a[1]=6 a[2]=8 и так 8 раз для каждого шага соответствующая цифра
и потом вызывать в программе вместо всей той бандуры что привёл сверху
одной строкой:
Код: Выделить всё
PORTC=a[step]Глупый не задает вопросы. Глупый и так все знает.
- oleg110592
- Друг Кота
- Сообщения: 3832
- Зарегистрирован: Сб сен 10, 2011 17:46:25
Re: как вывести младший байт в порт
AVR446: Linear speed control of stepper motor on tinyAVR and megaAVR:
Код: Выделить всё
#define SM_PORT PORTD
#define SM_DRIVE DDRD
#define A1 PD7 //!< Stepper motor winding A positive pole.
#define A2 PD6 //!< Stepper motor winding A negative pole.
#define B1 PD5 //!< Stepper motor winding B positive pole.
#define B2 PD4 //!< Stepper motor winding B negative pole.
....
// Bit position for data in step table
#define BIT_A1 3
#define BIT_A2 2
#define BIT_B1 1
#define BIT_B2 0
//! Table with control signals for stepper motor
__flash unsigned char steptab[] = {((1<<BIT_A1) | (0<<BIT_A2) | (0<<BIT_B1) | (0<<BIT_B2)),
((1<<BIT_A1) | (0<<BIT_A2) | (1<<BIT_B1) | (0<<BIT_B2)),
((0<<BIT_A1) | (0<<BIT_A2) | (1<<BIT_B1) | (0<<BIT_B2)),
((0<<BIT_A1) | (1<<BIT_A2) | (1<<BIT_B1) | (0<<BIT_B2)),
((0<<BIT_A1) | (1<<BIT_A2) | (0<<BIT_B1) | (0<<BIT_B2)),
((0<<BIT_A1) | (1<<BIT_A2) | (0<<BIT_B1) | (1<<BIT_B2)),
((0<<BIT_A1) | (0<<BIT_A2) | (0<<BIT_B1) | (1<<BIT_B2)),
((1<<BIT_A1) | (0<<BIT_A2) | (0<<BIT_B1) | (1<<BIT_B2))};
void sm_driver_StepOutput(unsigned char pos)
{
unsigned char temp = steptab[pos];
// Output the fast way
SM_PORT |= ((temp<<4)&0xF0);
SM_PORT &= ((temp<<4)|0x0F);
}
- novarobotix
- Опытный кот
- Сообщения: 759
- Зарегистрирован: Пн май 12, 2014 06:13:33
Re: как вывести младший байт в порт
ассемблер это хорошо, но я пишу на си под atmega16
Глупый не задает вопросы. Глупый и так все знает.
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: как вывести младший байт в порт
Причём тут ассемблер ?
Что можно объяснить человеку, который даже не знает что такое байт
novarobotix, начните с азов. А конкретно - байт, бит, логические операции, дальше - цифровая электроника. А потом уже садитесь за книгу по языку.
Что можно объяснить человеку, который даже не знает что такое байт
novarobotix, начните с азов. А конкретно - байт, бит, логические операции, дальше - цифровая электроника. А потом уже садитесь за книгу по языку.
- novarobotix
- Опытный кот
- Сообщения: 759
- Зарегистрирован: Пн май 12, 2014 06:13:33
Re: как вывести младший байт в порт
да, ошибся, не младший байт а младшие пол байта.
но смысл понятен, я подробно расписал что нужно.
но смысл понятен, я подробно расписал что нужно.
Глупый не задает вопросы. Глупый и так все знает.
- eess9
- Вымогатель припоя
- Сообщения: 672
- Зарегистрирован: Ср фев 29, 2012 01:58:32
- Откуда: Харьков, Украина
Re: как вывести младший байт в порт
Аlex писал(а):Причём тут ассемблер ?![]()
novarobotix, начните с азов. А конкретно - байт, бит, логические операции, дальше - цифровая электроника. А потом уже садитесь за книгу по языку.
А что мало было ассемблерного кода выше по теме? Или вы его в упор не видите?
novarobotix является радиолюбителем и знает ровно столько, сколько ему на сегодня надо (равно как и любой другой человек). Новое постигается по мере необходимости. Зачем за некорректную терминологию пинать человека ногами?
- novarobotix
- Опытный кот
- Сообщения: 759
- Зарегистрирован: Пн май 12, 2014 06:13:33
Re: как вывести младший байт в порт
я вот думаю на первые 4 ноги порта выводить команды на мотор а вторые 4 ноги порта на ввод(к примеру читать степдир импульсы), но терзают смутные сомнения. если я сконфигурю вторые 4 ноги на ввод и сначала командой я выведу на порт число а потом буду слушать не пришол ли сигнал на ногу порта которая сконфигурена на ввод
повлияет ли то что я перед этим на весь порт вывел?
Код: Выделить всё
PORTC=6 Код: Выделить всё
if (PIND.6==0) {dir=1;} //читаем направление повлияет ли то что я перед этим на весь порт вывел?
Глупый не задает вопросы. Глупый и так все знает.
- zero648
- Вымогатель припоя
- Сообщения: 650
- Зарегистрирован: Пн июн 18, 2012 12:01:04
- Откуда: Челябинская область, Копейск
Re: как вывести младший байт в порт
Думаю не повлияет, если поставите внешние подтягивающие резисторы на входы.
Re: как вывести младший байт в порт
А что об этом говорит даташит на atmega16?novarobotix писал(а):повлияет ли то что я перед этим на весь порт вывел?
Если не ошибаюсь, то оный рассказывает только о подтягивающих резисторах, подключение которых зависит от записи в порт в режиме "нога на чтение".
Итого: в целом может повлиять (при "особенностях" схемы). Но, если в старший полубайт писать всё время одно и то же - то не повлияет.
- novarobotix
- Опытный кот
- Сообщения: 759
- Зарегистрирован: Пн май 12, 2014 06:13:33
Re: как вывести младший байт в порт
mas123 писал(а):Но, если в старший полубайт писать всё время одно и то же - то не повлияет.
какая разница одно и то же пишется или нет? либо влияет либо нет
Глупый не задает вопросы. Глупый и так все знает.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: как вывести младший байт в порт
да, разницы нет никакой, если изучить аппаратную часть и работать с ней корректно.
как известно, направление пинов порта вы задаете регистром DDRx. те пины, для которых в этом регистре установлены единицы, работают на вывод, т.е. будут "мощно" повторять те сигналы, которые вы пишите в PORTx. если же в DDRx для пинов заданы нолики, то эти пины будут работать на ввод, а соответствующие разряды PORTx будут либо включать встроенную подтяжку к плюсу, либо отключать ее.
поэтому для пинов, которые работают на ввод, вы обязаны всегда выводить в PORTx те же самые уровни, что там были до этого - в этом случае ничего не изменится.
итак, у вас старшие 4 бита работают на ввод, а младшие на вывод. чтобы никогда не менять состояние старших, вы должны делать так:
как-то так...
как известно, направление пинов порта вы задаете регистром DDRx. те пины, для которых в этом регистре установлены единицы, работают на вывод, т.е. будут "мощно" повторять те сигналы, которые вы пишите в PORTx. если же в DDRx для пинов заданы нолики, то эти пины будут работать на ввод, а соответствующие разряды PORTx будут либо включать встроенную подтяжку к плюсу, либо отключать ее.
поэтому для пинов, которые работают на ввод, вы обязаны всегда выводить в PORTx те же самые уровни, что там были до этого - в этом случае ничего не изменится.
итак, у вас старшие 4 бита работают на ввод, а младшие на вывод. чтобы никогда не менять состояние старших, вы должны делать так:
Код: Выделить всё
// это маска старшей тетрады. изменяя ее вы можете изменть назначение пинов в порту
#define HI_VAL 0xF0
// это маска младшей тетрады
#define LO_VAL (~HI_VAL)
// это режимы работы старшей тетрады порта
#define HI_MODE 0x80 /* пусть на старшем включена подтяжка, а на остальных - нет */
unsigned char lo_val; // а эта переменная будет у вас содержать выводимые на 4 младших пина сигналы
// нижеследующий код настраивает порт в соответствии с вашими предпочтениями
DDRD = LO_VAL;
PORTD = HI_VAL;
// нижеследующий код обновляет состояние младших 4 битов в порту, не затрагивая старшие
PORTD = HI_VAL | (lo_val & LO_VAL);как-то так...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- novarobotix
- Опытный кот
- Сообщения: 759
- Зарегистрирован: Пн май 12, 2014 06:13:33
Re: как вывести младший байт в порт
я пока решил не заморачиваться с подтягивающими резисторами и прочими тонкостями, сделал просто и топорно
вот весь код
тут кроме самого степдира ещё сделано подключение сглаживающих кандёров на низких скоростях и энкодер для коррекции пропусков, но вроде работает.
настроил первые 4 на выход вторые 4 на вход на 4 и 5 пин подпаял степдирсигналы
задал табличку для вывода на порт младшего полубайта ну и сам вывод одной строкой
в результате общее время выполнения сократилось в полтора раза, учитывая большой остальной код разница существенная. ну и упрощать есть ещё что
у меня есть такое подозрение что скорость также зависит от размера переменной, типа операции с longint выполняются дольше чем с int
в ассемблерный код я попытался въехать, но пока туго, мозги в трубочку сворачиваются
вот весь код
Спойлер
Код: Выделить всё
#include <io.h> // Хотим использовать порты ввода/вывода
#include <delay.h> // Хотим использовать функции задержек
#include <math.h>
#include <string.h>
#include <stdlib.h>
int step=1,temp_step,i,dir,temp,temp_save,step2=1,temp_step2,dir2,temp2,temp_save2,go_step,go_step2,c_on=1,ob,ob_temp,ob_const,c0,corr_count,mig_count,temp_mig_count,correct,cd;
unsigned long int n,k,n2,k2,nfp,nfp2;
unsigned char a[9];
unsigned long int n_prev;
//int p;
eeprom unsigned long int n_eprom,n_eprom2,ob_eprom;
void mig(int v) {
for (i=0; i < v; i++) { //моргаем
PORTB.2=0; delay_us(100000);PORTB.2=1;delay_us(100000);PORTB.2=0;
}
}
void main()
{
DDRA=(0<<DDA7) | (0<<DDA6) | (1<<DDA5) | (1<<DDA4) | (1<<DDA3) | (1<<DDA2) | (1<<DDA1) | (1<<DDA0);
DDRB=(1<<DDB7) | (1<<DDB6) | (1<<DDB5) | (0<<DDB4) | (0<<DDB3) | (1<<DDB2) | (1<<DDB1) | (0<<DDB0);
DDRC=(0<<DDC7) | (0<<DDC6) | (0<<DDC5) | (0<<DDC4) | (1<<DDC3) | (1<<DDC2) | (1<<DDC1) | (1<<DDC0);
DDRD=(0<<DDD7) | (0<<DDD6) | (0<<DDD5) | (1<<DDD4) | (1<<DDD3) | (1<<DDD2) | (1<<DDD1) | (1<<DDD0);
a[1]=1;a[2]=3;a[3]=2;a[4]=6;a[5]=4;a[6]=12;a[7]=8;a[8]=9;
PORTA.0=1; // нормальное питание
nfp=n_eprom;
nfp=47; //вручную задаём момент включения кандёров
nfp2=n_eprom2;
while (1)
{
if (mig_count>0) temp_mig_count=temp_mig_count+1;
if (mig_count>0 & temp_mig_count==500) {PORTB.1=0;} //моргаем число пропусков
if (mig_count>0 & temp_mig_count==1000) {PORTB.1=1;mig_count=mig_count-1;temp_mig_count=0;}
if (PINB.3==1){ob_temp=0;}
if (PINB.3==0 & ob_temp==0 & ob>100 & dir==1){
if (c0==1){
corr_count=ob-400;
if (abs(corr_count)>0) {correct=correct+corr_count;cd=0;mig_count=abs(correct);} //PORTB.1=1;mig_count=mig_count+abs(abs(corr_count)/2);
}
ob_temp=1;
ob=0;
c0=1;
}
if (k>100 || dir==2) cd=1;
if (PINB.0==1 & temp_save==0) {n_eprom=n;nfp=n;temp_save=1;mig(2);} // записываем в память значение включения конденсаторов
if (PINB.0==0) {temp_save=0;} // nfp - значение с которого включаются кандёры X
n2=5;
if (PINB.4==1 & temp_save2==0) {n_eprom2=n2;nfp2=n2;temp_save2=1;mig(2);} // записываем в память значение включения конденсаторов для Y
if (PINB.4==0) {temp_save2=0;} // nfp2 - для Y
/////////////////////////////////////////////// канал Х ......................
if (PINC.5==0) {dir=1;} //читаем направление
if (PINC.5==1) {dir=2;}
if (PINC.4==0) {temp_step=0;} //читем шаг
if (PINC.4==1 & temp_step==0) {
if (nfp>k+2) {
PORTD.0=0; //индицируем выключение кандёров
PORTD.2=0; //выключаем кандёры
}
PORTB.2=0; //индицируем отключение простоя
go_step=1; // пойдём делать шаг
temp_step=1;
n=k;k=0; // обнуляем счётчик и узнаём время между импульсами n
if (correct>=0 || cd==0) { // шаг в одну сторону
if (step==8 & dir==1) {step=1;temp=1;ob=ob+1;};
if (step<8 & dir==1 & temp==0) {
step++;temp=1;ob=ob+1;
}
}
if(dir==1 & correct<0 & cd==1) correct++;
if (correct<=0) { // шаг в другую сторону
if (step>1 & dir==2 & temp==0) {
step--;temp=1;ob=ob-1;
}
if (step==1 & dir==2 & temp==0) {step=8;temp=1;ob=ob-1;}
}
if(dir==2 & correct>0) correct--;
temp=0;
if (ob==-400) ob=0;
}
if ( nfp<n-2 ) {
PORTD.0=1; //индицируем включение кандёров
PORTD.2=1; //включаем кандёры
}
if (k>5000) //режим простоя
{
PORTB.2=1; //индицируем режим простоя
PORTC=0;
//PORTC.1=0; //отключаем обмотки
// PORTC.2=0;
// PORTC.3=0;
// PORTC.4=0;
}
//начало обработки шагов
if (go_step==1) {PORTC=a[step];go_step=0;}
/*
if (step==1 & go_step==1)
{
go_step=0;
PORTC.1=1;
PORTC.2=0;
PORTC.3=0;
PORTC.4=0;
}
if (step==2 & go_step==1)
{ go_step=0;
PORTC.1=1;
PORTC.2=1;
PORTC.3=0;
PORTC.4=0;
}
if (step==3 & go_step==1)
{go_step=0;
PORTC.1=0;
PORTC.2=1;
PORTC.3=0;
PORTC.4=0;
}
if (step==4 & go_step==1)
{go_step=0;
PORTC.1=0;
PORTC.2=1;
PORTC.3=1;
PORTC.4=0;
}
if (step==5 & go_step==1)
{ go_step=0;
PORTC.1=0;
PORTC.2=0;
PORTC.3=1;
PORTC.4=0;
}
if (step==6 & go_step==1)
{ go_step=0;
PORTC.1=0;
PORTC.2=0;
PORTC.3=1;
PORTC.4=1;
}
if (step==7 & go_step==1)
{ go_step=0;
PORTC.1=0;
PORTC.2=0;
PORTC.3=0;
PORTC.4=1;
}
if (step==8 & go_step==1)
{ go_step=0;
PORTC.1=1;
PORTC.2=0;
PORTC.3=0;
PORTC.4=1;
}
*/
if (k<1000000) k=k+1;
if (k2<1000000) k2=k2+1;
}
}тут кроме самого степдира ещё сделано подключение сглаживающих кандёров на низких скоростях и энкодер для коррекции пропусков, но вроде работает.
настроил первые 4 на выход вторые 4 на вход
Код: Выделить всё
DDRC=(0<<DDC7) | (0<<DDC6) | (0<<DDC5) | (0<<DDC4) | (1<<DDC3) | (1<<DDC2) | (1<<DDC1) | (1<<DDC0);задал табличку для вывода на порт младшего полубайта
Код: Выделить всё
a[1]=1;a[2]=3;a[3]=2;a[4]=6;a[5]=4;a[6]=12;a[7]=8;a[8]=9;Код: Выделить всё
if (go_step==1) {PORTC=a[step];go_step=0;} в результате общее время выполнения сократилось в полтора раза, учитывая большой остальной код разница существенная. ну и упрощать есть ещё что
в ассемблерный код я попытался въехать, но пока туго, мозги в трубочку сворачиваются

Глупый не задает вопросы. Глупый и так все знает.
Re: как вывести младший байт в порт
Именно что топорно.novarobotix писал(а):я пока решил не заморачиваться с подтягивающими резисторами и прочими тонкостями, сделал просто и топорно
Открой для себя чудесный мир оптимизацииnovarobotix писал(а):что скорость также зависит от размера переменной,
Мало того, что размер переменной влияет, так ещё влияет и качество написания кода.
Зачем переменные с именем "step***" имеют тип int, если принимают значения куда меньше 0xFF, т.е. идеально укладываются в байт?
Очень сильно советую "въехать". Не нужен уровень "могу на асме написать что угодно", достаточно понимать что компилятор из твоего С-исходника сделал и понимать как быстро это работает и где тормозит.novarobotix писал(а):в ассемблерный код я попытался въехать, но пока туго
Если абсолютное значение больше нуля.... Я правильно понимаю, что это замедленная запись if( 0 != corr_count ) ?novarobotix писал(а):if (abs(corr_count)>0)
Вот просто попробуй себя в роли процессора: три раза подряд проверить: "а вдруг mig_count больше нуля"?novarobotix писал(а):if (mig_count>0) temp_mig_count=temp_mig_count+1;
if (mig_count>0 & temp_mig_count==500) {PORTB.1=0;} //моргаем число пропусков
if (mig_count>0 & temp_mig_count==1000) {PORTB.1=1;mig_count=mig_count-1;temp_mig_count=0;}
- novarobotix
- Опытный кот
- Сообщения: 759
- Зарегистрирован: Пн май 12, 2014 06:13:33
Re: как вывести младший байт в порт
mas123 писал(а):Если абсолютное значение больше нуля.... Я правильно понимаю, что это замедленная запись if( 0 != corr_count ) ?
точно, так и сделаюmas123 писал(а):Зачем переменные с именем "step***" имеют тип int, если принимают значения куда меньше 0xFF, т.е. идеально укладываются в байт?
mas123 писал(а):Вот просто попробуй себя в роли процессора: три раза подряд проверить: "а вдруг mig_count больше нуля"?
щас как раз пытаюсь соптимизировать этот кусок кода
я сначала быстро сделал общий вид, проверил на маленьких скоростях - работает. теперь оптимизация
вообще есть много переменных флагов - принимающих либо 1 либо ноль, но что-то не нашёл в описаниях переменных такого короткого типа переменной.(типа bit)
Глупый не задает вопросы. Глупый и так все знает.
- rxstart1
- Вымогатель припоя
- Сообщения: 508
- Зарегистрирован: Пт фев 22, 2013 18:00:43
- Откуда: Беларусь, г. Гомель
Re: как вывести младший байт в порт
novarobotix писал(а):надо уменьшить время выполнения операции в программе. есть код:
PORTD.0=0;
PORTD.1=1;
PORTD.2=1;
PORTD.3=0;
можно ли эти 4 операции свести к одной? типа:
PORTDL=6;
то есть вывести одной командой первые 4 ноги порта а вторые 4 не трогать
Конечно есть способ обыкновенная маска по &
- novarobotix
- Опытный кот
- Сообщения: 759
- Зарегистрирован: Пн май 12, 2014 06:13:33
Re: как вывести младший байт в порт
rxstart1 писал(а):Конечно есть способ обыкновенная маска по &
я пока непонимаю как это реализовать и насколько это будет быстрее чем сейчас сделано
пока код такой
Спойлер
Код: Выделить всё
#include <io.h> // Хотим использовать порты ввода/вывода
#include <delay.h> // Хотим использовать функции задержек
#include <math.h>
#include <string.h>
#include <stdlib.h>
int ob,corr_count,mig_count,correct;
unsigned int n,k,n2,k2,nfp,nfp2,temp_mig_count;
unsigned char a[9];
unsigned char temp2,temp_save2,temp,temp_save,i,temp_step,temp_step2,step=1,step2=1,dir,dir2,go_step,go_step2,c0,ob_temp,cd;
unsigned int n_prev;
//int p;
eeprom unsigned int n_eprom,n_eprom2,ob_eprom;
void mig(int v) {
for (i=0; i < v; i++) { //моргаем
PORTB.2=0; delay_us(100000);PORTB.2=1;delay_us(100000);PORTB.2=0;
}
}
void main()
{
DDRA=(0<<DDA7) | (0<<DDA6) | (1<<DDA5) | (1<<DDA4) | (1<<DDA3) | (1<<DDA2) | (1<<DDA1) | (1<<DDA0);
DDRB=(1<<DDB7) | (1<<DDB6) | (1<<DDB5) | (0<<DDB4) | (0<<DDB3) | (1<<DDB2) | (1<<DDB1) | (0<<DDB0);
DDRC=(0<<DDC7) | (0<<DDC6) | (0<<DDC5) | (0<<DDC4) | (1<<DDC3) | (1<<DDC2) | (1<<DDC1) | (1<<DDC0);
DDRD=(0<<DDD7) | (0<<DDD6) | (0<<DDD5) | (1<<DDD4) | (1<<DDD3) | (1<<DDD2) | (1<<DDD1) | (1<<DDD0);
a[1]=1;a[2]=3;a[3]=2;a[4]=6;a[5]=4;a[6]=12;a[7]=8;a[8]=9;
PORTA.0=1; // нормальное питание
nfp=n_eprom;
nfp=84; //вручную задаём момент включения кандёров
nfp2=n_eprom2;
while (1)
{
if (mig_count>0) temp_mig_count=temp_mig_count+1;
if (temp_mig_count==2500) {PORTB.1=0;} //моргаем число пропусков
if (temp_mig_count==5000) {PORTB.1=1;mig_count=mig_count-1;temp_mig_count=0;}
if (PINB.3==1){ob_temp=0;}
if (PINB.3==0 & ob_temp==0 & ob>100 & dir==1){
if (c0==1){
corr_count=ob-400;
if (corr_count!=0) {correct=correct+corr_count;cd=0;mig_count=abs(correct);} //PORTB.1=1;mig_count=mig_count+abs(abs(corr_count)/2);
}
ob_temp=1;
ob=0;
c0=1;
}
if (k>100 || dir==2) cd=1; // смотрим если менялось направление или была пауза чтобы скорректировать шаги
if (PINB.0==1 & temp_save==0) {n_eprom=n;nfp=n;temp_save=1;mig(2);} // записываем в память значение включения конденсаторов
if (PINB.0==0) {temp_save=0;} // nfp - значение с которого включаются кандёры X
n2=5;
if (PINB.4==1 & temp_save2==0) {n_eprom2=n2;nfp2=n2;temp_save2=1;mig(2);} // записываем в память значение включения конденсаторов для Y
if (PINB.4==0) {temp_save2=0;} // nfp2 - для Y
/////////////////////////////////////////////// канал Х ......................
if (PINC.5==0) {dir=1;} //читаем направление
if (PINC.5==1) {dir=2;}
if (PINC.4==0) {temp_step=0;} //читем шаг
if (PINC.4==1 & temp_step==0) {
if (nfp>k+2) {
PORTD.0=0; //индицируем выключение кандёров
PORTD.2=0; //выключаем кандёры
}
PORTB.2=0; //индицируем отключение простоя
go_step=1; // пойдём делать шаг
temp_step=1;
n=k;k=0; // обнуляем счётчик и узнаём время между импульсами n
if (correct>=0 || cd==0) { // шаг в одну сторону если нет коррекции
if (step==8 & dir==1) {step=1;temp=1;ob=ob+1;};
if (step<8 & dir==1 & temp==0) {
step++;temp=1;ob=ob+1;
}
}
if(dir==1 & correct<0 & cd==1) correct++;
if (correct<=0) { // шаг в другую сторону если нет коррекции
if (step>1 & dir==2 & temp==0) {
step--;temp=1;ob=ob-1;
}
if (step==1 & dir==2 & temp==0) {step=8;temp=1;ob=ob-1;}
}
if(dir==2 & correct>0) correct--;
temp=0;
if (ob==-400) ob=0;
PORTC=a[step]; //выводим на мотор
}
if ( nfp<n-2 ) {
PORTD.0=1; //индицируем включение кандёров
PORTD.2=1; //включаем кандёры
}
if (k>5000) //режим простоя
{
PORTB.2=1; //индицируем режим простоя
PORTC=0; //отключаем обмотки
}
if (k<10000) k=k+1;
if (k2<10000) k2=k2+1;
}
}
Глупый не задает вопросы. Глупый и так все знает.