|
| |||||||
|
Опубликовано 2010-05-07 11:30:31 автором Ruslan Передача даних через UART в AVR. Урок AVR 9Для зв'язку мікроконтролера зі своїм старшим братом - ПК - можна використовувати інтерфейси передачі даних , але так як я навчальний курс з AVR намагаюся побудувати на мікроконтролері mega8 , то краще за все для зв'язку з ПК використовувати інтерфейс USART . Ні, можна, звичайно , заюзать і USB , але USART в mega8 реалізований апаратно , а це означає , що нам не доведеться вручну реалізовувати логіку передачі даних , ми просто запишемо дані в регістр , а самим процесом відправки вже буде рулити МК апаратно . Протокол UART ( Universal asynchronous receiver / transmitter ) є одним з найпоширеніших протоколів передачі даних між пристроями. У Atmega8 один USART , виведений він на ніжки PD0 - Rx , receiver (приймач ) і PD1 - Tx , transmitter ( передавач ) .
Давайте спробуємо передати дані з пк . Коли з пк приходитиме 1 , то світлодіод світитиметься , коли 0 , то гаснути . Схема виглядає наступним чином:
У CodeVision AVR створюємо новий проект , частоту мк встановлюємо на 8 мегагерц , далі переходимо у вкладку USART , там включаємо приймач і передавач
# include <mega8.h>
void main ( void )
{
char date = 0 ;
PORTC = 0x00;
DDRC = 0x01;
// USART initialization
// Communication Parameters : 8 Data , 1 Stop , No Parity
// USART Receiver : On
// USART Transmitter : On
// USART Mode : Asynchronous
// USART Baud Rate : 9600
UCSRA = 0x00;
UCSRB = 0x18 ;
UCSRC = 0x86 ;
UBRRH = 0x00;
UBRRL = 0x33 ;
while ( 1 )
{
date = UDR ;
if ( date == '1 ' ) PORTC.0 = 1 ;
if ( date == '0 ') PORTC.0 = 0 ;
} ;
}
У AVR є регістр UDR . Насправді , це два різних регістра , які мають одну адресу . Коли записуємо дані , то вони потрапляють в регістр передавача , а коли читаємо - беруться з регістра приймача. Для відправки ми просто записуємо дані в цей регістр і вони полетять до приймача , а якщо нам щось прийшло - зчитуємо їх з регістра . Стежити за UART вручну не потрібно , все обслуговування можна повісити на переривання. Коли до нас приходять дані , генерується переривання по завершенню прийому , а коли дані відправляться - викликається переривання по спустошенню Компілюємо програму , закидаємо в мк в Протеус . Для відсилання даних з терміналу потрібно поставити галочку біля : Робота на перериванняЯк ви помітили , наша програма нескінченно очікує приходу байта. Так робити недоцільно , тому що головний цикл завантажений прийомом і передачею даних через uart і більше нічого робити не може. Звичайно , можна не зациклюватися , а наприклад періодично раз в 10 мілісекунд перевіряти , чи не прийшли нам дані , в решту часу робити щось своє . Але тоді , якщо передача йде на великій швидкості , можна припустити байти . Найкраще цю малину замутити на переривання : прийшли дані - викликався обробник переривання і все. Для цього в CodeWizard AVR у вкладці USART потрібно поставити галочку біля Rx Interraptгенер код , і отримуємо
# include <mega8.h>
# 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
// 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 == RX_BUFFER_SIZE ) rx_wr_index = 0 ;
if ( + + rx_counter == RX_BUFFER_SIZE )
{
rx_counter = 0 ;
rx_buffer_overflow = 1 ;
} ;
} ;
if ( data == '1 ' ) PORTC.0 = 1 ;
if ( data == '0 ') PORTC.0 = 0 ;
}
# include <stdio.h>
void main ( void )
{
// Port C initialization
PORTC = 0x00;
DDRC = 0x01;
// USART initialization
// Communication Parameters : 8 Data , 1 Stop , No Parity
// USART Receiver : On
// USART Transmitter : Off
// USART Mode : Asynchronous
// USART Baud Rate : 9600
UCSRA = 0x00;
UCSRB = 0x90 ;
UCSRC = 0x86 ;
UBRRH = 0x00;
UBRRL = 0x33 ;
/ / Global enable interrupts
# asm ( " sei " )
while ( 1 )
{
} ;
}
Тут codewizard згенерував різні перевірки парності і буфер для запису даних , які прийшли. Нам для того , щоб засвітити світло діод, все це не потрібно , тому видаляємо зайве, і отримуємо
# include <mega8.h>
# include <stdio.h>
// USART Receiver interrupt service routine interrupt [ USART_RXC ] void usart_rx_isr ( void )
{
char data ;
data = UDR ;
if ( data == '1 ' ) PORTC.0 = 1 ;
if ( data == '0 ') PORTC.0 = 0 ;
}
void main ( void )
{
// Port C initialization
PORTC = 0x00;
DDRC = 0x01;
// USART initialization
// Communication Parameters : 8 Data , 1 Stop , No Parity
// USART Receiver : On
// USART Transmitter : Off
// USART Mode : Asynchronous
// USART Baud Rate : 9600
UCSRA = 0x00;
UCSRB = 0x90 ;
UCSRC = 0x86 ;
UBRRH = 0x00;
UBRRL = 0x33 ;
// Global enable interrupts
# asm ( " sei " )
while ( 1 )
{
} ;
}
Як бачите , головний цикл вільний . Тепер нам не потрібно регулярно перевіряти , а чи не прийшли дані по uart . Коли прийде байт по uart , то викличеться обробник переривання , і ми вже в ньому зробимо необхідні нам дії . Переходимо до заліза Якщо у вашого пк є COM порт , то вам для сполучення з мікроконтролером знадобиться перетворювач рівнів ТТЛ - RS232. Його легко зібрати на мікросхемі MAX232 . Він потрібен , тому що напруга на виході даних з COM- порту ПК:
Якщо у вашого ПК немає СОМ - портів , то потрібно юзати адаптер на мікросхемі FT232 - він підключається до USB вашого ПК і в системі з'являється віртуальний СОМ порт , а на виводах FT232 відповідні сигнали UART .
Комментарии - (2)
Добавить комментарийДля отправки комментария вы должны авторизоваться. |
|||||||