Перейти к содержанию
    

Контроллер - 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  
}

Запускаю терминал, выставляю настройки порта нужные, отправляю один байт - индикатор не горит.

Осцилографом посмотрел, байт до контроллера доходит, но прерывание так и не срабатывает.

Сама программа при этом запускается и работает нормально (другой светодиод моргает). Что нужно еще установить (включить)?

Спасибо.

 

З.Ы. Как сделать так, чтобы код в посте был компактный (с прокруткой), а не занимал большую часть поста?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А разрешить прерывания не забыли?

 

З.Ы. Как сделать так, чтобы код в посте был компактный (с прокруткой), а не занимал большую часть поста?

Используйте тэг

codebox

...

/codebox

Вверху слева менюшка "спец.элементы"

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Включил и прерывания и приемник с передатчиком
Теперь выкиньте цикл while ( !(UCSRA & (1<<RXC)) ); из обработчика прерывания и ту книгу, в которой вы такой пример нашли.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В симуляторе проверьте, все ли регистры реально правильно загружаются.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 __interrupt void Receive_Byte(void)
{
   unsigned char _data;
   PORTD&=~AVR_PIO_D_OK; //по приему хотя бы одного байта, должен загореться индикатор
   while ( !(UCSRA & (1<<RXC)) );
   _data = UDR;
}

 

Не надо тут опрашивать флаг - он сам сбросится.

 

А перед основным циклом программы прерывания разрешили? (команда __enable_interrupt())

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 

Это не книга, это чужой проект дали и велели разобраться, почему нет приема. Цикл выкинул, ничего не поменялось.

 

В симуляторе получилось следующее:

Сначала загружаются регистры UBRRH, UBRRL, UCSRB. Все значения, которые и требовались

Когда происходить запись в регистр UCSRC, одновременно вижу, что тоже самое и в регистре UBRRH. Но это, я так понимаю, потому что по одному адресу расположены.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Включил и прерывания и приемник с передатчиком

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

Глобальный флаг надо разрешить, иначе все остальные будут хлопать впустую.

По умолчанию он запрещён.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Доброго времени суток!

Я новичок в девайсостроении и у меня аналогичный, как мне кажется, случай, только у меня, по-моему, не «глобальное разрешение прерываний».

Помогите, пожалуйста, разобраться в следующем:

В моём устройстве используется МК 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 следующим кодом:

 

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) я осциллографом вижу приходящие биты, но вот прерывания приёма в МК НЕ ВОЗНИКАЕТ! (по прерыванию приёма МК должен перевести одну из свободных ног в высокое состояние – чего не происходит):

 

Код в прерывании:

 

 

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…»

 

Помогите понять, что именно я упустил из виду.

Заранее благодарен.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Помогите понять, что именно я упустил из виду.

 

Возможно вы забыли сконфигурировать UCSRC:

 

    UBRRH = (temp >> 8) & 0x0F;  <-- bod rate
    UBRRL = (temp & 0xFF);

    UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE) | (1 << TXCIE); // interrupt driven config
    UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0); // 8 bit, 1 stop

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Karaox, чтобы сработало Receive Complete interrupt, надо ещё разрешить бит RXC в UCSRA.

 

И зачем вы дёргаете RTS в прерывании по приёму? RTS (цепь 105) нужна для начала передачи в модем, а не для приёма из него.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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 сигнала сообщается модему, что система "готова принимать данные".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Благодарю за ответы.

 

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 стала постоянно высоким, так, кажется, и должно быть.

 

Буду благодарен за любые советы!

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как новичок, я возможно запутался в названии ног. Нога RTS (Request To Send =запрос на передачу) на МК в моём коде названа так мной и физически подключена к входу CTS_BT (Clear To Send = можно передавать), названным так производителем BlueTooth модуля.

Прочитайте документацию на модуль, что предполагает сигнал CTS_BT, т.к. в стандарте двояко...

Обычно достаточно RTS константно держать в 0 весь сеанс связи.

 

Буду благодарен за любые советы!

1. Попробуйте разрешить TXC прерывание, и отправить пару символов чтобы проверить возникают ли TX прерывания.

 

После чего

2. Закоротите пины TX / RX на МК, при этом отключив их от BlueTooth модуля, и повторите отправку - чтобы убедиться возникает ли RXC прерывание в loopback.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...