Receive Data UART Menggunakan Scanf CodevisionAVR

Untuk menerima data serial bisa menggunakan getchar(). Akan tetapi fungsi getchar() ini hanya mampu menerima satu karakter string. Agar kita bisa menerima data yang lebih kompleks, bisa kita gunakan fungsi scanf. Fungsi scanf sendiri ada di library stdio.h pada codevisionAVR. Dengan menggunakan scanf kita bisa menerima data string atau data angka yang dikirim dalam bentuk string.  Fungsi scanf ini akan mengembalikan nilai angka dari data angka yang dikirim dalam string. Berikut pemisalan program dalam penggunaan scanf.


...

int day, year;
char monthname[20];

void main(void)

...

while(1)
{

scanf("%d %s %d", &day, monthname, &year);
printf("%d %s %d", day, monthname, year);

}

}
 

program di atas akan menerima data lalu mengirim lagi lewat UART. Misal mikrokontroler kita koneksikan ke PC. Dari PC kita akan mengirim: 20 april 2012, maka mikrokontroler akan menerima data tersebut dalam bentuk tipe data yang kita setting sebelumnya. variabel day = 20, monthname = {‘a’ ‘p’ ‘r’ ‘i’ ‘l’}, year = 2012. Untuk data angka dalam penggunaan scanf ditambahkan & di depannya, misal: &day, &year. Dalam program tersebut, mirkokontroler akan mengirim kembali ke PC dengan fungsi printf.

Berikut contoh program lengkapnya. Misal saya akan menerima data  dari PC, menampilkan data yang diterima lewat LCD, dan mengirim kembali data yang diterima ke PC.

/*****************************************************
Chip type           : ATmega8535
Program type        : Application
Clock frequency     : 16.000000 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 128
*****************************************************/

#include <mega8535.h>

// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x1B ;PORTA
#endasm
#include <lcd.h>
#include <delay.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;
};
};
}

#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
char data;
while (rx_counter==0);
data=rx_buffer[rx_rd_index];
if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
#asm("cli")
--rx_counter;
#asm("sei")
return data;
}
#pragma used-
#endif

// USART Transmitter buffer
#define TX_BUFFER_SIZE 8
char tx_buffer[TX_BUFFER_SIZE];

#if TX_BUFFER_SIZE<256
unsigned char tx_wr_index,tx_rd_index,tx_counter;
#else
unsigned int tx_wr_index,tx_rd_index,tx_counter;
#endif

