Program serial receiver polling dengan display LCD.
Tanpa interrupt apalagi scheduler, polos-los. Data text akan ditampilkan secara
berjalan (left marquee). Program ini memanfaatkan loop aja silahkan dipelajari,
dimodif, diutak atik sesuai kebutuhan.

Program ini default menggunakan baudrate 19200bps dan bisa menerima paket data
(printable chars) maksimum 500 karakter dalam satu paket :D
mudah sekali untuk modif dan merubah parameter dari program ini. Yang perlu
diingat bila jumlah array pada variable ___buffer_ nilai maksimum sesuaikan
dengan kapasitas SRAM mikrokontroler yang digunakan. Sebagai contoh program
ini menggunakan AVR seri ATmega16..

Simulasi proteus untuk serial comm receiver (UART)

Berikut adalah listing programnya:

/*__ ___        __  __ ___  ___ ___  ___ _  _
|_ _|   \  ___ |  \/  |_ _|/ __| _ \/ _ \ \| | - eMBEDDED Design &
 | || |) ||___|| |\/| || |  (__|   / (_)| .` | - System Development
|___|___/      |_|  |_|___|\___|_|_\\___/_|\_|______________________+
 
;Homepage   : http://www.nubielab.com
;Email      : herlambang@nubielab.com
;Programmer : Herlambang Aribowo.
------------
Compiler: CodeVisionAVR V2.03.9
Chip    : ATmega16 X-tall 4Mhz
FUSE: H:C9    L:2F    Brownout@4.5V,WDT ON,BOD ON,SPI EN,X-tall High Freq.
FUSE: H:C9    L:AF    Brownout@2.7V,WDT ON,BOD ON,SPI EN,X-tall High Freq.
############################################################################
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
 
Copyright 2009, 2010 Herlambang Aribowo
############################################################################
Ing ngarso sung tulodo; Ing madyo mangun karso; Tut wuri handayani.
________________________________"ODJO DUMEH"________________________________
*/
#include <mega16.h>
 
// Alphanumeric LCD Module functions
#asm
   //.equ __lcd_port=0x1B ;PORTA   //yang dipakai tanpa slash
   //.equ __lcd_port=0x18 ;PORTB
   .equ __lcd_port=0x15 ;PORTC
   //.equ __lcd_port=0x12 ;PORTD
#endasm
 
// Standard Input/Output functions
#include <string.h>    //library string function sprti strlen()
#include <delay.h>     //library fungsi delay
#include <lcd.h>       //library LCD standar CodeVisionAVR
 
#define RXC UCSRA.7    //RX flag, new data is coming
#define arr_len 517    //maksimal arr_len-17 = 500chars (silahkan diubah2)
                       //nilai maksimal sesuaikan dengan kapasitas SRAM mikro yang
                       //digunakan.. :D
#define __MAXchars (arr_len-17) //untuk perbandingan data maksimal
#define lcd_number 16  //bila menggunakan LCD ..x16, kalo beda silahkan diubah
#define led_data PORTD.4 //led kedap - kedip :D
#define ADDSPACE 0x01  // tambah spasi pada 16 komponen array terakhir ___buffer_
#define CLRBUF__ 0x02  // clear ___buffer_
#define LOADMESS 0x03  // clear ___buffer_ and load welcome mesage
#define line0    0x00  // untuk pilihan line display moving message
#define line1    0x01  // --------------------||-------------------
 
// Global variables
char ___buffer_[arr_len]="";
__flash char pesan_pembuka[]={"NO DATA RECEIVED ~ SEND YOUR TEXT "
"TROUGH UART (19200BPS). MAX DATA/PACKETS 500 CHARS!"}; //max ikut arr_len - 17
unsigned int count = 0;
char cnt_led=0,cnt_disprcv=0;
bit flag_rcv=0,flag=0;
 
//function prototype
void sett_regs(void);
void terima(void);
void tampilan(unsigned char line);
void olahdata(unsigned char mode);
 
//Main routine buat super loop
void main(void){
sett_regs();
lcd_init(16);
_lcd_ready();
lcd_clear();
olahdata(LOADMESS);
for(;;){
    #asm("nop")
    tampilan(1);
    if (flag_rcv)cnt_disprcv++;
    if (cnt_disprcv >= 5){              //4X displayed text
        cnt_disprcv = 0;
        flag_rcv = 0;
        lcd_gotoxy(0,0);
        lcd_putsf("ANE HAPUS YA..  ");  //Biar belajarnya enak :D
        lcd_gotoxy(0,1);                //Programming is FUN
        lcd_putsf("DICOBA LAGI..^^'");  //yg penting enjoy :)
        delay_ms(2000);
        olahdata(LOADMESS);
        }
    #asm("wdr")
    }
}
 
// Setting register
void sett_regs(void){
//Define I/O
DDRA  = 0x00;PORTA = 0x00;
DDRB  = 0x00;PORTB = 0x00;
DDRC  = 0x00;PORTC = 0x00;
DDRD  = 0xF0;PORTD = 0xF0;
 
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: Off
// USART Mode: Asynchronous
// USART Baud Rate: 19200
UCSRA=0x00;
UCSRB=0x10;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x0C;
 
// Watchdog Timer initialization
// Watchdog Timer Prescaler: OSC/2048k
#pragma optsize-
WDTCR=0x1F;
WDTCR=0x0F;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
}
 
// Serial getchar function, tdk menggunakan library stdio.h
unsigned char ambilRX(void){
unsigned int i = 625;//nilai bwt loop timeout data
while (--i){//nilai loop dikecilin kalo baudrate lebih besar, dan sebaliknya
            //dibagi nilai rasionya aja, misal 19200 = 625 kalo 1200 = 625*16 = 10000
    if (!(UCSRA & (1<<rxc)))return UDR;
    }
}
 
