Pemrograman MCS51 (AT89S51,52 dll) dengan Bahasa C

Software yang digunakan dalam ujicoba kali ini ialah MIKROC 8051 ver 2.2. pemrograman mikrokontroler AT89S51 dengan bahasa C memang lebih mudah jika dibandingkan dengan menggunakan Assembler. apalagi jika kita ingin membuat perangkat yang rumit akan sangat terasa perbedaannya.

Awal pembuatan program bisa di lihat pada video berikut :


Resolusi lebih tinggi klik disini



Berikut merupakan daftar uji coba tersebut:
1. Percobaan LED
Skema Uji Coba LED

Program LED 1 menyalakan Led dengan bilangan heksa
void main() {
P0=0x00;     // LED SEMUA ON
}


Program LED 2 menyalakan sebagian Led dengan bilangan heksa
void main() {
P0=0xF0;     // LED P0-P3 ON
}

Program LED 3 menyalakan 1 Led dengan bilangan biner
void main() {
P0=0b11111110;     // LED 1 ON
}

Program LED 4 menyalakan 2  Led dengan bilangan biner
void main() {
P0=0b01111110;     // LED 1 dan 8 ON
}

Program LED 5 menyalakan Led per bit
void main() {
P0_0_bit=0;     // LED 1  ON
P0_7_bit=0;     // LED 8 ON
}


Program LED 6 Blinking led dengan delay
void main() {
while(1){
P0=0b00000000;     //led ON
delay_ms(1000);    //tunda 1 detik
P0=0b11111111;     //led OFF
delay_ms(1000);    //tunda 1 detik
} 

}

2. Percobaan Switch
Skema Uji Coba Switch

Program Switch 1
void main() {
while(1){
if(P1_0_bit==0){P0=0x00;}  //jika tombol 1 ditekan LED ON
}
}

Program Switch 2 
void main() {
while(1){
if(P1_0_bit==0){P0=0x00;}  //jika tombol 1 ditekan LED ON
if(P1_1_bit==0){P0=0xff;}  //jika tombol 2 ditekan LED OFF
}
}

Program Switch 3
void main() {
while(1){
if(P1_0_bit==0){P0_0_bit=0;}  //jika tombol 1 ditekan LED 1 ON
if(P1_1_bit==0){P0_1_bit=0;}  //jika tombol 2 ditekan LED 2 ON
if(P1_2_bit==0){P0=0xff;}     //jika tombol 3 ditekan LED OFF
}
}

Program Switch 4
void main() {
while(1){
if(P1_0_bit==0){P0=0x00;}     //jika tombol 1 ditekan led on dilepas led off
else{P0=0xff;}
} 
}

3. Percobaan LCD
Skema Uji Coba LCD

Program LCD 1
// lcd pinout settings
sbit LCD_RS at P2_0_bit;
sbit LCD_EN at P2_1_bit;
sbit LCD_D7 at P2_7_bit;
sbit LCD_D6 at P2_6_bit;
sbit LCD_D5 at P2_5_bit;
sbit LCD_D4 at P2_4_bit;

void main() {
lcd_init();
Lcd_Out(1, 3, "tutorial-");             //tulis di baris ke 1 kolom 3
lcd_Out(2,1, "mikrokontroler");   //tulis di baris ke 2 kolom 1
}


Program LCD 2
// lcd pinout settings
sbit LCD_RS at P2_0_bit;
sbit LCD_EN at P2_1_bit;
sbit LCD_D7 at P2_7_bit;
sbit LCD_D6 at P2_6_bit;
sbit LCD_D5 at P2_5_bit;
sbit LCD_D4 at P2_4_bit;

void main() {
lcd_init();
Lcd_Out(1, 3, "Uji coba");               //tulis di baris ke 1 kolom 3
Lcd_Cmd(_LCD_CURSOR_OFF);    //matikan kursor
while(1)
{
Lcd_Cmd(_LCD_SHIFT_RIGHT);     //geser tulisan ke kanan
delay_ms(1000);                              //tunda 1 detik
}                                                          //ulangi 
}


Program LCD 3
// lcd pinout settings
sbit LCD_RS at P2_0_bit;
sbit LCD_EN at P2_1_bit;
sbit LCD_D7 at P2_7_bit;
sbit LCD_D6 at P2_6_bit;
sbit LCD_D5 at P2_5_bit;
sbit LCD_D4 at P2_4_bit;