// USART Transmitter interrupt service routine
interrupt [USART_TXC] void usart_tx_isr(void)
{
if (tx_counter)
{
--tx_counter;
UDR=tx_buffer[tx_rd_index];
if (++tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0;
};
}

#ifndef _DEBUG_TERMINAL_IO_
// Write a character to the USART Transmitter buffer
#define _ALTERNATE_PUTCHAR_
#pragma used+
void putchar(char c)
{
while (tx_counter == TX_BUFFER_SIZE);
#asm("cli")
if (tx_counter || ((UCSRA & DATA_REGISTER_EMPTY)==0))
{
tx_buffer[tx_wr_index]=c;
if (++tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0;
++tx_counter;
}
else
UDR=c;
#asm("sei")
}
#pragma used-
#endif

// Standard Input/Output functions
#include <stdio.h>

// Declare your global variables here
unsigned char kata[16];
int day, year;
char monthname[20];

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: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 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: Timer 2 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;

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud rate: 9600
UCSRA=0x00;
UCSRB=0xD8;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x67;

// 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);

// Global enable interrupts
#asm("sei")
while (1)
{
scanf("%d %s %d", &day, monthname, &year);  //terima data UART
//-------kirim data ke LCD--------
lcd_clear();
lcd_gotoxy(0,0);
sprintf(kata,"%d %s %d", day, monthname, year);
lcd_puts(kata);
//--------------------------------
printf("%d %s %d", day, monthname, year);   //kirim data UART
};
}

44 Responses to Receive Data UART Menggunakan Scanf CodevisionAVR

  1. fuad says:

    misal saya ingin mengirimkan data angka ke mikro dari delphi, cara pengirimannya bgaimana dan terima datanya bagaimana ???

    terima kasih

    • wangready says:

      klo d delphi gk tau gan…kirimnya data string gan, cara terimanya ada di post pake scanf…

    • Irul kutu solder says:

      pake komponen comport gan..
      jadi setelah mikronya di isi program , misalnya baca adc trus mengirimkan data tsb melalui uart, selanjutnya tinggal buat form pd delphi yg komponennya ada comportnya, baru di buat koding scaning input serial yg di jadiin data integer.slnjutnya terserah agan, apa mau diolah menjadi grafik .dll

      maaf, masih nubie gan..hehe

  2. joan says:

    bagai mana cara untuk kendali led dan servo melalui uart.
    misal jika kirim data ‘1’ led on dan ‘0’ led off. untuk servo jika kirim data 90 maka servo bergerak sebesar 90 derajat.

    trimakasih

  3. fuad says:

    untuk serialnya di setting interupt tidak gan???

    berarti untuk penerimaanya sama dengan tutorial diatas ya???

  4. asyrofil says:

    mas ,, mw tnya ni misal kita mw buat perintah dari mikri 1 ke mikro 2,,pake protokol itu gmana mas ??

  5. hamdi says:

    gan , mw tanya kalo mw membuat suatu hitungan data tapi datanya di peroleh dari perangkat lain itu gmn ya contoh programnya ,, trims
    pake kom usart tapi pake fungsi counter itu bs ga ?

    • wangready says:

      kalo saya pake fungsi scanf disimpan di while(1), tapi di prosesnya tidak menggunakan delay. saya pernah coba pake delay jadinya scanfnya ketahan sama delay. Tapi scanf ini metodenya tidak seperti getchar yang menunggu sampai ada data diterima. pseudo code saya.
      while(1)
      {
      scanf(“data1:%d data2:%d”, buffer1, buffer2);
      proses();
      }
      dalam aplikasi lain mungkin bisa dimodif dengan getchar() atau read register UDR sesuai kebutuhan aplikasi.
      maksud agan pake fungsi counter itu bgmana?

  6. andi says:

    mau tanya gan, kebetulan saya membuat alat interface alat uji tarik. Nah untuk hasil data yang sudah valid di tampilkan di alat uji tarik melalui lcd 2×16. Apa bisa dari hasil data yang ditampilkan ke dalam lcd alat uji tarik dibaca dengan mikro kembali untuk komunikasi serial?

  7. sekedar berbagi aja brooh..

    kalo mau interface UART ke delphi bisa menggunakan komponen Comport..melalui Comport ini lah Delphi bisa berkomunikasi dengan Hyperterminal komputer,,jadi sama dengan menggunakan Hyperterminal, hanya saja dengan delphi kita bisa membuat tampilannya sesuka hati🙂

  8. El Shaarazy says:

    Bagaimana klo data yang kita kirim dari infra merah kemudian di terima oleh receiver TSOP 4838 kemudian data tersebut kita tampilkan di LCD, program akuisisi data

    • wangready says:

      mungkin kira2 sperti ini gan.
      -data dikirim IR pake Tx:
      char kata_kirim[32];
      int sensor = 12; //misal data sensor
      sprintf(kata_kirim,”data_lcd=%d”,sensor);//pake sprintf biar bisa kirim text ditambah data variabel kita
      puts(kata_kirim);
      -data diterima receiver pake Rx:
      char kata_terima[32];
      int data_terima;
      while(1)
      {
      scanf(“data_lcd=%d”,&data_terima);
      lcd_clear();
      lcd_gotoxy(0,0);
      sprintf(kata_terima,”data terima=%d”, data_terima);
      lcd_puts(kata_terima);
      }

  9. mas saya mau tanya….
    saya pakai atmega 16 dan LCD trus ada modul MP3 (buat play file .wav)

    program untuk nampilin rekaman yg sesuai dgn tampilan LCD gmn yah mas??
    Thanks before

  10. mau tanya gan….
    saya buat termometer dgn tampilan LCD + out put suara….
    program untuk menampilkan suara rekaman yg sesuai dgn LCD gmn ya gan???

  11. Reza says:

    saya mau tanya donk gan,,,
    di mikrokontroler saya bikin program stopwatch pakai counter, nah saya mau ngirim data stopwatch itu ke komputer gan tanpa perlu pake perintah dari pc, kira2 gimana ya program untuk UARTnya? apa bisa langsung pake printf?

    • wangready says:

      bisa gan, pake printf….

      • Reza says:

        ok bisa gan, sory mau nanya lagi nih,,, hehe
        disitu jd datanya dikirim terus menerus y gan, gimana caranya biar dikirimnya bisa satu persatu pake tombol? jadi ketika kita tekan tombol maka data dikirim….

      • wangready says:

        klo bayangan saya, untuk menghitung variabel stopwatchnya agan bisa pake timer interrupt gan, nanti bagian input tombol bisa disimpan di while(1) atau bisa juga sebaliknya…
        atau jika disimpan di while(1) semua, agan pake deteksi rising edge atau falling edge untuk deteksi tombol sambil menghitung stopwatchnya disimpan di while(kondisi tombol)

  12. Windya Saputra says:

    gan, mau tanya donk, klo misalkan data itu di kirim ke matlab gmn yaa program buat avrnya trs perintah di command windows matlabnya gmn juga yaa ??
    =newbie=

    • wangready says:

      daripada pake command window buat .m file aja gan…
      open port serial nya dulu

      %*******************inisialisasi serialport*****************************
      delete(instrfindall); 
      S1 = serial ('COM3', 'Baudrate', 9600, 'DataBits', 8, 'Parity','none'); 
      fopen(S1);
      

      klo buat nerima datanya

      linedata = fgetl(S1);
      data_dec = textscan(linedata,'data %d %f %d');
      dat_A  = data_dec{1};
      dat_B  = data_dec{2};
      dat_C  = data_dec{3};
      

      coba aja gan liat disini sebagai contohnya…https://wangready.wordpress.com/2013/11/17/mem-plot-data-serial-pada-matlab/
      klo dari AVR nya pake printf aja…

  13. hasmi bauh says:

    iya gan, bisa ga ajari bikin deteksi kata di hyperterminal pake ATMega 162
    jadi scenarionya mikro ngirim kata ke hyperterminal “ketikan huruf”, trs kita ngetik misalnya “belajar”, kemudian di tampilan di lcd gitu
    soalnya dr kmrn saya nyoba pake tutorial web agan, ga ada error tp ga terjadi apa2 waktu saya compile ke mikro hehe
    mohon bimbingannya

    • wangready says:

      masa sih gan, coba habis ngirim data dari hyperterminalnya tekan enter…
      klo gk, pake getchar aja gan

      char data[32];
      int i;
      .
      .
      .
      while(1)
      {
        for (i=0;i<32;i++)
         data[i]=0; //bersihkan variabel
       for (i=0;i<32;i++)
       {
         data[i] = getchar();
         if(data[i]==0x0A)//char enter
           break;
       }
       lcd_clear();
       lcd_gotoxy(0,0);
       lcd_puts(data);
      }
      
  14. Iroel says:

    @hasmi bauh &wangready

    char data[32];
    int i;
    .
    .
    .
    while(1)
    {
    for (i=0;i<32;i++)
    data[i]=0; //bersihkan variabel
    for (i=0;i<32;i++)
    {
    data[i] = getchar();
    if(data[i]==0x0D)//char enter
    break;
    }
    lcd_clear();
    lcd_gotoxy(0,0);
    lcd_puts(data);
    }

    listingnya diatas udah benar, cuma char enternya salah (buka 0x0A, tapi 0x0D)
    dalam hyperterminal, saat user menekan enter, maka karakter 0X0D (13 desimal) yang dikirim sebagai enter.kalau 0x0A itu karakter linefeed (pindah baris). adakalanya hyperterminal mengirim 0D dan 0A secara bergantian:
    contoh: text +0D + 0A (saat tekan enter)
    tapi secara default, karakter enter adalah 0x0D (13), sementara linefeed(0x0A) jarang diikutkan (berganung seting hyperterminal.
    mudah2an membantu

  15. Hasmi Baih says:

    bdw pada bener semua gan, thx😀

  16. Hasmi Baih says:

    oh iya mau tanya lagi, kan ini udah bisa nyecan
    niatnya kan uart 1 -> hyperterminal *buat nyecan kalimat yg diketik lwt keyboard
    ntar dikirim pake uart0 -> semacam sms gateway

    nah kan nyecannya kalimat tadi pake program yg diatas :

    for (i=0;i<32;i++)
    data[i]=0; //bersihkan variabel
    for (i=0;i<32;i++)
    {
    data[i] = getchar1();
    if(data[i]==0x0D)//char enter
    break;
    }
    lcd_clear();
    lcd_gotoxy(0,0);
    lcd_puts(data);

    nah itu saya mau ngeluarin variable "data" ke uart0 pake printf(data) kok ga bisa ya
    gmn ya gan biar bisa ngeluarin satu array dulu sampek habis dari variable data yg didapat dari inputan keyboard biar bisa dikirim ke uart0

    semoga paham maksud saya hehe
    mohon bimbingannya

    • wangready says:

      pake fungsi puts() gan, misal:
      puts(data);
      soalnya variabel data kan tipe nya char *data…lengkapnya bisa dilihat di library stdio.h yg isinya sbb.
      void puts(char *str);
      int printf(char flash *fmtstr,…);

  17. hasmibaih says:

    semisal saya bikin program pake 2 uart
    uart 0 untuk mendeteksi karakter dr inputan keyboard
    trs uart 1 untuk mengirim karakter yg di deteksi dr inputan keyboard tadi dengan sms gateway apakah benar programnya gni gan?

    void sms()
    {
    char data[32];
    int i;

    for (i=0;i<32;i++)
    data[i]=0; //bersihkan variabel
    for (i=0;i<32;i++)
    {
    data[i] = getchar1();
    if(data[i]==0x0D)//char enter
    break;
    }
    lcd_clear();
    lcd_gotoxy(0,0);
    lcd_puts(data);

    putchar(13); // sinkronisasi baudrate 115200
    delay_ms(500);
    putchar(13); // sinkronisasi baudrate 115200
    delay_ms(500);
    printf("at");
    putchar(13);
    delay_ms(500);
    printf("at+cmgf=1");
    putchar(13);
    delay_ms(500);
    printf("at+cmgs=\"083849xxx\"");
    putchar(13);
    delay_ms(2000);
    puts(data); // mengirim karakter yg dr inputan keyboard uart 1 dengan uart0
    delay_ms(500);
    putchar(26);
    putchar(13);
    lcd_gotoxy(0,1);
    lcd_putsf("done");
    delay_ms(500);
    }

    mohon bimbingannya gan
    thx

  18. gan kalo pake kode terima uart menggunakan scanf -> scanf(“%d”, &day)
    perintah kirim data dari vb ny gimana gan ? Bener gak kalo cuma kayak gini seriarport1.write(textboxt.text) ?

    • wangready says:

      kasih kepala data aja gan untuk mengurangi salah terima datanya
      misal:
      scanf(“data_day=%d,&day)
      sya agak lupa syntax vb, intinya kirim datanya sesuai format scanf, misal:
      day data integer
      serialport1.write(“data_day=”+day.toString())

  19. saya mau nanya nh gan … kalo pake kode scanf(“%d”, &PWM) ?
    perintah kirim dari vb nya gimana kode ny nh mas ?

  20. m33th0 says:

    bos, kalau mau baca data string dari serial kemudian data tersebut disimpan di eeprom internal gmn y caranya?
    trims

    • wangready says:

      di codevision avr misal buat ngambil maksimal 32 karakter sampai ketemu karakter enter, tambahkan eeprom depan variabel yg kita inginkan

      eeprom char data[32];

      for(i=0;i<32;i++) data[i]=0;
      for(i=0;i<32;i++)
      {
      data[i]=getchar();
      if (data[i]==0x0A)//cek ASCII enter
      break;
      }
      data sudah tersimpan di eeprom

  21. Ira says:

    Saya buat proyek perparkiran, kalau mobil mengenai sensor makan counter jumlah baris parkir kosong berkurang.
    mikro saya sudah berhasil membaca sensor dan menghasilkan angka 1 0 ((1=LED menyala, 0=LED mati karna sensor), komunikasi menggunakan RS232.
    nah permasalahannya, bagaimana cara mengolah data 1,0 dari mikro ke delphi 7 utk bisa digunakan sebagai counter.
    terimakasih banyak sebelumnya, makasih

  22. Bluekyuu39 says:

    Halo gan, saya newbie di codevisionavr , pingin tanya gan… kalau saya ingin memprogram ATmega128 agar bisa ngirim karakter hexadecimal melalui TX uart RS232 ke sensor (camera), gimana ya syntax nya? misalnya hexa yg mau dikirim (56 00 10 00) Respon dari camera maunya dibaca dari hyperterminal. Thanks Gan 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