Charoit 0 12 апреля, 2012 Опубликовано 12 апреля, 2012 · Жалоба Имеется проект для IAR'a под Атмегу32А, он компилится и работает нормально.. Решил перенести проект в AVR Studio 5.1, не сразу, но получилось, компилится нормально, без ошибок и предупреждений. Однако в железе работать не хочет, микроконтроллер впадает в ступор :( Опытным путем выяснилось, что происходит это во время инициализации 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, в остальном все нормально.. Что делать, не понимаю :( Помогите пжлста.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
navovvol 0 12 апреля, 2012 Опубликовано 12 апреля, 2012 · Жалоба Что значит в ступор? где он зацикливается ? на прерывании по опустошению регистра UDR ? или по резету ? Проверте в компиляторе alt+f7 / Toolchain/ AVR/GNU C Linker / Memory Settings -> поле Initial Stack Address. Должно быть пустым (или впишите RAMend для своего контроллера) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kolobok0 0 12 апреля, 2012 Опубликовано 12 апреля, 2012 · Жалоба ...Сам исходник большой, наверно нет смысла его тут приводить... если термин "ступор" - это зависание , то.... как раз наоборот :) если Вы не видите проблем при инициализации в ввиде циклов, ифов и прочей лабуды - то проблемы в другом. это же очевидно вам или нет? если Вы бы пошли дальше в своих рассуждениях, то достаточно комментировать вашу супер-пупер секретную мигалку светодиодами по блочно и смотреть когда эффект исчезнет(или проявится). дальше делите подозрительный блок лапополам и повторяете тест. и так вы дойдёте до действительно проблемного куска кода. и он будет не в этих строчках скорее всего. если напрячь телепатию - то скорее всего идёт выше инициализация неких прерываний, обработчиков и иже. попробуйте отключить всё кроме вызова этой функции и вы увидите что она тут не причём. (круглый) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Charoit 0 12 апреля, 2012 Опубликовано 12 апреля, 2012 · Жалоба Что значит в ступор? где он зацикливается ? на прерывании по опустошению регистра UDR ? или по резету ? Проверте в компиляторе alt+f7 / Toolchain/ AVR/GNU C Linker / Memory Settings -> поле Initial Stack Address. Должно быть пустым (или впишите RAMend для своего контроллера) Ступор - зависание. Поле Initial Stack Address проверял (как раз прочитал ваш пост об этом на форуме) - было пустым, прописал Ramend - не помогло. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
prottoss 0 12 апреля, 2012 Опубликовано 12 апреля, 2012 · Жалоба По моему, Вам правильно намекнули на счет прерываний - похоже дело не в бите UDRIE а в том, что он разрешает прерывание из за которого и возникает "ступор" Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Charoit 0 12 апреля, 2012 Опубликовано 12 апреля, 2012 · Жалоба если Вы бы пошли дальше в своих рассуждениях, то достаточно комментировать вашу супер-пупер секретную мигалку светодиодами по блочно и смотреть когда эффект исчезнет(или проявится). дальше делите подозрительный блок лапополам и повторяете тест. и так вы дойдёте до действительно проблемного куска кода. и он будет не в этих строчках скорее всего. У меня есть пищалка, включается программно, чтобы определять переход устройства из одного состояния в другое. Ее и использовал для определения проблемного места. Если включать пищалку до записи в регистр UCSRB - пищит, если после записи в этот регистр - уже не пищит. если напрячь телепатию - то скорее всего идёт выше инициализация неких прерываний, обработчиков и иже. попробуйте отключить всё кроме вызова этой функции и вы увидите что она тут не причём. Выше идет вот это (сразу после этих строк вызов 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; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 123 12 апреля, 2012 Опубликовано 12 апреля, 2012 · Жалоба Если включать пищалку до записи в регистр UCSRB - пищит, если после записи в этот регистр - уже не пищит.Контроллер после записи в этот регистр уходит в прерывание UDR. Сразу. Ибо глобально прерывания разрешены, а UDR пуст. Обработчик прерывания написан? Имя его правильное? Он располагается по правильному адресу? Посмотрите в дизассемблере, куда указывает вектор этого прерывания? Что делает обработчик этого прерывания, если учесть, что у вас еще нет данных для передачи? Очень странным выглядит взведение UDRIE в инициализации - обычно его взводят перед отправкой данных, чтобы в обработчике осуществить загрузку UDR из буфера передачи, и сбрасывают после опустошения буфера. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Charoit 0 12 апреля, 2012 Опубликовано 12 апреля, 2012 · Жалоба Контроллер после записи в этот регистр уходит в прерывание UDR. Сразу. Ибо глобально прерывания разрешены, а UDR пуст. Обработчик прерывания написан? Имя его правильное? Он располагается по правильному адресу? Посмотрите в дизассемблере, куда указывает вектор этого прерывания? Что делает обработчик этого прерывания, если учесть, что у вас еще нет данных для передачи? Очень странным выглядит взведение UDRIE в инициализации - обычно его взводят перед отправкой данных, чтобы в обработчике осуществить загрузку UDR из буфера передачи, и сбрасывают после опустошения буфера. Обработчик прерывания (USART__UDRE_vect - правильно понимаю?) не написан.. Взведение бита UDRIE сделано потому, что так было в исходнике, который мне достался по наследству, как уже писал выше, этот проект изначально был сделан в IAR'e, я же решил его перенести в среду AVR Studio. Удивительно, что этот же код работает после IAR'а - hex-файл прошил в контроллер, все функционирует.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 12 апреля, 2012 Опубликовано 12 апреля, 2012 · Жалоба Удивительно, что этот же код работает после IAR'а - hex-файл прошил в контроллер, все функционирует.. В IAR-е возможно все неиспользуемые прерывания заполняются RETI. В AVRGCC jmp BAD_VECTOR. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
hd44780 0 12 апреля, 2012 Опубликовано 12 апреля, 2012 (изменено) · Жалоба Обработчик прерывания (USART__UDRE_vect - правильно понимаю?) не написан.. Оень плохая практика включать прерывания, на которые не реализованы обработчики. Более того, раз обработчика нету, значит программе то прерывание вообще не нужно. Либо уберите тот бит, либо реализуйте обработчик. Иначе всегда будете зависеть от каких-то "подковёрных" особенностей разных компиляторов. И даже не факт, что выйдет какая-то другая версия IARа и в ней будет всё по-старому .... Изменено 12 апреля, 2012 пользователем hd44780 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
fox2trot 0 12 апреля, 2012 Опубликовано 12 апреля, 2012 · Жалоба Оень плохая практика включать прерывания, на которые не реализованы обработчики. Более того, раз обработчика нету, значит программе то прерывание вообще не нужно. Либо уберите тот бит, либо реализуйте обработчик. Иначе всегда будете зависеть от каких-то "подковёрных" особенностей разных компиляторов. И даже не факт, что выйдет какая-то другая версия IARа и в ней будет всё по-старому .... Делается немного проще при отладке - по вектору ставится сброс флага и возврат, а сам обработчик можно дописать позднее, зато не надо лишний раз перепахивать инициализацию. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Charoit 0 12 апреля, 2012 Опубликовано 12 апреля, 2012 (изменено) · Жалоба Оень плохая практика включать прерывания, на которые не реализованы обработчики. Более того, раз обработчика нету, значит программе то прерывание вообще не нужно. Либо уберите тот бит, либо реализуйте обработчик. Если бит убираю - устройство работает неправильно, но похоже, что причина где-то в другом месте.. Видимо, код был написан без учета существования других компиляторов. Буду разбираться дальше. Спасибо всем ответившим, пока есть куда копать :) Изменено 12 апреля, 2012 пользователем Charoit Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 123 12 апреля, 2012 Опубликовано 12 апреля, 2012 · Жалоба В IAR-е возможно все неиспользуемые прерывания заполняются RETI.Возможно (но маловероятно). И что бы нам это дало? Попадаем в обработчик, но поскольку в обработчике не было записи в UDR - флаг не сбрасывается, возвращаемся в основной цикл, выполняем одну ассемблерную инструкцию и снова улетаем в обработчик и так по кругу. Не, это конечно довольно оригинальный способ замедлить выполнение программы в пару десятков раз и запретить все прерывания с более низким приоритетом, но как-то это странно. Если бит убираю - устройство работает неправильноМожет быть этот обработчик там есть, но спрятан в каком-то другом файле? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ILYAUL 0 12 апреля, 2012 Опубликовано 12 апреля, 2012 · Жалоба Взять и написать обработчик UDR одной строкой - тупо отсылать туда 0x00 или 0xFF / Запищит значит в нём дело. И скорее всего дело именно в нём Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 13 апреля, 2012 Опубликовано 13 апреля, 2012 · Жалоба Возможно (но маловероятно). 50 на 50. Если задано IAR-у заполнить - заполнит, не задано - не заполнит. И что бы нам это дало? Попадаем в обработчик, но поскольку в обработчике не было записи в UDR - флаг не сбрасывается, возвращаемся в основной цикл, выполняем одну ассемблерную инструкцию и снова улетаем в обработчик и так по кругу. Не, это конечно довольно оригинальный способ замедлить выполнение программы в пару десятков раз и запретить все прерывания с более низким приоритетом, но как-то это странно. Да, оригинально. Но работать будет. Пока watchdog не сбросит. Может быть этот обработчик там есть, но спрятан в каком-то другом файле? Вариант. Взять и написать обработчик UDR одной строкой - тупо отсылать туда 0x00 или 0xFF / Запищит значит в нём дело. И скорее всего дело именно в нём Или запретить в нём прерывание USART_UDRE. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться