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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Прерывание UART
Timofey
сообщение Jun 1 2010, 05:09
Сообщение #1


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

Группа: Участник
Сообщений: 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  
}

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

З.Ы. Как сделать так, чтобы код в посте был компактный (с прокруткой), а не занимал большую часть поста?
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Jun 1 2010, 05:33
Сообщение #2


Беспросветный оптимист
******

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



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

Цитата(Timofey @ Jun 1 2010, 09:09) *
З.Ы. Как сделать так, чтобы код в посте был компактный (с прокруткой), а не занимал большую часть поста?

Используйте тэг
codebox
...
/codebox
Вверху слева менюшка "спец.элементы"


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
Timofey
сообщение Jun 1 2010, 06:14
Сообщение #3


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

Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528



Включил и прерывания и приемник с передатчиком
Код
UCSRB = ((1<<RXEN)|(1<<TXEN)|(1<<RXCIE)|(1<<TXCIE));
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 1 2010, 06:31
Сообщение #4


Гуру
******

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



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


--------------------
На любой вопрос даю любой ответ
"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
GDI
сообщение Jun 1 2010, 06:31
Сообщение #5


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

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



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


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Jun 1 2010, 06:35
Сообщение #6


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

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



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


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

А перед основным циклом программы прерывания разрешили? (команда __enable_interrupt())
Go to the top of the page
 
+Quote Post
Timofey
сообщение Jun 1 2010, 06:42
Сообщение #7


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

Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528



Цитата(Сергей Борщ @ Jun 1 2010, 12:31) *


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

Цитата(GDI @ Jun 1 2010, 12:31) *

В симуляторе получилось следующее:
Сначала загружаются регистры UBRRH, UBRRL, UCSRB. Все значения, которые и требовались
Когда происходить запись в регистр UCSRC, одновременно вижу, что тоже самое и в регистре UBRRH. Но это, я так понимаю, потому что по одному адресу расположены.
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Jun 1 2010, 07:11
Сообщение #8


Беспросветный оптимист
******

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



Цитата(Timofey @ Jun 1 2010, 10:14) *
Включил и прерывания и приемник с передатчиком
Код
UCSRB = ((1<<RXEN)|(1<<TXEN)|(1<<RXCIE)|(1<<TXCIE));

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


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
Timofey
сообщение Jun 1 2010, 07:56
Сообщение #9


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

Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528



Все, заработало. Всем спасибо. Тема закрыта.
Go to the top of the page
 
+Quote Post
Karaox
сообщение Sep 13 2010, 09:19
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 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…»

Помогите понять, что именно я упустил из виду.
Заранее благодарен.
Go to the top of the page
 
+Quote Post
defunct
сообщение Sep 13 2010, 15:20
Сообщение #11


кекс
******

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



Цитата(Karaox @ Sep 13 2010, 12:19) *
Помогите понять, что именно я упустил из виду.


Возможно вы забыли сконфигурировать 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
Go to the top of the page
 
+Quote Post
=GM=
сообщение Sep 13 2010, 15:41
Сообщение #12


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



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

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


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
defunct
сообщение Sep 14 2010, 03:51
Сообщение #13


кекс
******

Группа: Свой
Сообщений: 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 сигнала сообщается модему, что система "готова принимать данные".
Go to the top of the page
 
+Quote Post
Karaox
сообщение Sep 14 2010, 04:28
Сообщение #14


Участник
*

Группа: Участник
Сообщений: 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 стала постоянно высоким, так, кажется, и должно быть.

Буду благодарен за любые советы!
Go to the top of the page
 
+Quote Post
defunct
сообщение Sep 14 2010, 04:52
Сообщение #15


кекс
******

Группа: Свой
Сообщений: 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.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 22nd June 2024 - 20:26
Рейтинг@Mail.ru


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