Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Виснет USART
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
zheka
Господа, ковыряюсь с 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.
defunct
Цитата(zheka @ Dec 22 2010, 18:34) *
Господа, ковыряюсь с USART, есть проблемы.

Проблема может быть и со стороны FT232: было замечено, что она малость глючит на скоростях "от 115200".
Предлагаю все эксперименты проделать на 9600.
zheka
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();
}


Все равно виснет
Fry__
Цитата(zheka @ Dec 22 2010, 22:20) *
Кроме того, мне непонятно, как может глючить FT232 - что бы он не творил, нормально работающий AVR в строке
Код
while((((UCSRA)&(1<<RXC))==0) &&(cnt<TO_cnt))cnt++;//


рано или поздно завершит цикл, если наступит таймаут по превышению cnt, либо когда завершится прием.


Замени лог. условие "&&" на "||" - у тебя UDR не освобождается при выходе из функции.
zheka
Код
Замени лог. условие "&&" на "||" - у тебя UDR не освобождается при выходе из функции.

Вы еще раз подумайте над тем, что предложили.
Я вообще-то не сноб, я проверил на всякий случай - не работает.
alexeyv
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;    //Возвращаем его
}
zheka
Только что прощупал осциллографом линии TxD и RxD.
На линии RxD у меня все время лог.1. Имеется ввиду в покое, когда пытаюсь передать что-то с компа идут импульсы. Это нормально?

alexeyv
Какая разница? Если виснет при проверке UCSRA?
ПРоверил, не работает.




Ну и собственно для проверки версии

Цитата
у тебя UDR не освобождается при выходе из функции.



временно сделал принудительное освобождение
Код
while(((UCSRA & (1<<RXC))==0) && (cnt<TO_cnt))
{
dat=UDR;
cnt++;
}


все равно виснет...
alexeyv
Каким компилятором пользуешься?
Код
#define TO_cnt 100000


100000 = 0x186A0 (три байта) влазит ли в ваш ulong ?? как определен ulong?

вставьте
Код
#define TO_cnt 100000UL


Проверьте как происходит ожидание в ассемблеровском листинге функции

Код
На линии RxD у меня все время лог.1. Имеется ввиду в покое, когда пытаюсь передать что-то с компа идут импульсы. Это нормально?


А сам то как думаешь? biggrin.gif

Точно уверен что разводка нормальная??
zheka
Цитата
Каким компилятором пользуешься?

Я пользуюсь codevision 2

Цитата
Точно уверен что разводка нормальная??


Ознакомьтесь http://electronix.ru/forum/index.php?showt...75&start=75


Да и еще - в чем может быть причина - взгляните внимательно на схему. Заметил одну странность - при выключенном питании устройства если подключить разъем USB то диод D8, на выходе LM317 слабо светиться. Может ошибка в схеме? Исходя из нее может такое быть? Если нет, значит у меня ошибка монтажа или кривой FT232...
-=Женек=-
Цитата
На линии RxD у меня все время лог.1.

Порылся в талмудах - вообще-то 1 на RxD в покое это нормально.
_Pasha
Цитата(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;    //Возвращаем его
}
Палыч
Цитата(_Pasha @ Dec 23 2010, 10:42) *
Попробуйте где-то так
Автор утверждает, что в то место, что Вы предлагаете изменить, его программа сейчас не должна заходить и не заходит. Это утверждение автора поста хотелось бы проверить... А, попробуйте поставить вывод отладочного символа перед
Код
    return UDR;    //Возвращаем его
