CodeVision AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
amd9800
Опытный кот
Сообщения: 822
Зарегистрирован: Вс июн 02, 2013 12:23:03

Re: CodeVision AVR в вопросах и ответах

Сообщение amd9800 »

Есть две переменные типа char A,B
и одна переменная int X

хочу записать A как верхний байт в X, а B как нижний.

Самый простой метод который мне приходит в голову это
1. X=A;
2. X=X<<8;
3. X=X|B;

можно объединить 1-й и 2-й шаг в 1, но не уверен что любая оптимизация правильно обработает
X=A<<8;
Если компилятор обработает только 8 бит, то в X попадут одни нули.

Но вопрос собственно не в этом, а как это сделать на Си, экономя на максимум ресурсы процессора и флэш памяти.
Ведь операция смещения на 8 бит в лево это целых 8 операций смещения по 1 разу.

А также необходима обратная операция из int взять данные также загрузив в А верхний байт, а в B нижний и опять самым оптимальным способом.
Может быть с помощью указателей?
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение WiseLord »

Код: Выделить всё

X = (int)A << 8;
X |= B;

Но на самом деле, что этот вариант, что Ваш - разницы никакой. Я практически уверен, что компилятор сведёт это к одному и тому же ассемблерному коду. Причём не будет ничего смещать, а просто положит байты в регистровую пару. Такие вещи, как сдвиги на 8 компилятор делает по-умному. Ему даже можно писать * 256 вместо <<8 - ему всё равно (если, конечно, оптимизация не отключена вообще).

А ещё для таких вещей (интерпретация области памяти по-разному) можно использовать объединение:

Код: Выделить всё

typedef union {
  int X;
  struct {
    char B;
    char A;
  }
} myUnion;

myUnion m;

m.A = 0x34;
m.B = 0x87;

// Теперь m.X равно 0x3487

Иногда бывает удобно, например, при считывании из шины (I2C, SPI, 1-wire) 8-битных величин, которые потом комбинируются автоматически в 16-битные за счёт объединений.
amd9800
Опытный кот
Сообщения: 822
Зарегистрирован: Вс июн 02, 2013 12:23:03

Re: CodeVision AVR в вопросах и ответах

Сообщение amd9800 »

Спасибо за идею.
Кстати codevision ругался (ilegal simbol) и непонятно чего хотел
А атмел студио сразу указала на то что отсутствует точка с запятой в тексте она красная.
typedef union {
int X;
struct {
char B;
char A;
};
} myUnion;

myUnion m;
m.A = 0x34;
m.B = 0x87;
Wasily
Первый раз сказал Мяу!
Сообщения: 30
Зарегистрирован: Пн янв 16, 2012 09:19:44

Re: CodeVision AVR в вопросах и ответах

Сообщение Wasily »

Мужики, подскажите.

Есть пир, отвечающий на команды с компа по RS485.
Уже долго бьюсь, но никак не могу понять почему у меня драйвер adm485 отключается раньше, чем заканчивается передача по UART.
Вот код такой:

case SendStat:
Rs485SendEN=1; //driver on
UCSRA |= (1<<TXC);//sbros flaga txc
printf("%u",Rel1Stat); //esli rele wklucheno otprawlyaem 1
while(!(UCSRA & (1<<TXC)));//zdem konza posilki
Rs485SendEN=0;

Почему то while(!(UCSRA & (1<<TXC))); не работает - где ошибка?

Еще есть вопрос по приему комманд, но это отдельно.
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: CodeVision AVR в вопросах и ответах

Сообщение oleg110592 »

Мужики, подскажите

В родной документации (Mega48) есть пример:
The following code examples show a simple USART transmit function based on polling of the Data Register Empty (UDREn) Flag.

Код: Выделить всё

void USART_Transmit( unsigned char data )
{
  /* Wait for empty transmit buffer */
  while ( !( UCSRnA & (1<<UDREn)) );
  /* Put data into buffer, sends the data */
  UDRn = data;
}

