|
Прерывание UART |
|
|
|
Jun 1 2010, 05:09
|
Частый гость
 
Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528

|
Контроллер - Mega32 16AU Стоит внешний кварц на 16 МГц CKSEL=0F (выбран внешний кварц) Среда программирования IAR for AVR 5.30 Проблема: никак не могу включить прерывание по приему хотя бы одного байта Код #include <iom32.h> #define FOSC 16000000 #define UBRR_9600 (((FOSC/16)/9600)-1) #pragma vector=USART_RXC_vect __interrupt void Receive_Byte(void); __interrupt void Receive_Byte(void) { unsigned char _data; PORTD&=~AVR_PIO_D_OK; //по приему хотя бы одного байта, должен загореться индикатор while ( !(UCSRA & (1<<RXC)) ); _data = UDR; } void Init_UART (void) { Set_DE(0); UBRRH = (unsigned char)(UBRR_9600>>8); UBRRL = (unsigned char)(UBRR_9600); UCSRB = ((1<<RXEN)|(1<<TXEN)|(1<<RXCIE)|(1<<TXCIE)); UCSRC = ((1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)|(1<<UPM1)|(1<<UPM0));//8bit,stop-bit 1, part - ODD } Запускаю терминал, выставляю настройки порта нужные, отправляю один байт - индикатор не горит. Осцилографом посмотрел, байт до контроллера доходит, но прерывание так и не срабатывает. Сама программа при этом запускается и работает нормально (другой светодиод моргает). Что нужно еще установить (включить)? Спасибо. З.Ы. Как сделать так, чтобы код в посте был компактный (с прокруткой), а не занимал большую часть поста?
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 21)
|
Jun 1 2010, 05:33
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
А разрешить прерывания не забыли? Цитата(Timofey @ Jun 1 2010, 09:09)  З.Ы. Как сделать так, чтобы код в посте был компактный (с прокруткой), а не занимал большую часть поста? Используйте тэг codebox ... /codebox Вверху слева менюшка "спец.элементы"
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Jun 1 2010, 06:14
|
Частый гость
 
Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528

|
Включил и прерывания и приемник с передатчиком Код UCSRB = ((1<<RXEN)|(1<<TXEN)|(1<<RXCIE)|(1<<TXCIE));
|
|
|
|
|
Jun 1 2010, 06:42
|
Частый гость
 
Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528

|
Цитата(Сергей Борщ @ Jun 1 2010, 12:31)  Это не книга, это чужой проект дали и велели разобраться, почему нет приема. Цикл выкинул, ничего не поменялось. Цитата(GDI @ Jun 1 2010, 12:31)  В симуляторе получилось следующее: Сначала загружаются регистры UBRRH, UBRRL, UCSRB. Все значения, которые и требовались Когда происходить запись в регистр UCSRC, одновременно вижу, что тоже самое и в регистре UBRRH. Но это, я так понимаю, потому что по одному адресу расположены.
|
|
|
|
|
Jun 1 2010, 07:11
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(Timofey @ Jun 1 2010, 10:14)  Включил и прерывания и приемник с передатчиком Код UCSRB = ((1<<RXEN)|(1<<TXEN)|(1<<RXCIE)|(1<<TXCIE)); Глобальный флаг надо разрешить, иначе все остальные будут хлопать впустую. По умолчанию он запрещён.
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Sep 13 2010, 09:19
|
Участник

Группа: Участник
Сообщений: 15
Регистрация: 6-01-10
Пользователь №: 54 649