вдруг, Ваша программа всё-таки "дождалась" прихода символа?
zheka
Господа, причина, условно говоря найдена.
Код написан правильно.
Проблема физическая.

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 и Палыч, ваши предложения еще вчера были проверены - не помогает. Собственно выше я написал почему.
alexeyv
У меня в старой схеме:
1. между DP-GND и DM-GND стоят кондеры на 47пФ/50В,
2. диодных бантиков нет,
3. между микросхемами TX/RX развязаны с помощью опторазвязки (ADUM3201BRZ), питание развязано через нее же.
4. Вывод 3V3out подключен только к земле через кондер 0,1мкФ/50в
5. Выводы RESET/VCCI0/VCC подключены через мелкую идуктивность к PWR(на разъеме)
zheka
alexeyv у меня по такой же схеме как и здесь собран USB программатор, который прекрасно работает.
В общем, пока только одна мысль - приду домой перережу дорожку RX и посмотрю - будет ли виснуть.

Вот только каков путь попадания тока от USB на 5-вольтовую трассу...
Это еще разобраться надо, откуда он туда попадает с плюса USB или с сигнального выхода....
Попробовать что ли запитать FT232 от штатного преобразователя?...
Fry__
Цитата(zheka @ Dec 23 2010, 07:51) *
Код
Замени лог. условие "&&" на "||" - у тебя UDR не освобождается при выходе из функции.

Вы еще раз подумайте над тем, что предложили.
Я вообще-то не сноб, я проверил на всякий случай - не работает.


Был не прав.
fantex
При передаче по цепи RxD вывод 9 идет звон и наводки на вывод 8 кварцевого резонатора. Скорее всего из-за этого и виснет. Нужно хотя бы данные выводы (а лучше все) подключать через последовательно включеные резисторы или сборку номиналом 33-51 ом. А лучше всего всю плату проверить на целостность сигналов (звоны, перекрестные наводки).
zheka
Цитата
При передаче по цепи RxD вывод 9 идет звон и наводки на вывод 8 кварцевого резонатора


Надеюсь, вы внимательно читали - глючит даже при отключенном FT232 - он у меня от USB питается.

Предыдущую "угрозу" я выполнил, отпаял дроссель по питанию и подключил питание FT232RL к +5 вольт платы.светодиод при подключении к USB загораться перестал. Но проблемы это не исправило. Работает пару минут, а затем виснет. Лечится прикасанием пальца между USB разъемом и контроллером.

Цитата
При передаче по цепи RxD вывод 9 идет звон и наводки на вывод 8 кварцевого резонатора.



отпаял ножку FT232 от дорожки, ведущей к ножке 9 (RxD) AVR - вроде заработало сначала, минуты две не висло, уж хотел радостную весть писать - нет стало опять виснуть....



Ну вот - настроил контроллер на внутренний RC-генератор, дабы исключить помехи на кварц - все равно виснет...

Цитата
. А лучше всего всю плату проверить на целостность сигналов (звоны, перекрестные наводки).


Контроллер управляет кучей выходов, перекрещивающихся, переплетающихся, переходящих на другой слой - и ничего - дисплеем он управляет часами.
А вот единственные два гр...х Tx и Rx портят всю картину?
Да и у меня пока только питание FT232 и AVR напаяны, больше звенеть нечему. Разве сам контроллер? Так у меня конденсаторы блокировочные стоят, более того, залил этот код на старую-старую плату, сделанную тогда, когда я думал что АВР может питаться от одного любого GND и одного любого VCC на выбор, с преобразователем без конденсаторов на выходе - работает....

А может сам контроллер быть так слелективно неисправным?


Ну наконец-то!!!
тьфу-тьфу, чтоб не сглазить, а то каждый раз, когда у меня заработает и пальцы тянутся написать, что все ОК, тут же опять начинает глючить.

Выявил я причину.
Плата моя располагается на задней поверхности 7-дюймового TFT дисплея. На дисплее сзади плата, на которой развязка для дисплея на рассыпухе и испульсный преобразователь для питания подсветки дисплея. Правда он далеко но все же... Так вот, а кварц я напаял на заднем слое платы, так как отверстия неметаллизированные, а проволочки продевать лень было.
Отцепил дисплей, отвел его подальше - все работает как часы уже 10 минут.

Скажите, металлический экран между дисплеем и платой в будущем спасет отца русской демократии? Я все равно шасии из стали для крепления буду делать.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.