void terima(void){
unsigned int j=40000;                  //ubah nilai ini untuk kecepatan running text
volatile char i=0,temp=0;
while (--j){
    #asm("wdr")
    if (RXC == 1){                     //ada data baru masuk gak??
        led_data = ~led_data;
        j=35000;                       //bila ada data masuk reload counter
        ___buffer_[count] = ambilRX(); //ini datanya
        count++;                       //ini indexnya
        RXC = 0;                       //reset receive flag
        flag=1;                        //flag ada data baru
        cnt_disprcv = 0;
        };
    if(flag==1){
        if(!temp){
            temp = ___buffer_[0];      //save ___buffer_[0] sebelum diberihkan
            olahdata(CLRBUF__);        //clear all data in ___buffer_
            ___buffer_[0] = temp;      //return data to ___buffer_[0]
            }
        }
    };
 
if (count > __MAXchars){               //data tidak boleh lebih dari arr_len - 17
    led_data = 1;
    count=0;
    flag=0;
    lcd_gotoxy(0,0);
    lcd_putsf("   ~DITOLAK_!   ");     //warn about overload data
    lcd_gotoxy(0,1);
    lcd_putsf("DATA KEBANYAKAN!");
    delay_ms(2000);
    olahdata(LOADMESS);                //clear ___buffer_ dan load splash message
    }
 
if (flag == 1){                        //adakah data baru yg dah jadi array??
    led_data = 1;
    flag_rcv = 1;
    lcd_clear();
    olahdata(ADDSPACE);                //add space to ___buffer_ for marquee fading
    count=0;
    lcd_gotoxy(0,1);
    lcd_putsf(" MAHO DETECTED! ");     //bila ada data baru diterima
    delay_ms(1000);
    for (i=0; i<=2; i++){
        lcd_gotoxy(0,1);
        lcd_putsf("  -PROCESSING-  "); //cuman bwt aksesoris aja
        delay_ms(100);                 //sebenarnya tulisan -PROCESSING-
        lcd_gotoxy(0,1);               //gak penting.
        lcd_putsf("                ");
        delay_ms(100);
        lcd_gotoxy(0,1);
        lcd_putsf("  -PROCESSING-  ");
        delay_ms(100);
        lcd_clear();
        lcd_gotoxy(0,0);
        lcd_putsf("TEXT RECEIVED:  ");
        }
    }
cnt_led++;                             //counter bwt timer led kedap kedip :D haha..
if (cnt_led >=4){
    cnt_led = 0;
    led_data = ~led_data;
    }
}
 
//Tampilan LCD Dynamic :D (left marquee) running text, moving message.. whatever lah
//dibawah adalah fungsi running text / moving message (left marquee)
//sudah ditambahi fungsi receive uart while on marquee process
void tampilan(unsigned char line){
unsigned int i,j,k;
for (i=lcd_number; i>=0; --i){
    if (i > lcd_number)break;
    lcd_gotoxy(i,line);
    for (j=0; j<(lcd_number-i); j++){
        lcd_putchar(___buffer_[j]);
        if (RXC == 1){
            terima();
            if (flag != 0){
                flag  = 0;
                count = 0;
                return;
                };
            }
        }
    terima();
    if (flag != 0){
        flag  = 0;
        count = 0;
        return;
        };
    }
k=0;
for (i=0; i<=strlen(___buffer_); i++){
    k++;
    lcd_gotoxy(0,line);
    for (j=0; j<16; j++){
        lcd_putchar(___buffer_[j+k]);
        if (RXC == 1){
            terima();
            if (flag != 0){
                flag  = 0;
                count = 0;
                return;
                };
            }
        if (___buffer_[j+k] == 0)return;
        }
    terima();
    if (flag != 0){
        flag  = 0;
        count = 0;
        return;
        };
    }
if (count >= 1){
    count  = 0;
    olahdata(LOADMESS);
    }
}
 
void olahdata(unsigned char mode){
unsigned int i,j;
switch (mode){
    case 0x01:
        j = strlen(___buffer_);
        for (i=0; i<=lcd_number; i++)___buffer_[(j)+i] = ' ';
        break; //diatas buat nambahin karakter spasi. Spasi perlu bwt text marquee
    case 0x02:
        j = strlen(___buffer_);
        for (i=0; i<=j; i++)___buffer_[i] = 0;
        break;
    case 0x03:
        j = strlen(___buffer_);          //+ load message
        for (i=0; i<=j; i++)___buffer_[i] = 0;
        for (i=0; i<=strlenf(pesan_pembuka); i++)___buffer_[i] = pesan_pembuka[i];
        j = strlenf(pesan_pembuka);
        for (i=0; i<=lcd_number; i++)___buffer_[(j)+i] = ' ';
        lcd_clear();
        lcd_gotoxy(0,0);
        lcd_putsf("WWW.NUBIELAB.COM");
        break;
    default:
        break;
    }
}

Hwahwa.. program iseng diwaktu luang, program lucu, enak kalo bwt latihan; programming with ease :)
bwt yang belon bisa, tetep semangat! mikrokontroler itu menyenangkan
apalagi pake bahasa C nyamm… rasanya seperti martabak super yg telornya 4.
Wokey, kalo ada pertanyaan silahkan kunjungi www.nubielab.com terus tulis aja pada kolom komentar atau kirim aja pertanyaanya lewat email ke herlambang @nubielab. com

program komplit dan simulasi proteus bisa didownload disini.

Happy programming^^
Herlambang Aribowo