void main() {
lcd_init();
Lcd_Out(1, 3, "Uji coba");               //tulis di baris ke 1 kolom 3
Lcd_Cmd(_LCD_CURSOR_OFF);    //matikan kursor 

}

Command LCD lainnya :


4. Percobaan I2C RTC (Jam Digital Dengan LCD)
Skema Uji Coba RTC

Program Jam Digital
char seconds, minutes, hours, date, month;  // Global date/time variables
unsigned int year;
unsigned int RTCModuleAddress, YearOffset; // RTC chip description variables


#define DS1307          // Uncomment this line if you use DS1307 RTC chip (mE RTC2 extra board)

// Software I2C connections
sbit Soft_I2C_Scl at P1_0_bit;
sbit Soft_I2C_Sda at P1_1_bit;
// End Software I2C connections

// LCD module connections
sbit LCD_RS at P2_0_bit;
sbit LCD_EN at P2_1_bit;

sbit LCD_D4 at P2_4_bit;
sbit LCD_D5 at P2_5_bit;
sbit LCD_D6 at P2_6_bit;
sbit LCD_D7 at P2_7_bit;
// End LCD module connections

//------------------ Performs project-wide init
void Init_Main() {



  #ifdef DS1307
    RTCModuleAddress   = 0xD0;
    YearOffset         = 2000;
  #endif


  Soft_I2C_Init();           // Initialize Soft I2C communication
  Lcd_Init();                // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);       // Clear LCD display
  Lcd_Cmd(_LCD_CURSOR_OFF);  // Turn cursor off

  LCD_Out(1,1,"Date:");      // Prepare and output static text on LCD
  Lcd_Chr(1,8,':');
  Lcd_Chr(1,11,':');
  LCD_Out(2,1,"Time:");
  Lcd_Chr(2,8,':');
  Lcd_Chr(2,11,':');
}


//--------------------- Reads time and date information from DS1307 RTC
void Read_Time_DS1307() {
  char byte_read;

  Soft_I2C_Start();                   // Issue start signal
  Soft_I2C_Write(RTCModuleAddress);   // RTC module address + write (R#/W = 0)
  Soft_I2C_Write(0);                  // Start from seconds byte
  Soft_I2C_Start();                   // Issue repeated start signal
  Soft_I2C_Write(RTCModuleAddress+1); // RTC module address + read  (R#/W = 1)

  byte_read = Soft_I2C_Read(1);                                // Read seconds byte
  seconds = ((byte_read & 0x70) >> 4)*10 + (byte_read & 0x0F); // Transform seconds

  byte_read = Soft_I2C_Read(1);                                // Read minutes byte
  minutes = ((byte_read & 0x70) >> 4)*10 + (byte_read & 0x0F); // Transform minutes

  byte_read = Soft_I2C_Read(1);                                // Read hours byte
  if (byte_read.B6) {                                          // 12h format
    hours = ((byte_read & 0x10) >> 4)*10 + (byte_read & 0x0F); // Transform hours
    if (byte_read.B5)                                          // PM flag
      hours = hours + 12;
  }
  else
    hours = ((byte_read & 0x30) >> 4)*10 + (byte_read & 0x0F); // Transform hours

  byte_read = Soft_I2C_Read(1);                                // Read weekday byte

  byte_read = Soft_I2C_Read(1);                                // Read date byte
  date = ((byte_read & 0x30) >> 4)*10 + (byte_read & 0x0F);    // Transform date

  byte_read = Soft_I2C_Read(1);                                // Read month byte
  month = ((byte_read & 0x10) >> 4)*10 + (byte_read & 0x0F);   // Transform month

  byte_read = Soft_I2C_Read(1);                                // Read year byte
  year = YearOffset + ((byte_read & 0xF0) >> 4)*10 + (byte_read & 0x0F); // Transform year

  Soft_I2C_Stop();                    // Issue stop signal
}

//--------------------- Reads time and date information from RTC
void Read_Time() {

  #ifdef DS1307
    Read_Time_DS1307();
  #endif
}

