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

 
 
> Какова "реальная" скорость UART?
altlogic
сообщение Jun 2 2008, 23:15
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 222
Регистрация: 2-12-06
Из: г. Хабаровск
Пользователь №: 23 035



Здравствуйте!

Стояла задача добиться максимальной скорости обмена по UART в Atmega128. Со стороны мк была написана небольшая програмка для измерения скорости обмена. Передача осуществляется в режиме прерывания.
Код
#define TX_BUFFER_SIZE 128
char tx_buffer[TX_BUFFER_SIZE];

#if TX_BUFFER_SIZE<256
unsigned char tx_wr_index,tx_rd_index,tx_counter;
#else
unsigned int tx_wr_index,tx_rd_index,tx_counter;
#endif

// USART0 Transmitter interrupt service routine
interrupt [USART0_TXC] void usart0_tx_isr(void)
{
if (tx_counter)
   {
   --tx_counter;
   UDR0 = tx_buffer[tx_rd_index];
   if (++tx_rd_index == TX_BUFFER_SIZE)
      tx_rd_index=0;
   };
}

// Write a character to the USART0 Transmitter buffer
#pragma used+
int COM_putchar(unsigned char c)
{
while (tx_counter == TX_BUFFER_SIZE);
#asm("cli")
if (tx_counter || ((UCSR0A & DATA_REGISTER_EMPTY)==0))
   {
   tx_buffer[tx_wr_index]=c;
   if (++tx_wr_index == TX_BUFFER_SIZE)
   {        
      tx_wr_index=0;
   }
   ++tx_counter;
   }
else
   UDR0=c;
#asm("sei")
return 1;//<!
}

в main:

unsigned long int tx_cnt; // счётчик переданных байт
_включили_таймер
   if( ++tx_cnt < 65535 )
   {      
      COM_putchar(0x55);    
   }
_остановили_таймер

В теории скорость передачи BAUD = 115200 бит/с. Передаём один старт-бит, 8 бит данных, один стоп-бит, итого 10 бит на передачу одного байта данных.
На деле получаю:
передано 65535 байт;
время: 6,2с.
Считаем BAUD: 65535*10/6,2 = 105702 бит/с.

Не дотягивает передатчик до любой из стандартных скоростей, которую я выбирал. Может так и должно быть? Или стоит искать ошибки программы?

Сообщение отредактировал altlogic - Jun 2 2008, 23:17


--------------------
С уважением, Вячеслав
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
altlogic
сообщение Jun 3 2008, 07:15
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 222
Регистрация: 2-12-06
Из: г. Хабаровск
Пользователь №: 23 035



Цитата(aaarrr @ Jun 3 2008, 15:54) *
Код инициализации мы не видели.

Код
//#define _USART0_TXC_INTERRUPT_
void COM_init( unsigned int ubrr )
{
    UBRR0H = (unsigned char) (ubrr>>8);                       //Setting baudrate
    UBRR0L = (unsigned char) ubrr;                            //Setting baudrate
    #ifdef _USART0_TXC_INTERRUPT_
      UCSR0B = ( 1 << RXEN0 ) | ( 1 << TXEN0 );                     //Enable receiver and transmitter
    #else
      UCSR0B = ( 1 << RXEN0 )  ( 1 << TXEN0 ) | (1 << UDRIE0) |;                     //Enable receiver
    #endif
    UCSR0C = ( 1 << UCSZ01 ) | ( 1 << UCSZ00 );  //8N1...see Datasheet for more information
    UCSR0A=0x00;
    COM_rx_reset();
    COM_tx_reset();                                               //Reset buffers etc.        
}
void COM_rx_reset( void )
{
    COM_rx_off();       // Disable RX interrupt
    rx_i = rx_wr_i = 0;           //Init variables
    rx_overflow = rx_ack = 0;     //Zero overflow flag
    rx_buffer[ rx_wr_i ] = '\0';  //Buffer init.
}  

void COM_tx_reset( void )
{
    COM_tx_off();       // Disable RX interrupt
    tx_wr_index = 0;
    tx_rd_index = 0;
    tx_counter = 0;    
}

void COM_rx_on( void )
{
    UCSR0B |= ( 1 << RXCIE0 );  // Enable RX interrupt
}


void COM_rx_off( void )
{
    UCSR0B &= ~( 1 << RXCIE0 ); // Disable RX interrupt
}

void COM_tx_on( void )
{    
    UCSR0B |= ( 1 << TXCIE0 );  // Enable TX interrupt
}

void COM_tx_off( void )
{
    UCSR0B &= ~( 1 << TXCIE0 ); // Disable TX interrupt
}

#ifdef _USART0_TXC_INTERRUPT_

//<! USART0_TXC - tx complete

interrupt [ USART0_TXC ] void usart0_TXC_isr(void)
{
if ( tx_counter )
   {
   --tx_counter;
   UDR0 = tx_buffer[tx_rd_index];
   if (++tx_rd_index == TX_BUFFER_SIZE)
      tx_rd_index=0;
   };
}

#else

//<! USART0_DRE - usart data register emptry

