|
код для приема комманд от ПК через СОМ порт и отправки данных обратно |
|
|
|
Feb 17 2011, 05:55
|
Частый гость
 
Группа: Участник
Сообщений: 83
Регистрация: 2-12-05
Пользователь №: 11 688

|
Есть вот такой код(ниже только кусок) для приема комманд от ПК через СОМ порт и отправки данных обратно: Код u08 COMMAND;
UART_INTERRUPT_HANDLER(SIG_UART_RECV) { COMMAND = inb(UDR); blink(); // мигаем ледом }
int main(void) { sei(); // тут убраны разные инициализации
while(1) { // // разная фигня //
if ( COMMAND != 0x00 ) { switch ( COMMAND ) { case GET_TIME: uartSendDT(); //отправляем на ПК время с ds1307 break; case GET_TEMP: uartSendTemp(); //отправляем на ПК температуру с ds1820 break; }//end switch COMMAND = 0x00; } _delay_ms(5); }//end loop
}// end main Так вот, если вместо "разная фигня" есть какой то код, то все работает, если же там пусто, то при опции оптимизатора -О1 работает от случая к случаю, при -О2,О3,Оs не работает вообще. Лед в обработчике прерывания мигает всегда, как положено. Сабж?
Сообщение отредактировал AlexTech - Feb 17 2011, 07:08
|
|
|
|
|
Feb 17 2011, 06:54
|
Частый гость
 
Группа: Участник
Сообщений: 83
Регистрация: 2-12-05
Пользователь №: 11 688

|
volatile не пришло в голову попробовать, работало же, потом отладку убрал и перестало. вечером попробую, спасибо большое ) для поддержания чистоты стиля даже буквы на маленькие изменю )))
Может быть подскажете как лучше всего организовать обмен c ПК в случае когда приходящая команда не из одного байта, а например установка времени, как минимум 3 байта. Понятно что буфер нужен. Но как удобнее/правильнее его формировать из одиноких приходящих байтов и парсить потом, как отслеживать начало и конец команды. Да и честно говоря хотелось бы ответ на ПК отправлять сразу после получения команды, а не потом в цикле. Пробовал switch (command) засунуть прямо в обработчик SIG_UART_RECV, однако несмотря на то, что UDR освобождается, usart не желает ничего отправлять до выхода из прерывания. У меня есть идеи, но какие то кривенькие честно говоря, я уверен что работать будут, но хотелось бы красиво и быстро )))
Сообщение отредактировал AlexTech - Feb 17 2011, 07:09
|
|
|
|
|
Feb 17 2011, 19:18
|
Частый гость
 
Группа: Участник
Сообщений: 83
Регистрация: 2-12-05
Пользователь №: 11 688

|
В общем попробовал Wake прикрутить... Поскольку С версия написана под IAR пришлось немного помудрить, я gcc использую Ну кое как он заработал, однако при нормальной оптимизации из обработчика прерывания SIG_UART1_RECV напрочь вываливается вот этот важный кусок кода: Код if(data_byte == FEND) { Pc_Rx_Pre = data_byte; Pc_Rx_Crc = CRC_INIT; Pc_Rx_Sta = WAIT_ADDR; Do_Crc8(data_byte, &Pc_Rx_Crc); return; } не только в железе, но и в AVR Studio, там даже брэкпоинт не поставить :/ может быть и еще что то отваливается, но пока не проверить, что это такое может быть? (((
|
|
|
|
|
Feb 17 2011, 21:58
|
Частый гость
 
Группа: Участник
Сообщений: 83
Регистрация: 2-12-05
Пользователь №: 11 688

|
В общем полностью переписал в gcc нотации используя куски оригинального кода, заменил все char на uint8_t, добавил поддержку 2х usartов для 128 меги, добавил volatile где явно не хватало, изменил функцию инициализации, все заработало. В файле откуда будем использовать - надо объявить переменные: Код volatile uint8_t Command;
volatile uint8_t Rx_Cmd, Rx_Cnt, Rx_Data[FRAME];
volatile uint8_t Tx_Cmd, Tx_Cnt, Tx_Data[FRAME]; Если кому надо, то вот:
Сообщение отредактировал AlexTech - Feb 18 2011, 12:51
Прикрепленные файлы
wake.rar ( 3.42 килобайт )
Кол-во скачиваний: 41
|
|
|
|
|
Feb 18 2011, 09:37
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(AlexTech @ Feb 18 2011, 00:58)  В файле откуда будем использовать - надо объявить переменные: Немного неправильно с идеологической точки зрения. Все потроха должны быть сокрыты в недрах модуля, а пользователю лишь предоставить минимально необходимый и достаточный интерфейс через заголовочный файл в котором перечисляются прототипы доступных юзеру функций и если требуется extern переменные и прочие енумы. Просить пользователя объявлять кучу переменных, как Вы предлагаете - по меньшей мере некрасиво...
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Feb 18 2011, 12:02
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(AlexTech @ Feb 18 2011, 14:48)  Это не мое решение, так было задумано в оригинале, я не взялся исправлять, меня и так устраивает Вольному воля. Цитата это собственно и есть extern переменные А вот это не понял. Посмотрел приложенный Вами исходник, понял.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Feb 18 2011, 12:04
|
Частый гость
 
Группа: Участник
Сообщений: 83
Регистрация: 2-12-05
Пользователь №: 11 688

|
Ога, потому что сначала смотрим код, потом комментируем Это написано было не для профи, они и так разберутся, да и сами напишут, это для таких как я, кто использует чужие драйвера и либы, в которых профи отлично расписывают как это работает, но совершенно не объясняют как этим пользоваться
Сообщение отредактировал AlexTech - Feb 18 2011, 12:06
|
|
|
|
|
Feb 26 2011, 10:31
|

Местный
  
Группа: Участник
Сообщений: 318
Регистрация: 21-07-06
Из: Минск
Пользователь №: 18 986

|
Есть новая реализация Wake, котрая лучше инкапсулирует данные. http://electronix.ru/forum/index.php?showt...st&p=891230Работа с буфером ведется с помощью функций char Wake_GetByte(void); //читает байт из буфера приема int Wake_GetWord(void); //читает слово из буфера приема long Wake_GetDWord(void); //читает двойное слово из буфера приема и void Wake_AddByte(char  ; //помещает байт в буфер передачи void Wake_AddWord(int w); //помещает слово в буфер передачи void Wake_AddDWord(long dw); //помещает двойное слово в буфер передачи Конечно, оверхед, но ради красоты на него можно пойти.
--------------------
|
|
|
|
|
Feb 26 2011, 23:44
|
Участник

Группа: Участник
Сообщений: 26
Регистрация: 23-02-09
Из: Одесская обл.
Пользователь №: 45 249

|
Цитата(AlexTech @ Feb 17 2011, 07:55)  Есть вот такой код(ниже только кусок) для приема комманд от ПК через СОМ порт и отправки данных обратно: u08 COMMAND; switch ( COMMAND ) Проблема скорее всего в u8 для оператора switch - переменная COMMAND должна быть UINT. Не знаю, какой Вы использовали компилятор, но древний ИАР2.28 в подобном случае хранил адрес перехода в переменой того же типа, что и тип Вашей COMMAND, и соответственно делал переход только в пределах 256 байт.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|