тоже из документации:
Bit 5 – UDREn: USART Data Register Empty
The UDREn Flag indicates if the transmit buffer (UDRn) is ready to receive new data. If UDREn is one, the buffer is empty, and therefore ready to be written.
Wasily
Первый раз сказал Мяу!
Сообщения: 30
Зарегистрирован: Пн янв 16, 2012 09:19:44

Re: CodeVision AVR в вопросах и ответах

Сообщение Wasily »

Так и
The TXC Flag can be used
to check that the Transmitter has completed all transfers, Note that the TXC Flag must be
cleared before each transmission (before UDR is written) if it is used for this purpose.

А The UDR Flag indicates if the transmit buffer (UDRn) is ready to receive new data, но как я понял в шифт регистре все равно есть данные еще, после высылки которых как раз флаг TXC устанавливается.
Wasily
Первый раз сказал Мяу!
Сообщения: 30
Зарегистрирован: Пн янв 16, 2012 09:19:44

Re: CodeVision AVR в вопросах и ответах

Сообщение Wasily »

вот :
A data transmission is initiated by loading the transmit buffer with the data to be transmitted. The
CPU can load the transmit buffer by writing to the UDR I/O location. The buffered data in the
transmit buffer will be moved to the Shift Register when the Shift Register is ready to send a new
frame
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: CodeVision AVR в вопросах и ответах

Сообщение oleg110592 »

Пример от производителя: Application Note AVR306: Using the AVR® UART in C

Код: Выделить всё

/* Read and write functions */
unsigned char ReceiveByte( void )
{
  while ( !(USR & (1<<RXC)) );  /* wait for incomming data */
  /* return the data */
  return UDR;
}
void TransmitByte( unsigned char data )
{
  while ( !(USR & (1<<UDRE)) ); /* wait for empty transmit buffer */
  UDR = data; /* start transmittion */
}

Поскольку передача во времени происходит не мгновенно (биты выходят из передатчика последовательно, друг за другом), то бездумно пихать данные в регистр UDR нельзя - нужно дождаться окончания передачи предыдущего байта. О том, что UDR пуст и готов к приему нового байта, сигнализирует бит UDRE, он же вызовет аппаратное прерывание по опустошению буфера.

http://microsin.net/programming/AVR/uartrs232.html
Wasily
Первый раз сказал Мяу!
Сообщения: 30
Зарегистрирован: Пн янв 16, 2012 09:19:44

Re: CodeVision AVR в вопросах и ответах

Сообщение Wasily »

Так об этом я и не спорю.
Но всё же это для того чтобы понять что можно именно начать передачу (пихать в буфер :)) , т.е. когда пердатчик готов.
Но UDR не говорит нам что ВСЕ биты фышли и стоп бит тоже. Мне же надо знать именно когда вышел стоп бит и можно выключить передатчик DE в ADMке.
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: CodeVision AVR в вопросах и ответах

Сообщение oleg110592 »

вы ж функцией printf не один байт отправляете. Вроде же TXC установится после первого переданного символа, если не успели записать новые данные. У вас есть сброс этого бита в функции putchar? Прерывания другие в вашей программе используются?
Wasily
Первый раз сказал Мяу!
Сообщения: 30
Зарегистрирован: Пн янв 16, 2012 09:19:44

Re: CodeVision AVR в вопросах и ответах

Сообщение Wasily »

Да. Обычно отправляю не один байт.
Прерывания только таймеры. Putchar в теле нет. Пользуюсь готовой библиотекой *.h
Вот так например:
if(CmndSymb[0]==Adres1){
Rs485SendEN=1;
UCSRA |= (1<<TXC);//sbros flaga txc
printf("Status from adres%u\nRel1=%i,Led2Value=%i(pr),TimeTmr=%u(min),", Adres1,Rel1Stat,Led2Value,TimeTmr/845);
// printf("Daytime=%u",Daytime);
while(!(UCSRA & (1<<TXC)));// //poka flag ne ustanowilsya --konez peredachi
Rs485SendEN=0;};
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: CodeVision AVR в вопросах и ответах

Сообщение oleg110592 »

Прерывания только таймеры

