Pengetahuan Dasar Pemrograman USART (serial komunikasi) AVR Microcontroller
1.Register
2. Inisialisasi
3. Menerima Data
4. Mengirim Data
5. Contoh Program
6. Dual USART (atmega 162, atmega 128 dll)
1. Register
AVR USART (Universal Synchronous Asynchronous Receiver Transmitter) adalah komunikasi serial dua arah yang terdapat di AVR yang melibatkan register register sbb:
1. Register Data (UDR), menyimpan data yg dikirim dan diterima.
2. Register Control (UCSRA bit 0~ bit1, UCSRB dan UCSRC)
2. Register Status (UCSRA bit 2~bit 7)
• Bit 7 – RXC: USART Receive Complete
RXC otomatis akan bernilai 1, jika ada data baru di bufer penerima. RXC otomatis akan bernilai 0, jika data sudah dibaca atau bufer penerima kosong.
• Bit 6 – TXC: USART Transmit Complete
TXC otomatis akan bernilai 1, jika data di buffer selesai dikirim.
• Bit 5 – UDRE: USART Data Register Empty
UDRE otomatis akan bernilai 1 , jika register UDR kosong transmiter siap mengirim data. UDRE=0, UDR berisi data yg belum selesai dikirim .
• Bit 4 – FE: Frame Error
FE otomatis akan bernilai 1, jika ada frame eror.
• Bit 3 – DOR: Data OverRun
DOR otomatis akan bernilai 1, jika data datang ketika bufer penuh(terjadi antrian).
• Bit 2 – PE: Parity Error
PE otomatis akan bernilai 1, jika terjadi parity eror.
• Bit 1 – U2X: Double the USART Transmission Speed
kita set U2X=0, kecepatan normal. U2X=1 kecepatan 2xbaudrate.
• Bit 0 – MPCM: Multi-processor Communication Mode
kita set MCM=1 byte pertama yg diterima harus 9 bit , jika tdk data byte akan diabaikan.bit ini terjadi hanya untuk penerimaan saja pd komunikasi banyak microcontroller.
• Bit 7 – RXCIE: RX Complete Interrupt Enable
kita set RXCIE=1 , interupsi receive complete aktif.
• Bit 6 – TXCIE: TX Complete Interrupt Enable
kita set TXCIE=1, interupsi transmit complete aktif.
• Bit 5 – UDRIE: USART Data Register Empty Interrupt Enable
kita set UDRIE=1, interupsi UDRE aktip.
• Bit 4 – RXEN: Receiver Enable
kita set RXEN=1, USART receiver aktif. micon bisa mnerima data.
• Bit 3 – TXEN: Transmitter Enable
kita set TXEN=1, Usart Transmiter aktif. micon bisa mengirim data.
• Bit 2 – UCSZ2: Character Size
kita set UCSZ2:UCSZ1:UCSZ0 = 011 , panjang data 8 BIT. (bit UCSZ1 dan UCSZ0 ada di register UCSRC)
• Bit 1 – RXB8: Receive Data Bit 8
RXB8 menjadi bit ke-9 jika panjang data yg diterima 9 bit .
• Bit 0 – TXB8: Transmit Data Bit 8
TXB8 menjadi bit ke-9 jika panjang data yg dikirim 9 bit.
• Bit 7 – URSEL: Register Select . memilih UCSRC atau UBRRH
kita set URSEL=1 , UCSRC aktif ,UBRRH tdk aktif,
kita set URSEL=0 , UBRRH aktif , UCRSC tdk aktif.
• Bit 6 – UMSEL: USART Mode Select
kita set UMSEL=1 , mode synceonous. UMSEL=0 mode asyncronous
• Bit 5:4 – UPM1:UMP0: Parity Mode
kita set :
• Bit 3 – USBS: Stop Bit Select
kita set USBS=0, stop bit =1 bit , USBS=1 panjang stop bit = 2 bit.
• Bit 2:1 – UCSZ1:0: Character Size
kita set UCSZ2:UCSZ1:UCSZ0 = 011 , panjang data 8 BIT. (bit UCSZ2 ada di register UCSRB)
• Bit 0 – UCPOL: Clock Polarity bit ini digunakan untuk mode syncoronous saja.
kita set UCPOL=0 trnasmisi clock naik, UCPOL=1 transmisi clock turun. (khusus yg ini don’t care krn kita menggunakan mode asyncronous)
Detail penjelasan tiap bit pd register register di atas ada disini
3. Register 8 bit UBRRH dan 8 bit UBRRL , menyimpan parameter baudrate 16 bit UBRR register. Rumus untuk menghitung nilai UBRR adalah sbb:
Contoh menghitung nilai UBRR : diketahui baudrate = 9600 dan frekwensi cristal yg digunakan 11.059.200 hz , berapa nilai UBBRH dan UBRL nya?
UBRR = ( (11.59200)/(16*9600) ) – 1 = 71.
maka nilai UBRR adalah 71 atau 0047H. (dlm bentuk 16 bit hexa). penulisan nilai UBRR di program (ke dlm register UBRRH dan UBRRL) menjadi:
UBRRH=0x00;
UBRRL=0x47;
Tips Pemilihan nilai frekwensi Xtal
nilai UBRR adalah integer , maka pilih lah nilai frekwensi xtal yg menghasilkan perhitungan integer . misal contoh diatas saya ganti nilai Xtalnya jadi 8 Mhz ,baudrate 9600. maka nilai UBRR nya jadi 51,0833 yg dimasukan ke UBRR adalah 51. nilai ini akan menghasilkan kemungkinan komunikasi eror sebesar0,2%. sedangkan jika menggunakan Xtal 11.059200 erornya 0%.
Cara lain untuk meseting nilai UBRR adalah dgn menuliskan rumus perhitungan UBRR ke code program biarkan compiler yg menghitung nilai UBRR,, seperti contoh berikut ini:
#define Frekwensi_Xtal 11059200// Clock Speed #define BAUDRATE 9600 #define MYUBRR (Frekwensi_Xtal/(16*BAUDRATE))-1 void main( void ) { ... USART_Init ( MYUBRR ); ... } void USART_Init( unsigned int ubrr) { /* Set baud rate ubrr= 0047 */ UBRRH = (unsigned char)(ubrr>>8); //UBRH=00 UBRRL = (unsigned char)ubrr; //UBRRL=47 }
2. Inisialisasi
USART harus diinisialisasi sebelum komunikasi dilakukan. Proses inisialisasi
biasanya terdiri dari pengaturan baud rate, pengaturan format frame dan mengaktifkan(enable) Transmitter atau Receiver/Penerima tergantung pada penggunaan. Untuk operasi USART dgn interupsi, Global Interrupt Flag harus diclearkan (dan interupsi dinonaktifkan secara global) ketika melakukan inisialisasi.
Bit Flag TXC dapat digunakan untuk memeriksa bahwa Transmitter telah menyelesaikan semua transfer, dan bit flag RXC dapat digunakan untuk memeriksa bahwa tidak ada data yang belum dibaca dalam buffer penerima. Perhatikan bahwa Flag TXC harus diclearkan sebelum pengiriman (sebelum UDR ditulis) jika digunakan untuk pengiriman.
Berikut ini contoh inisialisasi dan program penerimaan dan pengiriman dgn AVR USART.
Pemrograman AVR USART dgn AVR Studio
Pemrograman USART dgn codevision
Pada pemrograman dgn codevision anda tdk perlu pusing menghitung nilai register control UCSR dan register UBRR , cukup gunakan tool codewizard.
klik Tools ->Codewizard , pilih tab USART sbb:
Setelah USART anda setting sesuai kebutuhan pd tab USART , code template dan nilai seting register register USART otomatis akan dibuatkan oleh codevision setelah anda mengklik menu generate,save and exit , hasilnya seperti dibawah ini :
#include <mega32.h>
#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7
#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#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; };
//Ketik data anda disini
};
}
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On (RXEN=1)
// USART Transmitter: On (TXEN =1)
// Receive interupt aktif (RXCIE=1)
// USART Mode: Asynchronous (UMSEL=O)
// USART Baud rate: 9600
UCSRA=0x00;
UCSRB=0x98; //10011000
UCSRC=0x86; //10000110
UBRRH=0x00;
UBRRL=0x47;
// Global enable interrupts “sei” , sebaliknya “cli” clear interupt.
#asm(“sei”)
while (1)
{
// Place your code here
};
}
3. Menerima Data
Fungsi Penerima pd USART diaktifkan dengan menset 1 bit RXEN di register UCSRB . Ketika penerima diaktifkan, operasi normal pin i/o dirubah mejadi pin receive serial(Rx) USART . Baud rate, mode operasi dan format frame harus diatur sebelum ada penerimaan serial.
Data yang diterima serial ditampung di bufer penerima dan kita bisa mendapatkan data tsb dgn cara membaca register UDR. Berikut ini contoh pembacaan data serial USART dengan polling bit RXC . bit RxC otomatis akan bernilai 1 jika ada data di buffer penerima dan bernilai 0 jika tdk ada data di buffer penerima. bit RXC ada bit ke7 di register UCSRA.
unsigned char USART_Receive( void )
{
/* Wait for data to be received */
while ( !(UCSRA & (1<<7)) )
;
/* Get and return received data from buffer */
return UDR;
}
atau
#define RXC 7
unsigned char USART_Receive( void )
{
/* Wait for data to be received(RXC=1) */
while ( !(UCSRA & (1<<RXC)) )
;
/* Get and return received data from buffer */
return UDR;
}
Menerima data dengan interupsi
Untuk mengaktifkan interupsi penerima dengan cara menset bit RXCIE dan RXC (dengan cara mengaktifkan interupsi global).Ketika ada data diterima rutin interupsi harus membaca data UDR krn hal ini akan mereset bit RXC. jika tidk sebuah interupsi baru akan terjadi lagi.
// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
}
// USART initialization
//clock xtal = 11.059200mhz
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud rate: 9600
UCSRA=0x00;
UCSRB=0x98; // 10011000 RXCIE=1 , TXEN=1, RXEN=1.
UCSRC=0x86; //10000110
UBRRH=0x00;
UBRRL=0x47; // set baudrate 9600
4. Pengiriman Data Serial
Fungsi Pengiriman pd USART diaktifkan dengan menset 1 bit TXEN di register UCSRB . Ketika fungsi pengiriman pd USRAT diaktifkan, operasi normal pin i/o dirubah mejadi pin transmit serial(Tx) USART . Baud rate, mode operasi dan format frame harus diatur sebelum ada pengirimn serial.
Data yang akan dikirim di simpan ke bufer pengiriman dengan cara menyimpan data ke register . bit UDRE otomatis akan bernilai 1 jika buffer siap mengirim data(buffer kosong) dan bernilai satu jika bufer berisi data/sedang ada proses pengiriman. bit UDRE ada di bit ke 5 pada register UCSRA. Keadaan pengiriman selain diketahui dari bit UDRE juga dari ke adaan bit TXC.
Berikut ini contoh code pengiriman data dgn cara pooling/memeriksa bit UDRE .
void USART_kirimChar( unsigned char data )
{
/* Wait for empty transmit buffer (UDRE=1) */
while ( !( UCSRA & (1<<UDRE)) )
;
/* Put data into buffer, sends the data */
UDR = data;
}
Mengirim data string
Data string merupakan sebuah array bertype char yg diakhiri dengan karakter NULL ” .
void sendString(char *s)
{
while (*s) {
USART_kirimChar(*s);
s++;
}
}
Contoh sederhana mengirim bilangan /angka
Tiap digit angka dikirim satu persatu. sebelum dikirim angka dirubah ke ASCII dengan menambah 48.
karna kode ASCII dari 0 adalah 0+48= 48
kode ASCII dari 1 adalah 1+48 = 49 dst..
void kirim_angka (unsigned int angka)
{
unsigned int digit;
digit=angka/1000;
USART_kirimChar(48+digit);
angka%=1000;
digit=angka/100;
USART_kirimChar(48+digit);
angka%=100;
digit=angka/10;
USART_kirimChar(48+digit);
angka%=10;
USART_kirimChar(48+angka);
}
Pengiriman dengan Interupsi
Untuk interupsi pengiriman bisa diaktifkan dengan 2 pilihan yaitu bit TXCIE dan UDRIE.
bila yg diaktfikan bit TXCIE=1 maka interupsi akan di triger oleh bit TXC
bila yg diaktifkan bit UDRIE=1 maka interupsi akan di triger oleh bit UDRE
Contoh dibawah ini inisialisasi interupsi pengiriman dgn triger TXC
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On , Interupsi Receiver On
// USART Transmitter: On , interupsi Transmiter On
// USART Mode: Asynchronous
// USART Baud rate: 9600
UCSRA=0x00;
UCSRB=0xD8; //11011000 , RXCIE=1, TXCIE=1 , TXEN=1, RXEN=1
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x47;
// USART Transmitter buffer
#define TX_BUFFER_SIZE 16
char tx_buffer[TX_BUFFER_SIZE];
unsigned char tx_rd_index,;
// USART Transmitter interrupt service routine
interrupt [USART_TXC] void usart_tx_isr(void)
{
if (++tx_rd_index == TX_BUFFER_SIZE) return;
UDR=tx_buffer[tx_rd_index];
}
untuk menaktifkan interupsi pengiriman kita buat TXC= 0 dengan cara mengirim data ke buffer pengirim UDR
USART_Transmit(tx_buffer[0]); // data pertama (tx_rd_index=0) dikirm tanpa interupsi
maka bufer pengirim akan ada isinya dan selanjutnya interupsi dijalankan. rutin interupsi akan mengirm semua data di tx_buffer
fungsi USART_Transmit() adalah sbb sebagaimana yg sudah di bahas pada bagian diatas sebelumnya
void USART_Transmit( unsigned char data )
{
/* Wait for empty transmit buffer (UDRE=1) */
while ( !( UCSRA & (1<<UDRE)) )
UDR = data;
}
Dual USART
Beberapa type AVR mempunyai 2 buah jalur komunikasi serial (dual USART) contoh atmega 161, atmega 162 dan atmega 128. Penggunaan kedua jalur komunikasi tsb pada prinsipnya sama hanya berbeda register yg digunakan. Register yang digunakan kedua jalur komunikasi tsb spt pada gambar dibawah ini:
Register yg digunakan USART pertama : UCSR0A, UCSR0B, UCSR0C UDR0, UBRR0L, dan UBRR0H
Register yg digunakan USART kedua : UCSR1A, UCSR1B, UCSR1C UDR1, UBRR1L, dan UBRR1H
berikut contoh inisialisasi kedua register pada atmega128
// USART0 initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART0 Receiver: On
// USART0 Transmitter: On
// USART0 Mode: Asynchronous
// USART0 Baud rate: 9600
UCSR0A=0x00;
UCSR0B=0x98;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x47;
// USART1 initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART1 Receiver: On
// USART1 Transmitter: On
// USART1 Mode: Asynchronous
// USART1 Baud rate: 9600
UCSR1A=0x00;
UCSR1B=0x98;
UCSR1C=0x06;
UBRR1H=0x00;
UBRR1L=0x47;
Posted on 04/07/2013, in AVR, Pemrograman C untuk AVR dgn CodeVision. Bookmark the permalink. 6 Comments.
gpp
blognya sangat bermanfaat, semoga berkembang terus.
maaf saya mau tanya. kalau error 0.2% itu bisa bikin komunikasi kemungkinan gagal gak? terima kasih
terima kasih sarannya gan.
ulasan ini telah membantu tugas saya. saran: lebih baik tambahkan referensi sumbernya. terimakasih, semoga makin berkembang blognya.
Bagus blognya, saya jadi benar2 tahu dasar2 register buat komunikasi serial, mantap dan perbanyak postingan bermanfaatnya ya…
Mas bisa bantu ga ?
saya ad project membaca sht11 dengan at8535 hasil pembacaan di tampilkan ke LCD 2×16 dan dikirim ke PC melalui jaringan LAN dengan modul DT-IO TCP IP to UART…..
saya kbingungan bikin codingnya serta cara menerima data di PC…terima kasih
salam kenal…