Category Archives: Pemrograman C untuk AVR dgn CodeVision

Pengetahuan dasar Pemrograman Led Matrix

Scan

ledmatrix

Untuk menampilkan karakter ke sebuah segment kita harus menyalakan  led per kolom secara bergantian(scanning) terus menerus.  Karena  frekwensi scanning  cepat  sehingga semua led  terlihat seolah menyala bersamaan.

ledmatrix2.jpg

untuk karakter A maka kode untuk tiap kolom yg akan di scan adalah

kolom ke-1=0x7E , ke-2 : 0x09, ke-3 :0x09, ke-4: 0x7E, & kolom ke-5:0x7E

step/urutan menampilkan huruf A

kirim 0x7E  aktifkan kolom ke-1

kirim 0x09  aktifkan kolom ke-2

kirim 0x09  aktifkan kolom ke-3

kirim 0x7E  aktifkan kolom ke-4

 

berikut Contoh Program

/*****************************************************
Chip type : ATmega16
Program type : Application
Clock frequency : 11,059200 MHz
*****************************************************/

#include <mega16.h>
#include <delay.h>
// External Interrupt 0 service routine
unsigned short count, column, num, repeat,i;
unsigned char data[4]={‘A’,’B’,’C’,’0′};
void displayLEDmatrix(char huruf);

// Declare your global variables here
unsigned short Alphabets[130]={ 0x7E, 0x09, 0x09, 0x7E, 0xFF, // A
0x7f, 0x49, 0x49, 0x49, 0x36, // B
0x3e, 0x41, 0x41, 0x41, 0x22, // C
0x7f, 0x41, 0x41,0x22, 0x1c,
0x7f, 0x49, 0x49, 0x49, 0x63,
0x7f, 0x09, 0x09, 0x09, 0x01,
0x3e, 0x41, 0x41, 0x49, 0x7a,
0x7f, 0x08, 0x08, 0x08, 0x7f,
0x00, 0x41, 0x7f, 0x41, 0x00, // I
0x20, 0x40, 0x41, 0x3f, 0x01,
0x7f, 0x08, 0x14, 0x22, 0x41,
0x7f, 0x40, 0x40, 0x40, 0x60,
0x7f, 0x02, 0x04, 0x02, 0x7f,
0x7f, 0x04, 0x08, 0x10, 0x7f,
0x3e, 0x41, 0x41, 0x41, 0x3e,
0x7f, 0x09, 0x09, 0x09, 0x06,
0x3e, 0x41, 0x51, 0x21, 0x5e,
0x7f, 0x09, 0x19, 0x29, 0x46,
0x46, 0x49, 0x49, 0x49, 0x31, // S
0x01, 0x01, 0x7f, 0x01, 0x01,
0x3f, 0x40, 0x40, 0x40, 0x3f,
0x1f, 0x20, 0x40, 0x20, 0x1f,
0x3f, 0x40, 0x30, 0x40, 0x3f,
0x63, 0x14, 0x08, 0x14, 0x63,
0x07, 0x08, 0x70, 0x08, 0x07,
0x61, 0x51, 0x49, 0x45, 0x43 // Z
};

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

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

// Port B initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=0 State6=0 State5=0 State4=0 State3=1 State2=1 State1=1 State0=1
PORTB=0x0F;
DDRB=0xFF;

// 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=P State2=P State1=P State0=P
PORTD=0x0F;
DDRD=0x00;
// Global enable interrupts
#asm(“sei”)

while (1){
// huruf A mulai index array 0-5
//huruf B mulai index array 6-11
//dst

for(i=0;i<5;i++ )
{

displayLEDmatrix(data[i]);

}

};
}
void displayLEDmatrix(char huruf)
{
//=====================
num=huruf-65;
// Display 26 alphabets

for (repeat=0; repeat<100; repeat++)
{
column = 1;
for(count = num*5;count < (num*5+6);count++) //num=0,5,10,15,dst…
{
PORTB = ~Alphabets[count];
PORTA = column;
delay_ms(5);
column = column<<1;
}
}
delay_ms(10);

//=====================
}