Посмотрите как в вашей готовой библиотеке putchar организован. В папке кожевижена есть пример 2usart_lcd - там есть готовый putchar. Если есть прерывания, представим в UDR вы записали данные, далее в putchar ожидаем бит UDRE, но тут произошло прерывание, помешавшее записать новые данные в UDR вовремя - TXC установится.
Wasily
Первый раз сказал Мяу!
Сообщения: 30
Зарегистрирован: Пн янв 16, 2012 09:19:44

Re: CodeVision AVR в вопросах и ответах

Сообщение Wasily »

Wasily писал(а):В папке кожевижена есть пример 2usart_lcd - там есть готовый putchar.

case USART0: // the output will be directed to USART0
while ((UCSR0A & 1<<UDRE)==0);
UDR0=c;

по сути функция ждет освобождения буффера.

Wasily писал(а):Посмотрите как в вашей готовой библиотеке putchar организован.

Как? мало знаний у меня.

Как тогда правильнее решить мою проблему?

Кстати пробывал писать cli и sei - не помогло. Получается таймер не причем...
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение ARV »

по-моему, вам надо ждать, когда оба бита будут установлены UDRE и TXC - это будет означать, что все данные переданы и буфер пуст. после этого можно и выключать драйвер.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Wasily
Первый раз сказал Мяу!
Сообщения: 30
Зарегистрирован: Пн янв 16, 2012 09:19:44

Re: CodeVision AVR в вопросах и ответах

Сообщение Wasily »

ARV писал(а):по-моему, вам надо ждать, когда оба бита будут установлены UDRE и TXC - это будет означать, что все данные переданы и буфер пуст. после этого можно и выключать драйвер.

ок, попробую вскоре
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: CodeVision AVR в вопросах и ответах

Сообщение oleg110592 »

совсем тупой способ - после printf сделать задержку, перед переключением 485, сторона принимающая тоже не должна сразу по приему строки отправлять сразу назад свою передачу. Видел подобное в чужом коде - после записи в UDR, ожидание UDRE, и небольшая программная задержка. Да и сам такое давненько применил - некрасиво, но работает. Наверное можно на прерываниях сделать.
Wasily
Первый раз сказал Мяу!
Сообщения: 30
Зарегистрирован: Пн янв 16, 2012 09:19:44

Re: CodeVision AVR в вопросах и ответах

Сообщение Wasily »

Пробовал, конечно работает. Но как то не профессионально :).
Подбирать под разную скорость надо задержку.
pokk
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

Re: CodeVision AVR в вопросах и ответах

Сообщение pokk »

Недавно сталкивался точно с такой проблемой. Проблема оказалась в том что без использовании прерываний(по TXC) бит TXC не сбрасывается.
т.е после каждой передачи его надо в ручную сбрасывать.
Аватара пользователя
sphincs
Нашел транзистор. Понюхал.
Сообщения: 174
Зарегистрирован: Вт сен 11, 2012 09:13:52
Откуда: Брест, Беларусь
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение sphincs »

где можно взять библиотеку для работы с LCD на HD44780 через I2C расширитель PCF8574 для CV AVR? желательно с пояснениями по ней
DC_DC
Родился
Сообщения: 8
Зарегистрирован: Вс окт 05, 2014 21:11:48

Re: CodeVision AVR в вопросах и ответах

Сообщение DC_DC »

Всем доброго времени суток. У меня тут возник вот такой вопрос. Допустим я ниписал некуюю программу А и программу Б. Программы одинакового характера, но с разными условиями. Пусть это будет даже программы для имерения чего нибудь при помощи АЦП с отображением результатов на ЖКИ. Как сделать так, чтобы после нажатия на кнопку на ЖКИ отображались результаты программы Б а при повторном нажатии опять программа А ну и так далее. Одиночные программы работают. Я думаю лучше использовать внешнее прерывания или всё-таки опрос кнопок? Ещё я думаю что нужно после нажатия на кнопку переходить к соответсвующему программному коду? Я ещё только делаю первые шаги с МК. Буду очень благодарен за помощь.
Ответить

Вернуться в «AVR»