|
Виснет USART |
|
|
|
Dec 22 2010, 13:34
|
Гуру
     
Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164

|
Господа, ковыряюсь с USART, есть проблемы. Контроллер mega32, 16МГц, настроен USART на 250кбод, 8бит , 2 стоповых бита. Суть программы проста - принимать от FT232R байты, отправлять их по SPI, затем принимать по SPI и отправлять по USART на FT232R. Такой USB-SPI преобразователь. В бесконечном цикле пытаюсь дождаться стартового слова 0xAA. Каждый раз на второй итерации программа замирает. Вот код Код #define TO_cnt 100000 unsigned char TimeOut;
......
void InitUART(void) //Настраивает UART на 250000 бод - настройки взяты из исходника устройства, принцип общения с USART которого я хочу повторить в точности ибо работает с заточенным под него ненастраиваемым софтом {
DDR_RXD =0; DDR_TXD =1; UBRRL = 3;//250кБод при 16 МГц (у оригинального устройства стояло "1" - 250кбод при 8 МГц) UBRRH = 0; UCSRA = 0; UCSRC = (1<<USBS)|(3<<UCSZ0); UCSRB = (1<<RXEN)|(1<<TXEN); }
ubyte RcvUART0(void) //дожидается прихода байта в UART0 и возвращает его { ulong cnt=0; unsigned char dat; PutString("2 "); // очередной запуск функции чтения байта - выводится символ "2" while((((UCSRA)&(1<<RXC))==0) &&(cnt<TO_cnt))cnt++;//ждем приход байта c таймаутом // В ЭТОЙ СТРОКЕ СУДЯ ПО ВСЕМУ И ПРОИСХОДИТ ЗАВИСАНИЕ НА ВТОРОЙ ИТЕРАЦИИ БЕСКОНЕЧНОГО ЦИКЛА В ОСНОВНОЙ ПРОГРАММЕ
if(cnt>=TO_cnt){ PutString("3 "); //если не дождались байта по таймауту, то символ "3" появляется на экране TimeOut=1; return 0; } return UDR; //Возвращаем его }
void SendUART(ubyte data) { while((UCSRA&(1<<UDRE))==0);//ждем освобождения буфера передатчика UDR = data; }
void main()
{
ubyte data; ubyte cnt; InitTFTPort(); InitUART(); SetBackLight(255); ClrScr();
CursorXY(100,50); PutString("Старт");
//ждем команду while(1){ TimeOut = 0; //Таймаут приема одного байта cnt=0; //Ждем, когда придет первый байт пакета if(RcvUART0()==0xAA){ while(TimeOut==0){ data = RcvUART0(); if(TimeOut==0){ // data = Send2SPI(data); if ((data == 0xFF)&&(cnt==0))cnt=10; if (cnt>0){ cnt--; SendUART(data); } } } }; PutString("1 "); //очередная итерация бесконечного цикла - выводится символ "1"
}; } Отлаживаю оригинально, но без JTAG - привык только так. Что означают выводимые на экран символы - читайте выше, в комментария к коду. А на экране появляется строка "Старт 2 3 1 2 3 1 2" Добавлю - в этот момент на USART ничего не передается, отключил передачу сразу как понял что программа не хочет бесконечно ждать символа. Ошибок монтажа точно нет, игрался с терминалом примитивными командами - байты отправляет/байты принимает. Код содрал из оригинальной прошивки, написанной для IAR. Может где и намухлевал, сами знаете, перенос кода мерзкое дело. В чем причина зависания? P.S. выкладываю оригинальную программу для mega48, которую и хочу встроить в другую программу, написанную под CodeVision и mega32.
Сообщение отредактировал zheka - Dec 22 2010, 13:36
|
|
|
|
|
Dec 22 2010, 15:20
|
Гуру
     
Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164

|
defunct, я попробую, а в ознакомьтесь пока с неглючным устройством http://schemov.com/usb2spi/Кроме того, мне непонятно, как может глючить FT232 - что бы он не творил, нормально работающий AVR в строке Код while((((UCSRA)&(1<<RXC))==0) &&(cnt<TO_cnt))cnt++;// рано или поздно завершит цикл, если наступит таймаут по превышению cnt, либо когда завершится прием. Нет... попробовал на 9600 - то же самое. Да и опять таки, причем здесь FT232, если я им даже не пользуюсь, я просто читаю регистр UCSRA.. Провел еще эксперимент - отключил usb кабель, а соответственно и питание FT232 чтобы не смущать AVR - виснет на 2 цикле... Я даже код основного цикла упростил: Код while(1) { data=RcvUART0(); } Все равно виснет
|
|
|
|
|
Dec 22 2010, 16:12
|
Участник

Группа: Участник
Сообщений: 17
Регистрация: 26-03-10
Пользователь №: 56 229

|
Цитата(zheka @ Dec 22 2010, 22:20)  Кроме того, мне непонятно, как может глючить FT232 - что бы он не творил, нормально работающий AVR в строке Код while((((UCSRA)&(1<<RXC))==0) &&(cnt<TO_cnt))cnt++;// рано или поздно завершит цикл, если наступит таймаут по превышению cnt, либо когда завершится прием. Замени лог. условие "&&" на "||" - у тебя UDR не освобождается при выходе из функции.
|
|
|
|
|
Dec 23 2010, 00:56
|
Местный
  
Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940

|
to Fry__ Цитата Замени лог. условие "&&" на "||" - у тебя UDR не освобождается при выходе из функции. С этого места поподробнее!!! Зачем менять "&&" на "||", если надо Лог. И , а не ИЛИ? Если заменить, то "cnt++" станет простой задержкой выхода из цикла даже если байт пришел, а если не придет - то будем ждать его бесконечно to zheka Попробуй переписать функцию так: Код ubyte RcvUART0(void) { unsigned char dat; ulong cnt = 0; PutString("2 "); TimeOut=0; while(!(UCSRA & (1<<RXC))) { if(++cnt>=TO_cnt)) { PutString("3 "); TimeOut=1; break; } } if(TimeOut) dat = 0; else dat = UDR; return dat; //Возвращаем его }
Сообщение отредактировал alexeyv - Dec 23 2010, 01:04
|
|
|
|
|
Dec 23 2010, 01:07
|
Гуру
     
Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164

|
Только что прощупал осциллографом линии TxD и RxD. На линии RxD у меня все время лог.1. Имеется ввиду в покое, когда пытаюсь передать что-то с компа идут импульсы. Это нормально? alexeyv Какая разница? Если виснет при проверке UCSRA? ПРоверил, не работает. Ну и собственно для проверки версии Цитата у тебя UDR не освобождается при выходе из функции. временно сделал принудительное освобождение Код while(((UCSRA & (1<<RXC))==0) && (cnt<TO_cnt)) { dat=UDR; cnt++; } все равно виснет...
|
|
|
|
|
Dec 23 2010, 01:26
|
Местный
  
Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940

|
Каким компилятором пользуешься? Код #define TO_cnt 100000 100000 = 0x186A0 (три байта) влазит ли в ваш ulong ?? как определен ulong? вставьте Код #define TO_cnt 100000UL Проверьте как происходит ожидание в ассемблеровском листинге функции Код На линии RxD у меня все время лог.1. Имеется ввиду в покое, когда пытаюсь передать что-то с компа идут импульсы. Это нормально? А сам то как думаешь? Точно уверен что разводка нормальная??
|
|
|
|
|
Dec 23 2010, 01:50
|
Гуру
     
Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164

|
Цитата Каким компилятором пользуешься? Я пользуюсь codevision 2 Цитата Точно уверен что разводка нормальная?? Ознакомьтесь http://electronix.ru/forum/index.php?showt...75&start=75Да и еще - в чем может быть причина - взгляните внимательно на схему. Заметил одну странность - при выключенном питании устройства если подключить разъем USB то диод D8, на выходе LM317 слабо светиться. Может ошибка в схеме? Исходя из нее может такое быть? Если нет, значит у меня ошибка монтажа или кривой FT232...
|
|
|
|
|
Dec 23 2010, 03:35
|
Знающий
   
Группа: Свой
Сообщений: 559
Регистрация: 6-09-06
Пользователь №: 20 131

|
Цитата На линии RxD у меня все время лог.1. Порылся в талмудах - вообще-то 1 на RxD в покое это нормально.
|
|
|
|
|
Dec 23 2010, 04:42
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(zheka @ Dec 23 2010, 06:51)  Вы еще раз подумайте над тем, что предложили. Я вообще-то не сноб, я проверил на всякий случай - не работает. Предложил он не совсем правильно. Попробуйте где-то так: Код ubyte RcvUART0(void) { ulong cnt=0; unsigned char dat; PutString("2 "); while((((UCSRA)&(1<<RXC))==0) &&(cnt<TO_cnt))cnt++; if(cnt>=TO_cnt){ PutString("3 "); //если не дождались байта по таймауту, то символ "3" появляется на экране TimeOut=1; return 0; } dat = UDR; UCSRA |= 1<<RXC; return dat; //Возвращаем его }
|
|
|
|
|
Dec 23 2010, 05:04
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(_Pasha @ Dec 23 2010, 10:42)  Попробуйте где-то так Автор утверждает, что в то место, что Вы предлагаете изменить, его программа сейчас не должна заходить и не заходит. Это утверждение автора поста хотелось бы проверить... А, попробуйте поставить вывод отладочного символа перед Код return UDR; //Возвращаем его вдруг, Ваша программа всё-таки "дождалась" прихода символа?
|
|
|
|
|
Dec 23 2010, 05:23
|
Гуру
     
Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164

|
Господа, причина, условно говоря найдена. Код написан правильно. Проблема физическая. http://electronix.ru/forum/index.php?showt...75&start=75Посмотрите на схему и плату. Я уже писал выше что какя-то странная проблема имеет место быть - подключаешь кабель USB на выключенное устройство - загорается диод D8 на выходе 5 вольтового стабилизатора, питающего АВР. Может быт в этом проблема? Однако USART виснет даже когда USB кабель отключен. Устойивая работа программы наступает если прикоснуться пальцем между USB разъемом контроллером AVR... А там только блокировочный конденсатор для АВР и контактные площадки для защитных диодов на DP и DM от USB, диоды пока не припаяны. ПРоблема в разводке USB? Но FT232 нормально работает, если в режиме ногодрыганья авр тупо передает сигнал с RxD на TxD - все нормально эхо терминалом ловится. Единицы и нули детектируются когда ножка настроена на прием.. Когда в режиме включенного USART передаем сигнал с АВР на терминал - тоже все ОК. КОгда шлю байт из терминала на АВР, на выходе FT232 TxD - входе AVR RxD сигнал есть, то есть до АВР все нормально. Вот только на втором или третьем байте виснет проверка UCSRA.. или не виснет, если держаться пальцем за обозначенную выше область... Мысли кончились... Гляньте разводку, вдруг я чего не учел.... Как хоть протестировать, где что отпаять, припаять, измерить? Pasha и Палыч, ваши предложения еще вчера были проверены - не помогает. Собственно выше я написал почему.
Сообщение отредактировал zheka - Dec 23 2010, 05:29
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|