Advertisements

Contoh Low Cost Counter Sederhana 4 Digit 7 Segment

Rangkaian counter sederhana yg kita buat menggunakan komponen minimal sehingga bisa menghemant cost.

– 1 pcs board AVR

–  1 pcs 4 digit 7 segment

–  12 pcs  female to female cable

counterminimal

7 segment yang saya gunakan adalah Common Catoda 4 segment untuk clock dengan konfigurasi pin dibawah ini

 

Data Konfigurasi kaki/pin 7 segment berguna untuk menghubungkan dengan pin pada  port microcontroller sebagai berikut ini :

counter4digit

Kode program

/*****************************************************

Chip type : ATmega8535
Clock frequency : 11.059200 MHz

*****************************************************/

#include <mega8535.h>
#include <delay.h>

void kirimbyte7segment(unsigned char data,unsigned char digit);
void writeData(int dat);

int dataglobal=0;

interrupt [EXT_INT0] void ext_int0_isr(void)
{
delay_ms(90);
// Place your code here
dataglobal=dataglobal +1;;
delay_ms(90);
}

// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
delay_ms(60);
// Place your code here
dataglobal=dataglobal -1;;
delay_ms(60);
}
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
writeData(dataglobal);
}
void writeData(int dat);
flash unsigned char text7segmentClock[]=
{  // dp-g-f-e-d-c-b-a
0b00111111,   //0
0b10000110,  / /1
0b01011011,  //2
0b11001111,  //3
0b01100110,  //4
0b11101101,  //5
0b01111101,  //6
0b10000111,  //7
0b01111111,  //8
0b11101111,  //9
0b00000000,  //  blank
0b01000000  // tanda  minus
};

void main(void)
{

char i=0;

// Port A initialization
PORTA=0xff;
DDRA=0xff;

// Port B initialization
PORTB=0xff;
DDRB=0xff;

// Port C initialization
PORTC=0xff;
DDRC=0xff;

// Port D initialization
PORTD=0xff;
DDRD=0xff;

// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Low level
// INT1: On
// INT1 Mode: Low level
// INT2: Off
GICR|=0xC0;
MCUCR=0x00;
MCUCSR=0x00;
GIFR=0xC0;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 10.800 kHz
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x05;
TCNT0=0xC0;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;
// Global enable interrupts
#asm(“sei”)

for(i=1;i<5;i++)
{
kirimbyte7segment(text7segmentClock[0],i);
delay_ms(100);
}

dataglobal=0;
while (1)
{

};
}

void kirimbyte7segment(unsigned char data, char digit)
{

if(digit==1)
{
PORTA.0=0;
PORTA.1=1 ;
PORTA.2=1 ;
PORTA.3=1 ;
}
if(digit==2)
{
PORTA.0=1;
PORTA.1=0 ;
PORTA.2=1 ;
PORTA.3=1 ;
}
if(digit==3)
{
PORTA.0=1;
PORTA.1=1 ;
PORTA.2=0 ;
PORTA.3=1 ;
}
if(digit==4)
{
PORTA.0=1;
PORTA.1=1 ;
PORTA.2=1 ;
PORTA.3=0 ;
}

PORTC =data ;
delay_ms(5);
}

void writeData(int dat) // dat max 4 digit
{
unsigned char j,sign=1;
unsigned char angka;

if(dat<0)
{
dat= dat * -1;
sign=0;
}

for(j=0;j<4;j++)
{

angka=dat%10;
dat /= 10; //6/10

if(angka==0)
{
if(dat==0)
{
if(sign==1)angka=10; // blank

if(sign==0)
{
angka=11; //tanda minus
sign=1;
}
}
}
kirimbyte7segment(text7segmentClock[angka], 4-j);

}
}

Pengetahuan Dasar Timer Untuk Pengukuran Jarak Dengan Ultrasonic

under construction.

