Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Контроллер впадает в ступор..
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
Charoit
Имеется проект для IAR'a под Атмегу32А, он компилится и работает нормально..

Решил перенести проект в AVR Studio 5.1, не сразу, но получилось, компилится нормально, без ошибок и предупреждений. Однако в железе работать не хочет, микроконтроллер впадает в ступор sad.gif

Опытным путем выяснилось, что происходит это во время инициализации UART, а именно после записи в регистр UCSRB. Причем контроллеру не нравится запись именно бита UDRIE - если его оставить нулем, то ступора не будет (но при этом не будет работать правильно железо)

Сам исходник большой, наверно нет смысла его тут приводить, а функция инициализации UART'a выглядит вот так :

Код
void InitUART()
{

    UCSRA=0x00;

    UCSRB = (1<<RXCIE)|(1<<TXCIE)|(1<<RXEN)|(1<<TXEN)|(1<<UDRIE);  

        UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);

        UBRRH=0;
  
        UBRRL=12;//BAUD=57692.31 (+0.16%) <-baudrate for Fosc=12 MHz и 6 MHz.
  
        UART_RxBufIndex=0;
  
  
}


Даташит на Мегу32А читал, насколько понял, есть особенность только при записи в регистры UCSRC и UBRRH, в остальном все нормально..

Что делать, не понимаю sad.gif Помогите пжлста..
Navovvol
Что значит в ступор? где он зацикливается ? на прерывании по опустошению регистра UDR ? или по резету ?
Проверте в компиляторе alt+f7 / Toolchain/ AVR/GNU C Linker / Memory Settings -> поле Initial Stack Address. Должно быть пустым (или впишите RAMend для своего контроллера)
kolobok0
Цитата(Charoit @ Apr 12 2012, 16:04) *
...Сам исходник большой, наверно нет смысла его тут приводить...


если термин "ступор" - это зависание , то....

как раз наоборот sm.gif если Вы не видите проблем при инициализации в ввиде циклов, ифов и прочей лабуды - то проблемы в другом. это же очевидно вам или нет?

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

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


(круглый)
Charoit
Цитата(Navovvol @ Apr 12 2012, 15:20) *
Что значит в ступор? где он зацикливается ? на прерывании по опустошению регистра UDR ? или по резету ?
Проверте в компиляторе alt+f7 / Toolchain/ AVR/GNU C Linker / Memory Settings -> поле Initial Stack Address. Должно быть пустым (или впишите RAMend для своего контроллера)



Ступор - зависание.

Поле Initial Stack Address проверял (как раз прочитал ваш пост об этом на форуме) - было пустым, прописал Ramend - не помогло.
prottoss
Цитата(Charoit @ Apr 12 2012, 18:33) *
По моему, Вам правильно намекнули на счет прерываний - похоже дело не в бите UDRIE а в том, что он разрешает прерывание из за которого и возникает "ступор"
Charoit
Цитата(kolobok0 @ Apr 12 2012, 15:24) *
если Вы бы пошли дальше в своих рассуждениях, то достаточно комментировать вашу супер-пупер секретную мигалку светодиодами по блочно и смотреть когда эффект исчезнет(или проявится). дальше делите подозрительный блок лапополам и повторяете тест. и так вы дойдёте до действительно проблемного куска кода. и он будет не в этих строчках скорее всего.


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

Цитата(kolobok0 @ Apr 12 2012, 15:24) *
если напрячь телепатию - то скорее всего идёт выше инициализация неких прерываний, обработчиков и иже. попробуйте отключить всё кроме вызова этой функции и вы увидите что она тут не причём.


Выше идет вот это (сразу после этих строк вызов InitUART) :

Код
SREG=0x80;
  GICR=0x00;
  GIFR=0x00;

  MCUCR = 0x80;
  
  
  MCUCSR=0x00;
  
  WDTCR=0x10;
  
  SFIOR=0x00;

  DDRA =0x00; // if '1' --> PORTAn --> OUT;   if '0' --> PORTAn --> IN
  DDRB =0xFF; // if '1' --> PORTBn --> OUT;   if '0' --> PORTBn --> IN
  DDRC =0xFF; // if '1' --> PORTCn --> OUT;   if '0' --> PORTCn --> IN
  DDRD =0x0C; // if '1' --> PORTDn --> OUT;   if '0' --> PORTDn --> IN
  

//******************************************************************************  
  PORTA=0xDF;   // ножку 5 порта А переводим в Z-состояние, на остальных Pull-up
//******************************************************************************  
  
  PORTB=0x00;
  PORTC=0xFF;
  PORTD=PORTD | 0xFC;

  SPCR=0x00;//F0;
  SPSR=0x01;
  //-------     Настройка таймера TIMER0  --------------------------------------
  
  ASSR  = 0x00;
              
  TIMSK = 0x42;
  TCNT0 = 0x00;

  
  TCCR0 = 0x0D;
                
  
  //-------  Кварцевый резонатор  12 МГц  --------------------------------------
  OCR0  = 11;
Сергей Борщ
QUOTE (Charoit @ Apr 12 2012, 15:41) *
Если включать пищалку до записи в регистр UCSRB - пищит, если после записи в этот регистр - уже не пищит.
Контроллер после записи в этот регистр уходит в прерывание UDR. Сразу. Ибо глобально прерывания разрешены, а UDR пуст. Обработчик прерывания написан? Имя его правильное? Он располагается по правильному адресу? Посмотрите в дизассемблере, куда указывает вектор этого прерывания? Что делает обработчик этого прерывания, если учесть, что у вас еще нет данных для передачи? Очень странным выглядит взведение UDRIE в инициализации - обычно его взводят перед отправкой данных, чтобы в обработчике осуществить загрузку UDR из буфера передачи, и сбрасывают после опустошения буфера.
Charoit
Цитата(Сергей Борщ @ Apr 12 2012, 15:57) *
Контроллер после записи в этот регистр уходит в прерывание UDR. Сразу. Ибо глобально прерывания разрешены, а UDR пуст. Обработчик прерывания написан? Имя его правильное? Он располагается по правильному адресу? Посмотрите в дизассемблере, куда указывает вектор этого прерывания? Что делает обработчик этого прерывания, если учесть, что у вас еще нет данных для передачи? Очень странным выглядит взведение UDRIE в инициализации - обычно его взводят перед отправкой данных, чтобы в обработчике осуществить загрузку UDR из буфера передачи, и сбрасывают после опустошения буфера.