|
Доброго времени суток! Я новичок в девайсостроении и у меня аналогичный, как мне кажется, случай, только у меня, по-моему, не «глобальное разрешение прерываний». Помогите, пожалуйста, разобраться в следующем: В моём устройстве используется МК ATMega8L, который связывается по SPI с некоторым сторонним устройством, и по USART с BlueTooth модулем BlueNiceCom IV от AMBER wireless (AMB2300). Ноги USART’a соединены: крест накрест TX_BT (на ВТ-модуле) <--> RXD (на МК), RX_BT <--> TXD, CTS_BT <--> RTS, RTS_BT <--> CTS. RTS (output, active low), CTS (input, active low) – на МК выделенные мной ножки для контроля протокола. СTS на МК фактически не используется. К МК написана прошивка на базе WinAVR 4.1.1 (WinAVR 20070122). МК работает от внутреннего калибруемого RC осциллятора на частоте 2 МГц, конфигурационные биты и калибрующее значение для внутреннего генератора читаются и шьются (как и прошивка) программатором ChipProg-ISP без проблем и ругани со стороны программатора. На старте МК RTS на МК выставляется в low, после чего инициализируется USART следующим кодом: CODE cli();
//9600 на 2000 кГц; UBRRH = 0; UBRRL = 12;
UCSRB = (1<<RXEN) | (1<<TXEN); UCSRB = UCSRB | (1<<RXCIE);
sei();
Скорость, я вроде, установил правильно – проверял по таблице в Datasheet’е ATMega8L, остальные параметра как я понимаю всё тот же Datasheet автоматически выставляются в 8-битовый кадр без чётности и 1 стоп битом, чего собственно и хочется. Далее устройство работает – по прерыванию таймера2 в SPI выдаётся сигнал и принимающее устройство его читает и реагирует как надо, т.е. правильно. Тут проблем нет. Но вот при попытке связаться с этой конструкцией через BlueTooth’у с компа происходит следующее: после отсылки с компа через терминальную программу (порт, формат кадра, чётность и т.п. настроены правильно) на ножке RXD МК (и естественно на TX_BT) я осциллографом вижу приходящие биты, но вот прерывания приёма в МК НЕ ВОЗНИКАЕТ! (по прерыванию приёма МК должен перевести одну из свободных ног в высокое состояние – чего не происходит): Код в прерывании: CODE ISR(USART_RXC_vect) {
PORT_TEST = PORT_TEST | (1<<NUM_TEST); //Тестовая нога;
PORT_RTS = PORT_RTS | (1<<NUM_RTS);
/*код обработки принятого байта*/
PORT_RTS = PORT_RTS & ~(1<<NUM_RTS); } При этом имена прерываний заданы правильно (проверял по инструкции к WinAVR) и компилятор не ругается на то, что это «похоже на misspelled interrupt name…» Помогите понять, что именно я упустил из виду. Заранее благодарен.
|
|
|
|
|
Sep 14 2010, 03:51
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(=GM= @ Sep 13 2010, 18:41)  RTS (цепь 105) нужна для начала передачи в модем, а не для приёма из него. RTS/CTS handshaking Further information: Hardware flow control In older versions of the specification, RS-232's use of the RTS and CTS lines is asymmetric: The DTE asserts RTS to indicate a desire to transmit to the DCE, and the DCE asserts CTS in response to grant permission. This allows for half-duplex modems that disable their transmitters when not required, and must transmit a synchronization preamble to the receiver when they are re-enabled. This scheme is also employed on present-day RS-232 to RS-485 converters, where the RS-232's RTS signal is used to ask the converter to take control of the RS-485 bus - a concept that doesn't otherwise exist in RS-232. There is no way for the DTE to indicate that it is unable to accept data from the DCE. A non-standard symmetric alternative, commonly called "RTS/CTS handshaking," was developed by various equipment manufacturers: CTS indicates permission from the DCE for the DTE to send data to the DCE (and is controlled by the DCE independent of RTS), and RTS indicates permission from the DTE for the DCE to send data to the DTE. This was eventually codified in version RS-232-E (actually TIA-232-E by that time) by defining a new signal, "RTR (Ready to Receive)," which is CCITT V.24 circuit 133. TIA-232-E and the corresponding international standards were updated to show that circuit 133, when implemented, shares the same pin as RTS (Request to Send), and that when 133 is in use, RTS is assumed by the DCE to be ON at all times.[9] Thus, with this alternative usage, one can think of RTS asserted (positive voltage, logic 0) meaning that the DTE is indicating it is "ready to receive" from the DCE, rather than requesting permission from the DCE to send characters to the DCE. Note that equipment using this protocol must be prepared to buffer some extra data, since a transmission may have begun just before the control line state change. Для embedded модемов / bluetooth модулей чаще применяется симметричная схема в виду особенности их принемения - где в системе может не быть досаточно большого буфера чтобы принимать все подряд от модема. С помощью RTS сигнала сообщается модему, что система "готова принимать данные".
|
|
|
|
|
Sep 14 2010, 04:28
|
Участник

Группа: Участник
Сообщений: 15
Регистрация: 6-01-10
Пользователь №: 54 649