Pada artikel ini sensor ultrasonik  yang digunakan adalah aktif high ,  maksudnya  pemicunya/start pulse  berupa sinyal pendek high spt pada gambar  dibawah ini . jika anda membeli sensor ultrasonic perhatikan datasheet /manual nya apakah  start pulse dan sinyal output sensor  nya aktif low atau aktif high.

SONAR1 Pada gambar diatas  sinyal  satrt pulse warna merah dikirim dari micon AVR ke sensor ultrasonic ,  sedangkan warna biru menggambarkan sinyal  output dari sensor ultrasonic. keduanya berjalan pada jalur yg sama tapi secara bergantian.

Cara kerja  (lihat gambar  diatas):

– AVR mentriger sensor (sinyal warna merah) agar mengirim    sinyal pendek (burst) dgn frekwensi 40khz

– Ketika Sensor ultrasonik mengirim burst , output sensor menjadi high    (sinyal warna biru), menandakan awal burst dipancarkan

– Burst menabrak pahlawan bertopeng dan kembali dipantukan ke sensor – Ketika sinyal pantulan terdeteksi, output sensor menjadi low

– Panjang pulsa high  (sinyal warna biru) dari output sensor sebanding dgn jarak yg ditempuh burst.

SONAR

Panjang sinyal output sensor  yg berwarna biru  mencerminkan waktu tempuh sinyal burst 40khz yg dipancarkan sampai pantulan diterima. waktu tempuh tsb  juga bisa digunakan untuk  mengetahui jarak tempuh sinyal . Karena di ketahui kecepatan Burst adalah 344 M/Detik maka jarak yg ditempuh oleh burst adalah

Jarak  sensor dgn pahlawan bertopeng = (T/2)*340   meter

Menghitung Panjang Pulsa dgn Timer Seperti kita ketahui Timer mempunyai  mode kerja antara lain

  • Mode Normal
  • Mode PWM
  • Mode CTC

Untuk menghitung panjang pulsa kita bisa menggunakan mode normal dan dengan mengaktifkan  interupsi  input capture (int  melalui pin ICP) .

menghitungpanjangpulsa

urutan satu siklus program kira kira begini :

1.  PORTD.6  diset  sbg output

2.   buat start pulse    low-high-low  di PORTD.6   ,  burst  dipancarkan

3. PORTD.6 diset sebagai input

4,  interupt input capture di aktifkan  , set pemicu interupt : rising edge.

5.   , sensor mengeluarkan pulsa high  , terjadi interupsi ICP  dipicu rising edge . low->high

6. service rutin  inteupsi ICP dijalankan  ,timer1 di aktifkan , TCNT1 mulai counting , triger interupsi ICP diset Falling edge.

7.   terjadi interupsi kedua  dipicu perubahan falling edge  high->low,  sinyal keluaran sensor .

8.  service rutin ICP kembali di laksanakan , matikan timer , ambil nilai  conter timer1 di reg TCNT1.

9. selesai

Pemrograman perhitungan panjang pulsa  output sensor  dengan interupsi ICP

/*****************************************************
This program was produced by the
CodeWizardAVR V2.04.4a Advance
Chip type : ATmega16
AVR Core Clock frequency: 11.059200 MHz
*****************************************************/

#include <mega16.h>
#include <delay.h>
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x15 ;PORTC
#endasm
#include <lcd.h>
#include <stdio.h>
#define awal 1
#define counting 2
#define finish 3
unsigned char status=3;
float counter;
char lcd_buffer[16];

// Timer1 input capture interrupt service routine
interrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
// Place your code here
if(status==awal)
{

TCCR1B |= 0x05; //Start Timer 1  ,  set clock  timer 10800 Hz
TCCR1B &= 0xBF; //bit ICSE=0 set triger ICP falling edge
status = 2;

return ;
}