Обработчик прерывания (USART__UDRE_vect - правильно понимаю?) не написан..

Взведение бита UDRIE сделано потому, что так было в исходнике, который мне достался по наследству, как уже писал выше, этот проект изначально был сделан в IAR'e, я же решил его перенести в среду AVR Studio. Удивительно, что этот же код работает после IAR'а - hex-файл прошил в контроллер, все функционирует..
_Артём_
Цитата(Charoit @ Apr 12 2012, 16:04) *
Удивительно, что этот же код работает после IAR'а - hex-файл прошил в контроллер, все функционирует..

В IAR-е возможно все неиспользуемые прерывания заполняются RETI.
В AVRGCC jmp BAD_VECTOR.
hd44780
Цитата(Charoit @ Apr 12 2012, 16:04) *
Обработчик прерывания (USART__UDRE_vect - правильно понимаю?) не написан..


Оень плохая практика включать прерывания, на которые не реализованы обработчики. Более того, раз обработчика нету, значит программе то прерывание вообще не нужно.
Либо уберите тот бит, либо реализуйте обработчик.
Иначе всегда будете зависеть от каких-то "подковёрных" особенностей разных компиляторов.
И даже не факт, что выйдет какая-то другая версия IARа и в ней будет всё по-старому ....
fox2trot
Цитата(hd44780 @ Apr 12 2012, 18:14) *
Оень плохая практика включать прерывания, на которые не реализованы обработчики. Более того, раз обработчика нету, значит программе то прерывание вообще не нужно.
Либо уберите тот бит, либо реализуйте обработчик.
Иначе всегда будете зависеть от каких-то "подковёрных" особенностей разных компиляторов.
И даже не факт, что выйдет какая-то другая версия IARа и в ней будет всё по-старому ....

Делается немного проще при отладке - по вектору ставится сброс флага и возврат, а сам обработчик можно дописать позднее, зато не надо лишний раз перепахивать инициализацию.
Charoit
Цитата(hd44780 @ Apr 12 2012, 17:14) *
Оень плохая практика включать прерывания, на которые не реализованы обработчики. Более того, раз обработчика нету, значит программе то прерывание вообще не нужно.
Либо уберите тот бит, либо реализуйте обработчик.



Если бит убираю - устройство работает неправильно, но похоже, что причина где-то в другом месте.. Видимо, код был написан без учета существования других компиляторов.
Буду разбираться дальше. Спасибо всем ответившим, пока есть куда копать sm.gif
Сергей Борщ
QUOTE (_Артём_ @ Apr 12 2012, 16:41) *
В IAR-е возможно все неиспользуемые прерывания заполняются RETI.
Возможно (но маловероятно). И что бы нам это дало? Попадаем в обработчик, но поскольку в обработчике не было записи в UDR - флаг не сбрасывается, возвращаемся в основной цикл, выполняем одну ассемблерную инструкцию и снова улетаем в обработчик и так по кругу. Не, это конечно довольно оригинальный способ замедлить выполнение программы в пару десятков раз и запретить все прерывания с более низким приоритетом, но как-то это странно.


QUOTE (Charoit @ Apr 12 2012, 20:47) *
Если бит убираю - устройство работает неправильно
Может быть этот обработчик там есть, но спрятан в каком-то другом файле?
ILYAUL
Взять и написать обработчик UDR одной строкой - тупо отсылать туда 0x00 или 0xFF / Запищит значит в нём дело.
И скорее всего дело именно в нём
_Артём_
Цитата(Сергей Борщ @ Apr 13 2012, 01:14) *
Возможно (но маловероятно).

50 на 50.
Если задано IAR-у заполнить - заполнит, не задано - не заполнит.

Цитата(Сергей Борщ @ Apr 13 2012, 01:14) *
И что бы нам это дало? Попадаем в обработчик, но поскольку в обработчике не было записи в UDR - флаг не сбрасывается, возвращаемся в основной цикл, выполняем одну ассемблерную инструкцию и снова улетаем в обработчик и так по кругу. Не, это конечно довольно оригинальный способ замедлить выполнение программы в пару десятков раз и запретить все прерывания с более низким приоритетом, но как-то это странно.

Да, оригинально. Но работать будет.
Пока watchdog не сбросит.

Цитата(Сергей Борщ @ Apr 13 2012, 01:14) *
Может быть этот обработчик там есть, но спрятан в каком-то другом файле?

Вариант.


Цитата(ILYAUL @ Apr 13 2012, 01:25) *
Взять и написать обработчик UDR одной строкой - тупо отсылать туда 0x00 или 0xFF / Запищит значит в нём дело.
И скорее всего дело именно в нём


Или запретить в нём прерывание USART_UDRE.
hd44780
Цитата(Charoit @ Apr 12 2012, 20:47) *
Если бит убираю - устройство работает неправильно, но похоже, что причина где-то в другом месте.. Видимо, код был написан без учета существования других компиляторов.


Может там какая-то экзотика вроде подменённого стартового кода, подсовывающего обработчик, либо прилинковыающийся .lib/.obj c этим обработчиком.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.