Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Прерывание для RS232 на AtMega128
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
Nekromant
Добрый день, уважаемые форумчане.
Возникла задача реализовать общение между контроллером и ПК.
Сама передача работает. т.е контроллер принимает символы и отправляет, но при попытке организовать прерывание по приему символа-оно просто не срабатывает. вот фрагменты кода на строгий суд:
используется отладочная плата STK500
CODE
extern THD44780Service Lcd;
extern char c;

void TDebugSerial::Init() //инициализация USART
{
/* Enable double speed */
UCSR1A = (1 << U2X);
/* Enable receiver, transmitter and interrupts */
UCSR1B = (1 << RXEN1) | (1 << TXEN1) | (1 << RXCIE1);
/* 8 bit data */
UCSR1C = (1 << UCSZ11) | (1 << UCSZ10) ;
/* high byte of UART speed */
UBRR1H = (8000000 /(19200 * 8L) - 1) >> 8;
/* low byte of UART speed */
UBRR1L = (uint8_t)(8000000 / (19200 * 8L)-1);

}
......
ISR(USART1_RX_vect)//организация прерывания по приему символа
{
uint32_t i=98765432; //проверка срабатывания прерывания
Lcd.WriteInt(i); //проверка срабатывания прерывания


}



Lcd.WriteInt(i)---функция вывода на дисплей жк-индикатора-в главных циклах и других функция срабатывает. В этом же прерывании просто молчание и никакой реакции. вместо нее даже пытался менять состояние светодиодов-все равно молчание.
SysRq
Глобально прерывания разрешены? Другие прерывания работают? Как проверяли что USART1 работает?
Nekromant
проверял просто, организовал нечто вроде эха. гипертерминалом отправляю в сторону контроллера символ тот его получает, выводит на свой ЖКИ и отправляет назанд в сторону компа-без прерывания все это отрабатывается без нареканий на различных скоростях.
прерывания скажем от таймера отрабатывают так же без каких либо нареканий
SysRq
TDebugSerial как объявлен? Инициализация точно выполняется? Выведите себе на экран состояние регистров USART1. Собстно, я за этим и спрашивал как USART1 проверяли -- реализацию посмотреть...

http://electronix.ru/forum/index.php?showtopic=55479 smile.gif
Nekromant
забавно, я на самом деле подобную тему уже создавал, но там проблема действительно совершенно не относилась к USART.
здесь же подключен только LCD.в функции Main вообще пустой цикл, который мигает диодами. то есть проблем со стороны быть не должно. завтра попробую тот же самый код, опробовать на другой меге, сравню результаты и выложу здесь же.
DpInRock
Данный код в прерывании имеет шанс сработать ровно один раз. Часто этот один раз возникает еще при инициализации, после которой не делается сброс приемника (просто чтение из регистра приемника для снятия ложного прерывания).

Таким образом этот код имеет немного шансов и на выполнение хотя бы 1 раз.

Где чтение из регистра приемника?
Nekromant
Не совсем понял почему всего один раз и еще и при инициализации, но не суть важно.
мне в данный момент не прочитать символы надо а просто просто вообще понять что контроллер попал в область ISTR().
первоначальный вариант был следующим:
Код
ISR(USART1_RX_vect)//организация прерывания по приему символа
{
char i; //проверка срабатывания прерывания
i=GetChar();
Lcd.WriteInt(i); //проверка срабатывания прерывания

}
Где
char TDebugSerial::GetChar()
{

while(!(UCSR1A & (1 << RXC1)));
return (char)UDR1;//вот здесь и читаем все что надо-в общей программе без прерываний работает, в прерывании же нет.

}
smac
Цитата(Nekromant @ Apr 6 2009, 05:30) *
Не совсем понял почему всего один раз и еще и при инициализации, но не суть важно.
мне в данный момент не прочитать символы надо а просто просто вообще понять что к...


Попробуйте сделать как Вам уже посоветовали - считывать UDR в прерываниях без функции GetChar(), не могу объяснить почему но мне кажется что дело в ней. Считывание UDR обязательно, т. к. только таким образом можно сбросить RXС1.
SysRq
Цитата(DpInRock @ Apr 6 2009, 04:43) *
Данный код в прерывании имеет шанс сработать ровно один раз.

Почему один? Наоборот! МК в прерывании по RXC1 сидеть будет, т.к. флаг RXC1 будет взведен до тех пор пока UDR1 не пуст. Но вы правы в другом: инициализация USART1 и правда кривая, а я внимания не обратил.

Нельзя задавать UBRR и формат фрейма при включенном USART. Включать приемник и передатчик надо в последнюю очередь.

Вызов GetChar() вообще не понятен: указанную функцию класса, да еще и не static, таким макаром не вызвать. Уберите ее, как smac предлагает.
Nekromant
сделал следующим образом:
1-UBRR поставил в самое начало инициализации
2а-попробовал считать без функции GetChar(); просто сразу выдать занчение UDR на дисплей и отправить назад ПК
2б-попробовал считать без функции GetChar(); просто сразу выдать занчение UDR на дисплей
2в-попробовал считать без функции GetChar(); просто сразу занчение UDR отправить назад на ПК
результат один и тот же
провел эксперимент по поводу того что МК будет вечно сидеть в прерывании если UDR не считать-хм результат можно оченить так:
1-либо он воообще прерывания не заметил и не пошел по нему
2- либо зашел и вышел
Потому что основная программа не зависла а отрабатывала свой код без нареканий
Master_MW
Доброго времени суток, чатяне. Некогда сталкивался с той же проблемой, что и автор топика, на том же микроконтроллере. Как показал опыт, - да, действительно, включать USART0 (я использовал USART0, а не USART1 в своём дипломном проекте ) можно только по завершению инициализации скорости передачи и разрешения прерываний по завершению приёма и передачи (другие параметры настройки порта по умолчанию). Код всей программы седующий:

Сей код прекрасно ведет себя как в железе, так и в Proteus'е. Частота внешнего кварца - 1 МГЦ. Скорость передачи 4800 Бод.
Прошу прощения, что поздно, но, возможно кому-то это поможет. Предположу, что исходный код автора статьи не работал из-за неправильно выбранного уровня оптимизации. (Я предпочитаю использовать уровень 0s).

Модератор. Из сообщения удалены огромные цитаты исходного текста потому, что это является грубым нарушением п.3.4. Правил форума. Значительные по объему исходные тексты следует прикреплять к сообщению в виде файлов.
С уважением, rezident
Master_MW
Да, действительно нарушил, прошу прощения... Вот архив с кодом исходной программы:
Нажмите для просмотра прикрепленного файла
В этом архиве необходимый для проекта внешний Makefile:
Нажмите для просмотра прикрепленного файла.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.