if(status==counting)
{
TCCR1B &= 0xF8; // stop Timer 1
counter =TCNT1;

TCNT1 = 0x0000; //Clear Timer 1

TIMSK &= 0xDF; // matikan int ICP , PIND6 sebagai I/O lagi

DDRD |= 0x40; //Set PIND.6 as out

TCCR1B |= 0x40; //Rising edge

status = finish;
lcd_gotoxy(0,0);
lcd_clear();

//diketahui kecepatan burst = 344 m/detik

sprintf(lcd_buffer,”jarak=%f”,(float)(counter/2*(1/10800.0) *344.0);
lcd_puts(lcd_buffer);
delay_ms(500);
lcd_gotoxy(5,1);
lcd_putsf(“satuan Meter”);
return;

}

}
// Declare your global variables here

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

// 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=0x40;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 10.800 kHz
// Mode: Normal top=FFFFh

// Input Capture on Rising Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: On
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x40; //TIMER1 STOP
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x20;

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

lcd_gotoxy(0,1);
lcd_putsf(“distance meter”);
delay_ms(1500);
lcd_clear();
while (1)
{
delay_ms(1000);
//Bit 5 TIMSK – TICIE1=0, Timer1 Input Capture Interrupt(ICP) DISABLE
TIMSK &= 0xDF;

//======================SEND TRIGER TO PING SENSOR
DDRD |= 0x40; //Set PIND.6 /ICP as out
PORTD |= 0x40; // PIND.6 SET HIGH
delay_us(20);
PORTD.6 &= 0xBF; // PIND.6 SET LOW
DDRD &= 0xBF; // Set PORTD.6 as in
//===========================================

PORTD &= 0xBF; // PORTD.6 Tri-state tdk terkonek dgn resistor pull up

status =awal;

TIMSK |= 0x20; // aktifkan int ICP TICIE1=1

};
}

Pemrograman perhitungan panjang pulsa  output sensor tanpa  interupsi ICP

*****************************************************/

#include <mega16.h>
#include <delay.h>
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x15 ;PORTC
#endasm
#include <lcd.h>
#include <stdio.h>

float counter;
char lcd_buffer[16];

void main(void)

