close

ATmega 16 USART 可以使用 Asynchronous 與 Synchronous 兩種模式來進行控制,此範例將介紹 USART Synchronous Mode,範例使用兩顆 Atmega16 單晶片,一個擔任 Master另一個則是 Slave,來進行發送與接收的測試,範例中當按下按鈕後由 Master 發送字元 ‘0’ 與 ’1’ ,當 Slave 接收到 ‘0’ LED 則 ON,否則 LED即 OFF,因按下按鈕後,由於傳輸速度較快的原因,看不到 LED 閃爍,當放開按鈕後,最後會發送 ‘1’ 字元,則可將 LED OFF。

 

電路:

以下介紹 USART Synchronous Mode 下幾個重要的 Register

UBRR:

Baud Rate 的計算,將使用 Synchronous Master Mode 計算式進行計算  ((F_CPU)/(BAUD*2UL)-1),而 Synchronous Slave Mode 則不設定 UBRR,將由 Synchronous Master Mode XCK 接腳提供 Clock Singal,計算方法則可以參考( ATmega16 USART 控制(Asynchronous) )。

 

 

UCSRC:

如要使用 Synchronous Mode,需要將 UMSEL 設為 1。

 

XCK:

XCK 接腳設定,需要將 Master XCK 接腳設為 Output, Slave XCK 接腳設為 Input,設定方式如下:

Output:將PB0(XCK) 接腳DDRB Register  設為 1。 ( DDRB=0x1 )

Input:由於預設 DDRB 與 PORTB 設定皆為 0,PB0 為 Input ,無須再另外設定。

 

其餘 USART Register 設定,則請參考ATmega16 USART 控制(Asynchronous) 。

 

程式:

Master

#define F_CPU 16000000UL //外接振盪器頻率

#define BAUD 9600 //通訊鮑率                                  

#define BAUDRATE ((F_CPU)/(BAUD*2UL)-1)  

 

#include <avr/io.h>

#include <util/setbaud.h>

 

char getch();

void putch(char ch);

 

void uart_init(void) {

 

   UBRRH = BAUDRATE>>8;

   UBRRL = BAUDRATE;

 

  

   UCSRC = 1<<URSEL | 3<<UCSZ0 | 1<<UMSEL; /* 設定為 8-bit data */

   UCSRB = 1<<RXEN | 1<<TXEN;   /* Enable RX and TX */

DDRB = 1<<PB0;

}

 

void putch(char ch)

{

 

 while ( !( UCSRA & (1<<UDRE)) ); /* Wait for empty transmit buffer */

 UDR = ch;

 return 0;

}

 

char getch() {

   

while ( !(UCSRA & (1<<RXC)) );/* Wait for data to be received */

   return UDR;

}

 

int main(void)

{

 uart_init();

 PORTC=0x1;

 DDRB=0x1;

 

 while(1){

  if((PINC & 1)==0){

putch('0');

putch('1');

}

 }

 return 0;

}

 

Slave

#define F_CPU 16000000UL //外接振盪器頻率

#define BAUD 1200 //通訊鮑率                                  

#define BAUDRATE ((F_CPU)/(BAUD*2UL)-1)  

 

#include <avr/io.h>

#include <util/setbaud.h>

 

char getch();

void putch(char ch);

 

void uart_init(void) {

 

   UCSRC = 1<<URSEL | 3<<UCSZ0 | 1<<UMSEL; /* 設定為 8-bit data */

   UCSRB = 1<<RXEN | 1<<TXEN;   /* Enable RX and TX */

PORTB=1<<PB0;

}

 

void putch(char ch)

{

 

 while ( !( UCSRA & (1<<UDRE)) ); /* Wait for empty transmit buffer */

 UDR = ch;

 return 0;

}

 

char getch() {

   

while ( !(UCSRA & (1<<RXC)) );/* Wait for data to be received */

   return UDR;

}

 

int main(void)

{

 uart_init();

 char input;

 DDRA=0x01;

 

 while(1){

  if(input=='0')

PORTA=0 << PA0;

    else

PORTA=1 << PA0;

 

    input = getch();

 }

 return 0;

}

 

arrow
arrow
    全站熱搜

    iammic 發表在 痞客邦 留言(0) 人氣()