//-------------------- Output values to LCD
void Display_Time() {

  Lcd_Chr(1, 6, (date / 10)   + 48);       // Print tens digit of date variable
  Lcd_Chr(1, 7, (date % 10)   + 48);    // Print oness digit of date variable
  Lcd_Chr(1, 9, (month / 10)  + 48);
  Lcd_Chr(1,10, (month % 10)  + 48);
  Lcd_Chr(1,12, ((year / 1000) % 10) + 48);    // Print year
  Lcd_Chr(1,13, ((year / 100)  % 10) + 48);
  Lcd_Chr(1,14, ((year / 10)   % 10) + 48);
  Lcd_Chr(1,15, (year % 10)          + 48);

  Lcd_Chr(2, 6, (hours / 10)   + 48);
  Lcd_Chr(2, 7, (hours % 10)   + 48);
  Lcd_Chr(2, 9, (minutes / 10) + 48);
  Lcd_Chr(2,10, (minutes % 10) + 48);
  Lcd_Chr(2,12, (seconds / 10) + 48);
  Lcd_Chr(2,13, (seconds % 10) + 48);
}

//----------------- Main procedure
void main() {


  Init_Main();               // Perform initialization

  while (1) {                // Endless loop
    Read_Time();             // Read time from RTC
    Display_Time();          // Prepare and display on LCD

    Delay_ms(950);          // Wait 1 second
  }
}

5. Percobaan SOUND (mikrokontroler mengeluarkan nada)
Skema Uji Coba Sound

sbit Sound_Play_Pin at P2_0_bit;
/*
220.00 Hz A (La)
246.94 Hz B (Si)
261.63 Hz C (Do)
293.66 Hz D (Re)
329.63 Hz E (Mi)
349.23 Hz F (Fa)
392.00 Hz G (Sol)
*/

void main() {
 Sound_Init();
 while(1){

 Sound_Play(262, 250);  // Frequency = 262Hz, duration = 250ms DO
 Sound_Play(294, 250);  // Frequency = 294Hz, duration = 250ms RE
 Sound_Play(330, 250);  // Frequency = 330Hz, duration = 250ms MI
 Sound_Play(349, 250);  // Frequency = 349Hz, duration = 250ms FA
 Sound_Play(392, 250);  // Frequency = 392Hz, duration = 250ms SO
 Sound_Play(220, 250);  // Frequency = 220Hz, duration = 250ms LA
 Sound_Play(247, 250);  // Frequency = 247Hz, duration = 250ms SI
 }


}

semua file uji coba tersebut dapat di download disini


Tutorial Mikrokontroler AT89S51

Tutorial Mikrokontroler AT89S51 (Versi Bahasa Assembler)
Dalam tutorial ini dibahas mengenai mikrokontroler keluarga MCS51 yang diwakili oleh AT89S51, karena dalam aplikasinya nanti langkah pemrogramannya akan sama dengan jenis lain AT89Sxx/AT89Sxxxx.

Dasar Teori
Spesifikasi Mikrokontroler AT89S51
Konfigurasi PIN
Rangkaian Clock
Organisasi Memori
Timer dan Counter
Komunikasi Serial












Percobaan :  
Percobaan 1 Display LED
Percobaan 2 Push Button
Percobaan 3 Seven Segmen
Percobaan 4 Relay Driver
Percobaan 5 ADC
Percobaan 6 DAC
Percobaan 7 LCD Character
Percobaan 8 Komunikasi Serial (USART)
Percobaan 9 Motor Stepper
Percobaan 10 PWM

Dokumen Pendukung
Datasheet AT89S51
Datasheet MAX232
Datasheet Karakter LCD 16x2


Software Pendukung
Top View Simulator (Compiler dan Simulator)
USART Tester (serial komunikasi tester) 

Daftar Pustaka 



Percobaan 1 (Kontrol LED)

PERCOBAAN 1
Kontrol LED dengan Mikrokontroler AT89S51


LED (Light Emiting Diode) merupakan dioda yang memancarkan cahaya, saat ini led merupakan alternatif sumber cahaya dan diproduksi dalam berbagai bentuk dan ukuran, led hampir menyingkirkan komponen lain yang menghasilkan sumber cahaya, karena led memiliki daya yang rendah dibandingkan sumber cahaya lain.
Dalam penggunaannya dalam aplikasi mikrokontroler penting halnya untuk memperhatikan batasan arus yang mengalir dalam komponen ini, supaya dapat menghasilkan cahaya yang maksimal dan tidak rusak. Berikut merupakan rumusan dalam menentukan besarnya resistor yang digunakan dalam merangkai led :
 
