Membuat PIN Rx UART 8N1 dari PORT Biasa Mikrokontroler AVR (CodeVision AVR)

Berikut ini adalah program yang saya gunakan untuk menerima data serial dari fungsi biasa pin IO. Metode yang saya gunakan adalah menangkap signal yang dikirim dengan sela waktu perioda_baudrate sebanyak data bit yang dikirim, dalam kasus ini berformat UART 8N1. Untuk sela waktu, saya menggunakan fungsi delay my_delay_us() yang dibuat sendiri dari fungsi library bawaan karena fungsi delay_us() tidak bisa diisi dengan variabel. Akan tetapi hal itu menjadikan fungsi my_delay_us() tidak presisi. Untuk itu saya menambahkan konstanta_error untuk men-tunning agar nilai delay tepat. konstanta_error saya dapat dengan men-tunning-nya dengan terlebih dahulu melihat signal perioda dari my_delay_us(konstanta_error) dengan mengeluarkan HIGH dengan sela waktu tersebut kemudia juga dengan LOW pada salah satu PORT IO dan mencocokan dengan hitungan perioda baudrate yang digunakan. Dengan begitu, bisa didapatkan konstanta_error yang tepat.

/*****************************************************
Chip type               : ATmega16
Program type            : Application
AVR Core Clock frequency: 11.059200 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 256
*****************************************************/

#include mega16.h>
#include delay.h>
#include stdio.h>

// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0x1B ;PORTA
#endasm
#include lcd.h>

unsigned char kata[16];

// Declare your global variables here
#define my_RXport PINC.0 //set pin rx
#define my_RXport_dir DDRC.0 //direksi port

void my_delay_us(int n)
{
    while(--n)
    delay_us(1);
}

int perioda_baudrate;
void rx_init()
{
    int baudrate = 9600; //set baudrate
    int konstanta_error = -54; //ditunning sampai mendapat hasil optimal
    my_RXport_dir = 0; //set sebagai input
    perioda_baudrate = (1000000/baudrate) + konstanta_error; //dalam mikro second
}

unsigned char my_getchar()
{
    unsigned char   urut_data
                    ,data=0;
    while(my_RXport){}; //tunggu kepada data logic LOW
    my_delay_us(perioda_baudrate);
    for(urut_data=0;urut_data<8;urut_data++)
    {
        data = data >> 1;
        if(my_RXport)
            data += 128;
        else
            data += 0;
        my_delay_us(perioda_baudrate);
    }
    return(data);
}

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// LCD module initialization
lcd_init(16);
rx_init();
while (1)
      {
      // Place your code here
        sprintf(kata,"%c",my_getchar());   
        lcd_puts(kata);    
      };
}

14 Responses to Membuat PIN Rx UART 8N1 dari PORT Biasa Mikrokontroler AVR (CodeVision AVR)

  1. Ibn Syaifullah says:

    udah nyoba nih mas? ada simulasi atau yang lain??

  2. Ibn Syaifullah says:

    bukannya di header CV AVR udah ada delay_us(unsigned int n)?

  3. TooPayZ says:

    Klo komunikasi UART serial asinkron tidak sesederhana itu lho mas…
    Untuk putchar(); mungkin gak masalah tapi untuk getchar() dalam hal ini my_getchar() rawan kesalahan / error.
    Sepertinya sudah di jelaskan di datasheet mikrokontroller ATmega….

    Dan sebagai saran saja, gunakan interupsi timer jangan delay_us..
    Karena beda baudrate harus tuning terus…
    int konstanta_error = -54; //ditunning sampai mendapat hasil optimal…

    Sekedar informasi saja..
    Btw thanks sharing codingnya…

  4. okakzai says:

    Simulasinya pake Proteus gan!? Minta dong file simulasinya, saya coba di Proteus kok ga keluar apa-apa di LCD. Trims

  5. okakzai says:

    Sudah mas, tapi karakter yang keluar tdk sama dgn yg dikirimkan. Salahnya dimana ya? Mas tolongin saya dong, benerin program mikrokontrolernya. Hasil simulasi beserta programnya saya taruh di link ini:
    http://www.ziddu.com/download/20320780/RxBitBang.zip.html. Thanks sebelumnya🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s