{

PORTD=0x00;
DDRD=0x40;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 10.800 kHz
// Mode: Normal top=FFFFh

// Input Capture on Rising Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: On
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x40; //TIMER1 STOP
TCNT1H=0x00;
TCNT1L=0x00;

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

// LCD module initialization
lcd_init(16);

// Global enable interrupts
#asm(“sei”)

while (1)
{
delay_ms(1000);
DDRD |= 0x40; //Set PIND.6 /ICP as out
PORTD |= 0x40; // PIND.6 SET HIGH

delay_us(20);
PORTD.6 &= 0xBF; // PIND.6 SET LOW
DDRD &= 0xBF; // Set PORTD.6 as in

TCNT1=0;
while (!PINB.6); // tunggu pulsa output sensor

TCCR1B=0x05; // start timer
while ((PINB.6) && !(TIFR & 0x80)); //tunggu akhir sinyal output sensor
TCCR1B=0x00; // stop timer
counter = TCNT1; // simpan counting TCNT1

lcd_gotoxy(0,0);

lcd_clear();

//diketahui kecepatan burst = 344 m/detik

sprintf(lcd_buffer,”jarak=%f”,(float)(counter/2*(1/10800.0) *344.0);
lcd_puts(lcd_buffer);
delay_ms(500);
lcd_gotoxy(5,1);
lcd_putsf(“satuan Meter”);

};

http://www.parallax.com/sites/default/files/downloads/28015-PING-Sensor-Product-Guide-v2.0.pdf

Pengetahuan Dasar Membuat file library (*.Lib) pada C CodevisionAVR

Supaya program yg kita buat lebih terstruktur  dan lebih simple sebaiknya fungsi fungsi yg sering digunakan kita simpan pada file yg terpisah , yaitu pada file library. Selain itu juga fungsi fungsi tersebut bisa kita gunakan kembali dengan mudah pada kode program dilain waktu dengan mudah yaitu dgn cara meng-include file library nya kedalam kode program.

contoh program-1  yg akan kita  sederhanakan dg membuat library file.

#include <stdio.h>

void main(void)
{
int a ,b, hasil1,hasil2;
a=10;
b=5;
hasil1 = jumlah(a,b);
hasil2 = pengurangan(a,b);

}

//fungsi jumlah
int jumlah(int a, int b)
{
return a+b;
}

//fungsi pengurangan
int pengurangan(int a, int b)
{
return a-b;
}

==================================

Langkah-langkah membuat file library di codevision

1. buat header file.

buka IDE codevisionAVR  klik file new , pilih type: source

creatinglibrariesb2

ketik code prototipe  fungsi   berikut ini

#pragma used+

/* prototype fungsi jumlah */
int jumlah(int a, int b);
int pengurangan(int a, int b);

#pragma used-

#pragma library mylib.lib

simpan di folder inc  dengan nama file libraryku.h

2. buat file library.lib

klik file new, pilih type: source

creatinglibrariesb2

ketik code definisi fungsi jumlah dan fungsi pengurangan berikut

//fungsi jumlah
int jumlah(int a, int b)
{
return a+b;
}

//fungsi  pengurangan
int pengurangan(int a, int b)
{
return a-b;
}

simpan file dengan nama libraryku.c di folder  lib atau folder apa saja.

klik menu  File->Convert to Library

maka codevision  akan membuat  file libraryku.lib di folder  Lib

selsai

dengan menggunakan file library  libraryku.lib ,  contoh program-1 diatas akan lebih sederhana sbb:

#include <stdio.h>
#include <libraryku.h>

void main(void)
{
int a ,b, hasil1;
a=10;
b=5;
hasil1 = jumlah(a,b);
hasil2 = pengurangan(a,b);
}

Pengetahuan Dasar ADC AVR microcontroller

UNDER CONSTUCTION….  AVR MICROCONTROLLER ADC PROGRAMMING

-AVR ADC TEORY DASAR

-AVR ADC REGISTER

-AVR ADC BASIC PROGRAMMING

admux_registerregister data hasil konversi ADC

adch_adcl_register

register control dan flag ADCSRA

adcsra_reg

SFIOR register

sfior_adc

Sample Circuit

adc_circuit

Kode Sample

#include <mega32.h>
#include <stdlib.h>
#include <lcd.h>
#include <delay.h>

unsigned int data_adc, data_adc1;
char temp[16],temp1[16];

// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0X15;
#endasm

#define mode_adc 0×00 ;

#define ADC_VREF_TYPE 0x00

// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=( (adc_input | ADC_VREF_TYPE) & 0xff);
//ADMUX=ADC_VREF_TYPE | adc_input;
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while(ADCSRA & 0X10==0); //
ADCSRA |= 0X10;
return ADCW;
}

void main(void)
{
PORTD=0xff;
DDRD=0X07;
// ADC initialization
// ADC Clock frequency: 750.000 kHz
// ADC Voltage Reference: AREF pin
// ADC Auto Trigger Source: None
//ADMUX = ADC_VREF_TYPE & 0xff;
ADMUX=ADC_VREF_TYPE;
ADCSRA=0xA3;
SFIOR&=0x1F;

// LCD module initialization
lcd_init(16);

while (1)
{
lcd_clear( );
lcd_gotoxy(0,0);
lcd_putsf(“kelas-mikrokontrl”);
lcd_gotoxy(0,1);
lcd_putsf(“nilai ADC”);
//=========================================
data_adc=read_adc(0); //baca ADC channel(x)
itoa(data_adc,temp); // converts integer data_adc characters in string temp.
lcd_gotoxy(10,1) ;
lcd_puts(temp);
delay_ms(700);
//=========================================
data_adc1=read_adc(1); //baca ADC channel(x)
itoa(data_adc1,temp); // converts integer data_adc characters in string temp.
lcd_gotoxy(14,1);
lcd_puts(temp);
delay_ms(700);

};
}

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:

usartregisters

AVR_USART

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)

UCSRA

• 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.

UCSRB

• 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)

tabel_ucsz

• 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.

UCSRC

• 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 :

tabel_ump

• 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:

setting_ubrr

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%.

tabel_ubrr

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&amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;gt;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:

codevision_usart

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:

dualusart

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

dualusartcavcr

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