interrupt [ USART0_DRE ] void usart0_UDRE_isr(void)
{
if ( tx_counter )
   {
   --tx_counter;
   UDR0 = tx_buffer[tx_rd_index];
   if (++tx_rd_index == TX_BUFFER_SIZE)
      tx_rd_index=0;
   };
}

#endif

...
void main(void)
{
...
//<! USART0 initialization (UBRR = 0x01 = 115200 @ 3.6864MHz)
COM_init(0x01);  
...
}

С объявленным _USART0_TXC_INTERRUPT_ передатчик работает в четыре раза быстрее.

Цитата(Палыч @ Jun 3 2008, 17:00) *
C буфером передачи Вы, ИМХО, намудрили... По всей вероятности переменная tx_counter инициируется нулём, поэтому выражение в операторе if будет ложным всегда. (P.S. Тут я немного соврал, но правильность условия в первом if - очень сомнительна!) Использовать желательно прерывание UDE для добавления аппаратной буферизации.
Вероятно, добавили UDE, исправили прерывание, но не убрали разрешение прерывания по TXC, а обработчика прерывания уже - нет! Если разрешено какое-либо прерывание, а соответствующего обработчика нет, микроконтроллер попадает на адрес 0, и всё - заново.

Про прерывания по TXC вы правильно заметили


--------------------
С уважением, Вячеслав
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- altlogic   Какова "реальная" скорость UART?   Jun 2 2008, 23:15
- - repairDV   Цитата(altlogic @ Jun 3 2008, 10:15) Не ...   Jun 3 2008, 00:50
|- - altlogic   Цитата(repairDV @ Jun 3 2008, 11:50) Да, ...   Jun 3 2008, 01:12
|- - repairDV   Цитата(altlogic @ Jun 3 2008, 12:12) бит ...   Jun 3 2008, 02:58
- - aaarrr   Цитата(altlogic @ Jun 3 2008, 03:15) Не ...   Jun 3 2008, 03:03
- - altlogic   Цитата(repairDV @ Jun 3 2008, 13:58) Тут,...   Jun 3 2008, 03:14
- - MrYuran   Цитата(altlogic @ Jun 3 2008, 03:15) В те...   Jun 3 2008, 04:04
|- - altlogic   Цитата(MrYuran @ Jun 3 2008, 15:04) на са...   Jun 3 2008, 04:45
|- - LeonY   Цитата(MrYuran @ Jun 3 2008, 06:04) на са...   Jun 3 2008, 22:37
- - aaarrr   Цитата(MrYuran @ Jun 3 2008, 08:04) на са...   Jun 3 2008, 04:54
- - Палыч   Цитата(altlogic @ Jun 3 2008, 02:15) Стоя...   Jun 3 2008, 06:00
|- - Палыч   По-моему, Вам уже всё обьяснили... Или остались во...   Jun 3 2008, 07:56
- - lolful   Я наверно скажу глупость, но мне всегда казалось, ...   Jun 3 2008, 17:49
- - aaarrr   Ересь Стартовый бит всегда один, количество стопо...   Jun 3 2008, 17:59
- - altlogic   Всем участникам спасибо! Сегодня утром на свеж...   Jun 3 2008, 21:53
|- - aaarrr   Цитата(altlogic @ Jun 4 2008, 01:53) Вот ...   Jun 4 2008, 09:45
|- - Dog Pawlowa   Цитата(aaarrr @ Jun 4 2008, 12:45) Провер...   Jun 4 2008, 10:38
||- - aaarrr   Цитата(Dog Pawlowa @ Jun 4 2008, 14:38) Т...   Jun 4 2008, 10:48
||- - Dog Pawlowa   Цитата(aaarrr @ Jun 4 2008, 13:48) Ага, с...   Jun 4 2008, 11:20
|- - altlogic   Цитата(aaarrr @ Jun 4 2008, 20:45) Провер...   Jun 4 2008, 12:14
- - DpInRock   Бит четности не передается, если четность не включ...   Jun 4 2008, 03:48
- - WHALE   а зачем 2 индекса-rx_wr_index1 и rx_counter1?   Jun 4 2008, 05:54
- - altlogic   Там вообще три переменных под индексы: rx_wr_index...   Jun 4 2008, 07:02
- - aaarrr   Ну, если специально придумать плохой протокол и до...   Jun 4 2008, 11:51
- - DpInRock   Протокол верхнего уровня, это когда вы принятую ст...   Jun 5 2008, 10:37
- - altlogic   Что-то просел я с реализацией RTS/CTS протокола. Н...   Jun 5 2008, 11:35
|- - aaarrr   Цитата(altlogic @ Jun 5 2008, 15:35) Ко...   Jun 5 2008, 13:02
|- - altlogic   Спасибо, теперь вроде ничего не теряю Только я не ...   Jun 5 2008, 13:40
- - aaarrr   Да, при входе в прерывание прерывания запрещаются ...   Jun 5 2008, 13:54


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

 


RSS Текстовая версия Сейчас: 29th July 2025 - 12:16
Рейтинг@Mail.ru


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