|
Благодарю за ответы.
to defunct:
в datasheet’е при описании регистра UCSRC говорится, что значения необходимые для 8 битного кадра с 1 стоп битом асинхронной передачей задаются как значения по умолчанию. Тем не менее, я воспользовался Вашим кодом и задал эти значения явно. К сожалению, к желаемому результату это не привело.
to =GM=:
Опять таки по datasheet’у этот бит описывается как с возможностью только чтения и говориться, что он 0 по умолчанию и что он выставляется автоматически в 1 когда в приёмный буфер (регистр UDR, как я понимаю) приходят данные и они не прочитаны, а как только я их читаю (что я делаю в обработчике прерывания) RXC сбрасывается. Я вставил в код строку UCSRA = UCSRA | (1 << RXC) до начала работы с USATR. Это, к сожалению, также не помогло.
Как новичок, я возможно запутался в названии ног. Нога RTS (Request To Send =запрос на передачу) на МК в моём коде названа так мной и физически подключена к входу CTS_BT (Clear To Send = можно передавать), названным так производителем BlueTooth модуля. Переводя её в высокое состояние я думал запретить приём данных на время обработки принятого байта в прерывании. Собственно, когда я так делал в основном цикле программы – вне прерывания поток данных от BlueTooth модуля действительно был остановлен, а RX стала постоянно высоким, так, кажется, и должно быть.
Буду благодарен за любые советы!
|
|
|
|
|
Sep 14 2010, 04:52
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(Karaox @ Sep 14 2010, 07:28)  Как новичок, я возможно запутался в названии ног. Нога RTS (Request To Send =запрос на передачу) на МК в моём коде названа так мной и физически подключена к входу CTS_BT (Clear To Send = можно передавать), названным так производителем BlueTooth модуля. Прочитайте документацию на модуль, что предполагает сигнал CTS_BT, т.к. в стандарте двояко... Обычно достаточно RTS константно держать в 0 весь сеанс связи. Цитата Буду благодарен за любые советы! 1. Попробуйте разрешить TXC прерывание, и отправить пару символов чтобы проверить возникают ли TX прерывания. После чего 2. Закоротите пины TX / RX на МК, при этом отключив их от BlueTooth модуля, и повторите отправку - чтобы убедиться возникает ли RXC прерывание в loopback.
|
|
|
|
|
Oct 25 2010, 16:59
|
Участник

Группа: Участник
Сообщений: 15
Регистрация: 6-01-10
Пользователь №: 54 649

|
Большое спасибо, За советы. Я разобрался в своём вопросе. Пишу это, для того, чтобы помочь другим новичкам вроде меня избежать аналогичных проблем. В моём случае имела место совокупность ошибок: 1. Прерывание приёма на самом деле всё-таки возникало всё это время, однако, в конце кода его обработки (к сожалению, рассматривать её как источник ошибок я стал слишком поздно) стояла строка вида UCSRB = UCSRB | (1<<UDRIE); разрешающая прерывания освобождения буфера USART, обработчик которого не был объявлен, что является багом. Это вызывало циклический RESERT МК, напрочь стирая все следы возникновения прерываний. Нужно было внимательнее партировать код из доступного примера 2. после того, как я исправил это, USART всё равно принимал/посылал кашу. Виной было то, что я упустил из виду хрестоматийную истину о важности точного клока для UART – я использовал внутренний генератор системного клока для ATMega8L, который по даташиту «не надёжен». Как только я запаял внешний кварцевый резонатор – всё заработало как надо. Удачи всём тем, кто работает с USART’ом. И большое спасибо всем откликнувшимся!
|
|
|
|
|
Oct 26 2010, 10:37
|
Профессионал
    
Группа: Свой
Сообщений: 1 508
Регистрация: 26-06-06
Из: Киев
Пользователь №: 18 364

|
Цитата Виной было то, что я упустил из виду хрестоматийную истину о важности точного клока для UART – я использовал внутренний генератор системного клока для ATMega8L, который по даташиту «не надёжен». По даташиту он "с завода с точностью +/-3%" для Vcc=5В и температуры 25гр. В принципе должно хватать(+/-5% достаточно) и с температурой меняется не сильно. Но скорее всего у Вас не 5В, а 3В при которых частота 1.9МГц +/-3% т.е. еще на 5% ниже. Проблема может решаться алгоритмом автокаллибровки по символам из потока если внешнее устройство первым при включении начинает обмен.
|
|
|
|
|
Oct 26 2010, 19:30
|
Участник

Группа: Участник
Сообщений: 15
Регистрация: 6-01-10
Пользователь №: 54 649

|
Цитата(ArtemKAD @ Oct 26 2010, 14:37)  Но скорее всего у Вас не 5В, а 3В при которых частота 1.9МГц +/-3% т.е. еще на 5% ниже. Да у меня именно 3В и шла каша. Цитата(ArtemKAD @ Oct 26 2010, 14:37)  Проблема может решаться алгоритмом автокаллибровки по символам из потока если внешнее устройство первым при включении начинает обмен. Автокаллибровка – классная идея, спасибо, возьму на вооружение, на будущее. Типа, когда приёмник в начале калибровки знает, что посылает источник, т.е. первые N пакетов и «устанавливает таблицу соответствия».
|
|
|
|
|
Nov 25 2010, 11:37
|
Участник

Группа: Участник
Сообщений: 15
Регистрация: 6-01-10
Пользователь №: 54 649

|
Цитата(ArtemKAD @ Oct 26 2010, 23:43)  Достаточно одного символа в котором N фронтов между которыми меряешь времянку. Перепады можно мерять прерыванием по изменению порта (PCINT). Никак не возьму в толк как может помочь знание таймингов между фронтами в 1 посылке?
|
|
|
|
|
Nov 26 2010, 10:10
|
Участник

Группа: Участник
Сообщений: 15
Регистрация: 6-01-10
Пользователь №: 54 649

|
Цитата(Палыч @ Nov 25 2010, 18:37)  Вот посмотрите это. И пример применения. Большое спасибо!  Обязательно посмотрю.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|