Dengan parameter tipe led seperti ditunjukan dalam tabel berikut ini :
Karena mikrokontroler jenis AT89S51 ini hanya dapat menghasilkan arus yang rendah pada semua portnya maka pemasangan led hanya bisa dilakukan metode common anoda (mikrokontroler di fungsikan sebagai ground), pernyataan ini akan tampak jelas melalui gambar berikut ini:
 
Dalam seringkali percobaan yang saya lakukan led tidak akan menyala ketika menggunakan metode lain (common katoda) karena arus listrik yang dihasilkan port mikrokontroler sangatlah lemah.

Gambar Percobaan :
 Gambar kontrol led

Langkah Percobaan :
Program 1 : 
Ketikan program berikut ini pada program Top View Simulator dan lakukan simulasi (cara melakukan simulasi klik disini)
$mod51
org    0h               ;Tempatkan memori program pada 0h
start:
mov    P0,#00011100b    ;P0= 00011100b
sjmp start
end

Jika program berjalan dengan baik maka led yang menyala adalah (D1,D2,D6,D7,D8)

Program 2:
Menyalakan led dengan waktu tunda
org    0h
$mod51
start:
mov    p0,#00001111b  ;LED D5-D8 On D1-D4 off
call    delay         ;Panggil Delay (jeda waktu)
mov    p0,#11110000b  ;LED D1-D4 On D5-D8 off
call    delay
sjmp    start         ;kembali ke start
;-------------------------------
;---Sub rutin waktu tunda-------
;-------------------------------
delay: mov R1,#255
ret1: mov R2,#255
ret2: djnz R2,ret2
      djnz R1,ret1
      ret
end
Jika tidak ada masalah maka led akan menyala bergantian (Flip Flop)

Program 3:
Berikut merupakan cara lain dengan metode bit addresing ketika menyalakan led
org    0h
$mod51
setb    p0.0  ; led D1 off
clr     p0.1  ; led D2 on
setb    p0.2  ; led D3 off
clr     p0.3  ; led D4 on
setb    p0.4
clr     p0.5
setb    p0.6
clr     p0.7
end
Program diatas akan menyalakan led dengan perintah "clr".

Percobaan 3 (Seven Segmen)



PERCOBAAN 3
Seven Segmen dengan Mikrokontroler AT89S51

Pada dasarnya seven segmen ialah 8 buah led yang dikemas dalam membentuk digit digital yang dikemas dalam satu kemasan kotak plastik, sehingga dalam pemrograman mikrokontroler perlakuan seven segmen akan sama dengan melakukan pemrograman led.





Dalam aplikasinya sebuah mikrokontroler AT89S51 jika digunakan semua port untuk mengontrol seven segmen secara paralel makan jumlah digit maksimum hanyalah 4digit. disisi lain aplikasi menggunakan lebih dari 4digit, maka diperlukanlah cara lain untuk mengatasi hal ini.

 
Berikut ini merupakan tabel data penggunaan seven segmen :
Untuk menghemat penggunaan port maka diperlukan teknik MULTIPLEXING dalam mengontrol display seven segmen, sehingga digit yang dikontrol bisa lebih dari 4digit tetapi menggunakan port pada mikrokontroler yang minimal. teknik multiplexing ini di tunjukan pada gambar uji coba di bawah ini :

Langkah Percobaan :
Program 1 :
Menampilkan angka 0 pada digit 1 dan angka 0 pada digit 2

 
org    0h
$mod51

start:
mov    p2,#00000001b    ;aktifkan digit 1
mov    p1,#10000001b    ;tampilkan angka 0 pada digit 1 (lihat tabel)
call    delay           ;render
mov    p2,#00000010b    ;aktifkan digit 2
mov    p1,#10011111b    ;tampilkan angka 1 pada digit 2
call    delay           ;render
sjmp    start

;-------------------------------
;---Sub rutin waktu tunda-------
;-------------------------------
delay: mov R1,#255
ret1: mov R2,#255
ret2: djnz R2,ret2
      djnz R1,ret1
      ret
end

Program 2:
Counter 0 - 99