Страница 341 из 421
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вс июн 21, 2015 09:30:56
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 нижний и опять самым оптимальным способом.
Может быть с помощью указателей?
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вс июн 21, 2015 13:46:17
WiseLord
Но на самом деле, что этот вариант, что Ваш - разницы никакой. Я практически уверен, что компилятор сведёт это к одному и тому же ассемблерному коду. Причём не будет ничего смещать, а просто положит байты в регистровую пару. Такие вещи, как сдвиги на 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-битные за счёт объединений.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вс июн 21, 2015 14:23:23
amd9800
Спасибо за идею.
Кстати codevision ругался (ilegal simbol) и непонятно чего хотел
А атмел студио сразу указала на то что отсутствует точка с запятой в тексте она красная.
typedef union {
int X;
struct {
char B;
char A;
};
} myUnion;
myUnion m;
m.A = 0x34;
m.B = 0x87;
Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт июн 25, 2015 03:45:39
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))); не работает - где ошибка?
Еще есть вопрос по приему комманд, но это отдельно.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт июн 25, 2015 05:43:17
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.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт июн 25, 2015 06:29:06
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 устанавливается.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт июн 25, 2015 06:37:50
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
Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт июн 25, 2015 06:58:42
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
Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт июн 25, 2015 08:26:09
Wasily
Так об этом я и не спорю.
Но всё же это для того чтобы понять что можно именно начать передачу (пихать в буфер

, т.е. когда пердатчик готов.
Но UDR не говорит нам что ВСЕ биты фышли и стоп бит тоже. Мне же надо знать именно когда вышел стоп бит и можно выключить передатчик DE в ADMке.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт июн 25, 2015 08:35:00
oleg110592
вы ж функцией printf не один байт отправляете. Вроде же TXC установится после первого переданного символа, если не успели записать новые данные. У вас есть сброс этого бита в функции putchar? Прерывания другие в вашей программе используются?
Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт июн 25, 2015 08:53:08
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;};
Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт июн 25, 2015 09:01:44
oleg110592
Прерывания только таймеры
Посмотрите как в вашей готовой библиотеке putchar организован. В папке кожевижена есть пример 2usart_lcd - там есть готовый putchar. Если есть прерывания, представим в UDR вы записали данные, далее в putchar ожидаем бит UDRE, но тут произошло прерывание, помешавшее записать новые данные в UDR вовремя - TXC установится.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт июн 25, 2015 09:46:40
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 - не помогло. Получается таймер не причем...
Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт июн 25, 2015 09:52:03
ARV
по-моему, вам надо ждать, когда оба бита будут установлены UDRE и TXC - это будет означать, что все данные переданы и буфер пуст. после этого можно и выключать драйвер.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт июн 25, 2015 10:36:06
Wasily
ARV писал(а):по-моему, вам надо ждать, когда оба бита будут установлены UDRE и TXC - это будет означать, что все данные переданы и буфер пуст. после этого можно и выключать драйвер.
ок, попробую вскоре
Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт июн 25, 2015 11:17:36
oleg110592
совсем тупой способ - после printf сделать задержку, перед переключением 485, сторона принимающая тоже не должна сразу по приему строки отправлять сразу назад свою передачу. Видел подобное в чужом коде - после записи в UDR, ожидание UDRE, и небольшая программная задержка. Да и сам такое давненько применил - некрасиво, но работает. Наверное можно на прерываниях сделать.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт июн 25, 2015 11:29:29
Wasily
Пробовал, конечно работает. Но как то не профессионально

.
Подбирать под разную скорость надо задержку.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вт июн 30, 2015 03:58:29
pokk
Недавно сталкивался точно с такой проблемой. Проблема оказалась в том что без использовании прерываний(по TXC) бит TXC не сбрасывается.
т.е после каждой передачи его надо в ручную сбрасывать.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Ср июл 01, 2015 12:08:07
sphincs
где можно взять библиотеку для работы с LCD на HD44780 через I2C расширитель PCF8574 для CV AVR? желательно с пояснениями по ней
Re: CodeVision AVR в вопросах и ответах
Добавлено: Ср июл 01, 2015 22:51:10
DC_DC
Всем доброго времени суток. У меня тут возник вот такой вопрос. Допустим я ниписал некуюю программу А и программу Б. Программы одинакового характера, но с разными условиями. Пусть это будет даже программы для имерения чего нибудь при помощи АЦП с отображением результатов на ЖКИ. Как сделать так, чтобы после нажатия на кнопку на ЖКИ отображались результаты программы Б а при повторном нажатии опять программа А ну и так далее. Одиночные программы работают. Я думаю лучше использовать внешнее прерывания или всё-таки опрос кнопок? Ещё я думаю что нужно после нажатия на кнопку переходить к соответсвующему программному коду? Я ещё только делаю первые шаги с МК. Буду очень благодарен за помощь.