реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Контроллер впадает в ступор.., UART
Charoit
сообщение Apr 12 2012, 12:04
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 48
Регистрация: 10-10-07
Пользователь №: 31 217



Имеется проект для 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 Помогите пжлста..
Go to the top of the page
 
+Quote Post
Navovvol
сообщение Apr 12 2012, 12:20
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 105
Регистрация: 9-09-11
Пользователь №: 67 080



Что значит в ступор? где он зацикливается ? на прерывании по опустошению регистра UDR ? или по резету ?
Проверте в компиляторе alt+f7 / Toolchain/ AVR/GNU C Linker / Memory Settings -> поле Initial Stack Address. Должно быть пустым (или впишите RAMend для своего контроллера)
Go to the top of the page
 
+Quote Post
kolobok0
сообщение Apr 12 2012, 12:24
Сообщение #3


практикующий тех. волшебник
*****

Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417



Цитата(Charoit @ Apr 12 2012, 16:04) *
...Сам исходник большой, наверно нет смысла его тут приводить...


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

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

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

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


(круглый)
Go to the top of the page
 
+Quote Post
Charoit
сообщение Apr 12 2012, 12:33
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 48
Регистрация: 10-10-07
Пользователь №: 31 217



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



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

Поле Initial Stack Address проверял (как раз прочитал ваш пост об этом на форуме) - было пустым, прописал Ramend - не помогло.
Go to the top of the page
 
+Quote Post
prottoss
сообщение Apr 12 2012, 12:39
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(Charoit @ Apr 12 2012, 18:33) *
По моему, Вам правильно намекнули на счет прерываний - похоже дело не в бите UDRIE а в том, что он разрешает прерывание из за которого и возникает "ступор"


--------------------
Go to the top of the page
 
+Quote Post
Charoit
сообщение Apr 12 2012, 12:41
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 48
Регистрация: 10-10-07
Пользователь №: 31 217



Цитата(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;
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 12 2012, 12:57
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



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


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Charoit
сообщение Apr 12 2012, 13:04
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 48
Регистрация: 10-10-07
Пользователь №: 31 217



Цитата(Сергей Борщ @ Apr 12 2012, 15:57) *
Контроллер после записи в этот регистр уходит в прерывание UDR. Сразу. Ибо глобально прерывания разрешены, а UDR пуст. Обработчик прерывания написан? Имя его правильное? Он располагается по правильному адресу? Посмотрите в дизассемблере, куда указывает вектор этого прерывания? Что делает обработчик этого прерывания, если учесть, что у вас еще нет данных для передачи? Очень странным выглядит взведение UDRIE в инициализации - обычно его взводят перед отправкой данных, чтобы в обработчике осуществить загрузку UDR из буфера передачи, и сбрасывают после опустошения буфера.



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

Взведение бита UDRIE сделано потому, что так было в исходнике, который мне достался по наследству, как уже писал выше, этот проект изначально был сделан в IAR'e, я же решил его перенести в среду AVR Studio. Удивительно, что этот же код работает после IAR'а - hex-файл прошил в контроллер, все функционирует..
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Apr 12 2012, 13:41
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(Charoit @ Apr 12 2012, 16:04) *
Удивительно, что этот же код работает после IAR'а - hex-файл прошил в контроллер, все функционирует..

В IAR-е возможно все неиспользуемые прерывания заполняются RETI.
В AVRGCC jmp BAD_VECTOR.
Go to the top of the page
 
+Quote Post
hd44780
сообщение Apr 12 2012, 14:14
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980



Цитата(Charoit @ Apr 12 2012, 16:04) *
Обработчик прерывания (USART__UDRE_vect - правильно понимаю?) не написан..


Оень плохая практика включать прерывания, на которые не реализованы обработчики. Более того, раз обработчика нету, значит программе то прерывание вообще не нужно.
Либо уберите тот бит, либо реализуйте обработчик.
Иначе всегда будете зависеть от каких-то "подковёрных" особенностей разных компиляторов.
И даже не факт, что выйдет какая-то другая версия IARа и в ней будет всё по-старому ....

Сообщение отредактировал hd44780 - Apr 12 2012, 14:17


--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса.
(с) Мария Эдуарда
Go to the top of the page
 
+Quote Post
fox2trot
сообщение Apr 12 2012, 16:34
Сообщение #11


Частый гость
**

Группа: Участник
Сообщений: 87
Регистрация: 22-09-07
Из: Орел
Пользователь №: 30 754



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

Делается немного проще при отладке - по вектору ставится сброс флага и возврат, а сам обработчик можно дописать позднее, зато не надо лишний раз перепахивать инициализацию.
Go to the top of the page
 
+Quote Post
Charoit
сообщение Apr 12 2012, 17:47
Сообщение #12


Участник
*

Группа: Участник
Сообщений: 48
Регистрация: 10-10-07
Пользователь №: 31 217



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



Если бит убираю - устройство работает неправильно, но похоже, что причина где-то в другом месте.. Видимо, код был написан без учета существования других компиляторов.
Буду разбираться дальше. Спасибо всем ответившим, пока есть куда копать sm.gif

Сообщение отредактировал Charoit - Apr 12 2012, 17:48
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 12 2012, 22:14
Сообщение #13


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



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


QUOTE (Charoit @ Apr 12 2012, 20:47) *
Если бит убираю - устройство работает неправильно
Может быть этот обработчик там есть, но спрятан в каком-то другом файле?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Apr 12 2012, 22:25
Сообщение #14


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Взять и написать обработчик UDR одной строкой - тупо отсылать туда 0x00 или 0xFF / Запищит значит в нём дело.
И скорее всего дело именно в нём


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Apr 13 2012, 00:05
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(Сергей Борщ @ 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.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 03:54
Рейтинг@Mail.ru


Страница сгенерированна за 0.01738 секунд с 7
ELECTRONIX ©2004-2016