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; } |
留言列表