UART приемник

Обсуждаем контроллеры компании Atmel.
Ответить
Аватара пользователя
sphincs
Нашел транзистор. Понюхал.
Сообщения: 174
Зарегистрирован: Вт сен 11, 2012 09:13:52
Откуда: Брест, Беларусь
Контактная информация:

UART приемник

Сообщение sphincs »

Добрый день. задачка у меня такая простенькая для начала. мега32 периодически передает по uart данные, которые нужно принять мегой8 и вывести на дисплей. решил для начала для упрощения передавать целиком строку (хотя нужно 7-8 символов, а не 20 как в строке)

Код: Выделить всё

unsigned char d[]={'.','.','.','0','m','s','.','.','.','.','.','.','.','.','3','0','s','.','.','.'};

void USART_transmitter(unsigned char data)
    {
        while ( ! ( UCSRA & (1<<UDRE)))
        ;
        UCSRB &= ~(1<<TXB8);
        if ( data & 0x100)
            UCSRB |= (1<<TXB8);
        UDR = data;
    }  
в ходе программы я получаю нужные значения, ставлю их в нужное место в этот массив и передаю

Код: Выделить всё

for (m=0;m<20;m++)
USART_transmitter(d[m]);
тут вроде все прозрачно. а вот с приемником все куда хуже. сначала меня испугало то количество кода инициализации, которое сгенерил кодвижн. я пытался прикинуть куда мне нужно дописать свой код вывода на экран, дописал, теперь этот код намертво вешает AVRStudio, а Протеус вылетает с ошибкой :))
гляньте что не так, ну и может у кого-то есть нормально оформленный работающий код приемника, посмотреть как оно должно быть

Код: Выделить всё

#ifndef RXB8
#define RXB8 1
#endif

#ifndef TXB8
#define TXB8 0
#endif

#ifndef UPE
#define UPE 2
#endif

#ifndef DOR
#define DOR 3
#endif

#ifndef FE
#define FE 4
#endif

#ifndef UDRE
#define UDRE 5
#endif

#ifndef RXC
#define RXC 7
#endif

#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<DOR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

// USART Receiver buffer
#define RX_BUFFER_SIZE 8
char rx_buffer[RX_BUFFER_SIZE];

#if RX_BUFFER_SIZE <= 256
unsigned char rx_wr_index,rx_rd_index,rx_counter;
#else
unsigned int rx_wr_index,rx_rd_index,rx_counter;
#endif

#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
char data;
while (rx_counter==0);
data=rx_buffer[rx_rd_index++];
#if RX_BUFFER_SIZE != 256
if (rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
#endif
#asm("cli")
--rx_counter;
#asm("sei")
return data;
}
#pragma used-
#endif

// This flag is set on USART Receiver buffer overflow
bit rx_buffer_overflow;

// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
   {
   rx_buffer[rx_wr_index++]=data;
   
   if (rx_wr_index == 19)     //----------------------- начало моей вставки
    {
        for (i=0; i<20; i++)
        { 
            lcd_gotoxy(i,3);
            lcd_putchar(rx_buffer[i]);
        }                             //------------------------- конец моей вставки
   
#if RX_BUFFER_SIZE == 256
   // special case for receiver buffer size=256
   if (++rx_counter == 0) rx_buffer_overflow=1;
#else
   if (rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
   if (++rx_counter == RX_BUFFER_SIZE)
      {
      rx_counter=0;
      rx_buffer_overflow=1;
      }
#endif
   }
}
}

как я понимаю в rx_buffer складываются принятые значения из UDR. я передаю 20 символов, соответственно на экран вывожу так же после приема 20 символов из этого массива rx_buffer. где ошибки?

upd. с протеусом разобрался, не отвечает prospice.dll. видимо приемник USART он не симулирует :(
Реклама
Аватара пользователя
pyzhman
Друг Кота
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск
Контактная информация:

Re: UART приемник

Сообщение pyzhman »

Код: Выделить всё

#define RX_BUFFER_SIZE 8
Docendo discimus
Реклама
Аватара пользователя
sphincs
Нашел транзистор. Понюхал.
Сообщения: 174
Зарегистрирован: Вт сен 11, 2012 09:13:52
Откуда: Брест, Беларусь
Контактная информация:

Re: UART приемник

Сообщение sphincs »

с AVRStudio тоже разобрался, зависало на инициализации дисплея: закомментил ее, а перекомпилить забыл. теперь пропускает.

правильно я сделал вывод на дисплей или нет?

UPD. вроде пошла симуляция, но пишет в логе (AVR USART) RX Frame Error. на дисплее тоже ничего. на 1 сеанс передачи данных 9 ошибок вылазит таких
Аватара пользователя
desertkun
Открыл глаза
Сообщения: 61
Зарегистрирован: Пн ноя 05, 2012 14:14:30

Re: UART приемник

Сообщение desertkun »

Насколько я понял, ты воткнул в прерывание ресивера код рендера дисплея. Нет, так делать нельзя, в прерываниях лучше стараться делать по-меньше телодвижений. Слушать данные и рисовать нужно в "основном потоке", используя исключительно getchar(). Например, так:

Код: Выделить всё

char data[20];
for (char i = 0; i < 20; i++)
{
    data[i] = getchar();
}
// тут колдуешь с полученными данными data
Реклама
Эиком - электронные компоненты и радиодетали
Ответить

Вернуться в «AVR»