Menggunakan ic 74hc573 yg berfungsi sebagai latch

Menggunakan ic 74hc573 yangg berfungsi sebagai latch.
Untuk program memori, kita tidak perlu menset port RD,WR, dan ALE. karena smuanya sudah otomatis menjalankan fungsinya. Kita tinggal menentukan alamat/address..

WR akan low jika kita ingin mengirim data, contoh pada program

unsigned char xdata PPI0PortCfg _at_ 0x6011;
PPI0Cfg = 0x6080;

jadi pada addres PPI0Cfg akan dikirim data 0x6080, secara otomatis WR akan low pada saatnya (saat address sudah terkirim),
bgitu pula dengan RD, akan low pada saat ingin membaca data, contoh program

unsigned char xdata PPI0PortA _at_ 0x6000;
unsigned char xdata PPI1PortA _at_ 0xA000;
PPI0PortA = PPI1PortA;

membaca data PPI1 (sbelumnya di set sbagai input), kemudian data tersebut di kirim ke PPI0 portA

PIN ALE untuk menlacth address, agar menghemat port, karena pada Bit bwh (P0_0 - P0_7), berfungsi sebagai mengirim address,
mengirim data, dan membaca data. jadi, ic 74hc537 ini berfungsi sebagai pemisah antara address dan data, dengan sinyal dari pin ALE.

baudrate 1200
untuk menjalankan program,kirim karakter via virtual terminal proteus

1. Configurasi PPI0,PPO1, dan PPI2
2. Memadamkan led 0xff
3. Menyalakan led 0x00
4. menjalankan program scand, yaitu data yang diambil dari PPI1 (sbagai input), dikirim ke PPI0 dan PPI2 untuk menyalakan led.


Bagi yang ingin mengunduh program ini dan simulasi ini di proteus silakan download di link yang ada setelah tulisan dibawah ini...

http://www.4shared.com/rar/cyIpfv6b/8051_PPI8255.html?

** program ini menggunakan Keil, jgn lupa untuk mengcopy sio.h ke folder keil nya..


#include (REGX51.h)
#include (string.h)
#include (stdio.h)
#include (stdlib.h)
#include "sio.h"
#include (intrins.h)
#include (absacc.h)

#define TBUF_SIZE 2
#define RBUF_SIZE 8
#define TBUF_SPACE idata
#define RBUF_SPACE idata
#define CTRL_SPACE data
#define XTAL 12000000L
#define display P1
#define HIGH 1
#define TRUE 1
#define FALSE 0

#if TBUF_SIZE < 2
#error TBUF_SIZE is too small. It must be larger than 1.
#elif TBUF_SIZE > 128
#error TBUF_SIZE is too large. It must be smaller than 129.
#elif ((TBUF_SIZE & (TBUF_SIZE-1)) != 0)
#error TBUF_SIZE must be a power of 2.
#endif

#if RBUF_SIZE < 2
#error RBUF_SIZE is too small. It must be larger than 1.
#elif RBUF_SIZE > 128
#error RBUF_SIZE is too large. It must be smaller than 129.
#elif ((RBUF_SIZE & (RBUF_SIZE-1)) != 0)
#error RBUF_SIZE must be a power of 2.
#endif

static TBUF_SPACE unsigned char tbuf [TBUF_SIZE];
static RBUF_SPACE unsigned char rbuf [RBUF_SIZE];
static CTRL_SPACE unsigned char t_in = 0;
static CTRL_SPACE unsigned char t_out = 0;
static CTRL_SPACE unsigned char r_in = 0;
static CTRL_SPACE unsigned char r_out = 0;
static bit ti_restart = 0;


//================GLOBAL VARIABEL===================
int overflow_count = 0, time = 0, time1 = 0;
char x1,x10,y10,c,mode,datA,datB,datC;
char dA=0xff,dB=0xff,dC=0xff;

// program memory menggunakan PORT 0 (bit bawah) dan PORT 2 (bit atas),jadi total 16 bit (maksimal 64KB), klo ga salah

unsigned char xdata PPI0Cfg _at_ 0x6003; // alamat untuk configurasi PPI0 0b 011 00000000000 11
unsigned char xdata PPI0PortA _at_ 0x6000; // alamat untuk mengirim nilai ke PORTA PPI0 0b 011 00000000000 00
unsigned char xdata PPI0PortB _at_ 0x6001; // alamat untuk mengirim nilai ke PORTB PPI0 0b 011 00000000000 01
unsigned char xdata PPI0PortC _at_ 0x6002; // alamat untuk mengirim nilai ke PORTC PPI0 0b 011 00000000000 10
unsigned char PPI0PortAmem; // untuk lebih jelasnya, baca data sheet PPI8255
unsigned char PPI0PortBmem;
unsigned char PPI0PortCmem;

unsigned char xdata PPI1Cfg _at_ 0xA003; // sama sperti diatas, PPI1 PPI0 0b1010000000000011
unsigned char xdata PPI1PortA _at_ 0xA000; // alamat untuk mengirim nilai ke PORTA PPI1 0b 101 00000000000 00
unsigned char xdata PPI1PortB _at_ 0xA001; // alamat untuk mengirim nilai ke PORTB PPI1 0b 101 00000000000 01
unsigned char xdata PPI1PortC _at_ 0xA002; // alamat untuk mengirim nilai ke PORTC PPI1 0b 101 00000000000 10
unsigned char PPI1PortAmem;
unsigned char PPI1PortBmem;
unsigned char PPI1PortCmem;

unsigned char xdata PPI2Cfg _at_ 0xC003; // sama sperti diatas, PPI1 PPI0 0b 110 00000000000 11
unsigned char xdata PPI2PortA _at_ 0xC000; // alamat untuk mengirim nilai ke PORTA PPI1 0b 110 00000000000 00
unsigned char xdata PPI2PortB _at_ 0xC001; // alamat untuk mengirim nilai ke PORTB PPI1 0b 110 00000000000 01
unsigned char xdata PPI2PortC _at_ 0xC002; // alamat untuk mengirim nilai ke PORTC PPI1 0b 110 00000000000 10
unsigned char PPI2PortAmem;
unsigned char PPI2PortBmem;
unsigned char PPI2PortCmem;

//================SET SERIAL INTERRUPT==============
void Init_timer()
{ TMOD = (TMOD & 0xF0) | 0x01;
ET0 = 1;
TR0 = 1;
}

static void com_isr (void) interrupt 4
{ if(RI != 0)
{RI = 0;
if (((r_in - r_out) & ~(RBUF_SIZE-1)) == 0)
{rbuf [r_in & (RBUF_SIZE-1)] = SBUF;
r_in++;
}
}
if (TI != 0)
{TI = 0;
if (t_in != t_out)
{SBUF = tbuf [t_out & (TBUF_SIZE-1)];
t_out++;
ti_restart = 0;
}
else
{ti_restart = 1;}
}
c=SBUF; // variabel c sebagai buffer serial interrupt
}

#pragma disable
void com_initialize (void)
{ t_in = 0;
t_out = 0;
r_in = 0;
r_out = 0;
SM0 = 0; SM1 = 1;
SM2 = 0;
REN = 1; /* enable serial receiver */
RI = 0; /* clear receiver interrupt */
TI = 0; /* clear transmit interrupt */
ti_restart = 1;
ES = 1; /* enable serial interrupts */
PS = 0; /* set serial interrupts to low priority */
}

#pragma disable
void com_baudrate (unsigned baudrate)
{ TI = 0;
t_in = 0;
t_out = 0;
TR1 = 0; /* stop timer 1 */
ET1 = 0; /* disable timer 1 interrupt */
PCON |= 0x80; /* 0x80=SMOD: set serial baudrate doubler */
TMOD &= ~0xF0; /* clear timer 1 mode bits */
TMOD |= 0x20; /* put timer 1 into MODE 2 */
TH1 = (unsigned char) (256 - (XTAL / (16L * 12L * baudrate)));
TR1 = 1; /* start timer 1 */
}

#pragma disable
char com_putchar (unsigned char c)
{ if (com_tbuflen () >= TBUF_SIZE)
return (-1);
tbuf [t_in & (TBUF_SIZE - 1)] = c;
t_in++;
if (ti_restart)
{ti_restart = 0;
TI = 1; /* generate transmit interrupt */
}
return (0);
}

#pragma disable
int com_getchar (void)
{ if (com_rbuflen () == 0)
return (-1);
return (rbuf [(r_out++) & (RBUF_SIZE - 1)]);
}

#pragma disable
unsigned char com_rbuflen (void)
{ return (r_in - r_out); }

#pragma disable
unsigned char com_tbuflen (void)
{ return (t_in - t_out); }

char _getkey (void)
{ int k;
do
{k = com_getchar ();}
while (k == -1);
return ((unsigned char) k);
}

char putchar (char c)
{ volatile unsigned int i;
while (com_putchar (c) != 0)
{for (i=0; i<1000; i++){}}
return (c);
}

//================SET TIMER 0=======================
char convert(char value) // konverter untuk memisah bit atas dan bit bawah, sebagai display 7segment
{ int a,b,c;
a=value/10; // puluhan
b=value-(a*10); // satuan
c=a<<4;
value=c|b; // seven segment 1s
return value;
}

void timer0_ISR (void) interrupt 1
{TL0 = 0xF0; // timer 10ms
TH0 = 0xD8;
overflow_count++;
if(overflow_count==10)
{time++;
overflow_count=0;
}
if(time==10){time=0;x1--;} // menghitung mundur dari 25 - 0 (iseng-iseng)
if(x1==0){x1=25;}
display=convert(x1);
}

//==================================================
//==================================================

void scand()
{ PPI2PortA = PPI0PortA = PPI1PortA; // membaca data PPI1, kemudian data tersebut di kirim ke PPI0 dan PPI2
PPI2PortB = PPI0PortB = PPI1PortB; // PPI0 led, PPI1 push button, PPI2 kosong (blum dksh led)
PPI2PortC = PPI0PortC = PPI1PortC;
}

void telekomen() // fungsi untuk serial interrupt
{ while(1)
{ printf ("stand by \r\n");
c = getchar ();
switch(c)
{ case '1' : mode=1;break;
case '2' : mode=1;break;
case '3' : mode=1;break;
case '4' : mode=1;break;
default : mode=3;break;
}
while(mode==1)
{ switch(c)
{ case '1' : PPI0Cfg = 0x6080; // configurasi PPI0 0b 011 00000 10000000 smua port PPI0 jadi output
PPI1Cfg = 0xA09B; // configurasi PPI1 0b 101 00000 10011011 smua port PPI1 jadi output
PPI2Cfg = 0xC080; // configurasi PPI2 0b 110 00000 10000000 smua port PPI2 jadi output
break;

case '2' : PPI0PortA = 0xff; PPI0PortB = 0xff; PPI0PortC = 0xff; PPI2PortA = 0xff; PPI2PortB = 0xff; PPI2PortC = 0xff;
break; // mematikan led

case '3' : PPI0PortA = 0x00; PPI0PortB = 0x00; PPI0PortC = 0x00; PPI2PortA = 0x00; PPI2PortB = 0x00; PPI2PortC = 0x00;
break; // menyalakan led

case '4' : scand(); // mengaktifkan fungsi scand
break; // input = output, push button = led
}
}
}
}

void main (void)
{ com_baudrate (1200); // setting baudrate
com_initialize (); // setting serial interrupt
Init_timer(); // setting timer
EA = 1; // interrupt aktif
while (1)
{
telekomen();
}
}

Latihan Codevision Avr (Running Text)



Latihan berikut ini untuk membuat tampilan LCD berjalan di baris ke 2 nya (running text). LCD 16x2 diletakan di PortB sedangkan mikrokontroler memakai ATmega8535. Untuk merubah kecepatan dalam menjalankan text-nya dirubah dengan nilai di delay-nya. Delay dalam satuan ms.
Compiler yang dipakai adalah Codevision AVR dan simulasi Proteus.
Jika ada yang ingin men-download program dan simulasi di proteus silahkan ke link berikut ini:
http://www.4shared.com/rar/n9yqh5_b/Text_Running.html


Berikut Listing Program Running Text di Codevision AVR;

/*****************************************************
Chip type : ATmega8535
Program type : Application
AVR Core Clock frequency: 12.000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 128
*****************************************************/

#include (mega8535.h>
#include (lcd.h>
#include (delay.h>
#include (string.h>
#include (stdio.h>


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

// Standard Input/Output functions

// Global variables
char buffer_lcd[]="Selamat datang di Blogger Mohammad Ardi.Berbagi dalam ilmu pengetahuan.Semoga latihan ini bisa memperdalam ilmu pemprograman di codevision avr.";

// Function prototype
void sett_REGs(void);
void tampilan(void);

// Main routine (super loop)
void main(void){
sett_REGs();
lcd_init(16);
_lcd_ready();
lcd_clear();
for(;;){// Endless loop, podo karo "while(1)"
tampilan();
}
}

// Setting register
void sett_REGs(void){
//Define I/O
DDRA = 0x00;
PORTA = 0x00;
DDRB = 0xFF;
PORTB = 0x00;
DDRC = 0x00;
PORTC = 0x00;
DDRD = 0xFF;
PORTD = 0x00;
}

// Display routine :D
void tampilan(void){
unsigned int i,j,k;
char lcd_number = 16;
unsigned int data_len = strlen(buffer_lcd);
_lcd_ready();
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Codevision AVR");
for (i=lcd_number; i>=1; --i){
lcd_gotoxy(i,1);
for (j=0; j<(lcd_number-i); j++){
lcd_putchar(buffer_lcd[j]);
}
delay_ms(100);
};
k=0;
for (i=0; i<=data_len; i++){
k++;
lcd_gotoxy(0,1);
for (j=0; j<16; j++){
if (buffer_lcd[j+k] == NULL){
return;
}
lcd_putchar(buffer_lcd[j+k]);
}
delay_ms(100);
};
}

Latihan Codevision AVR (Tampilan Merubah Tulisan Dengan Push Button Ketika Di Tekan Push Button)




Latihan berikut ini untuk membuat tampilan LCD berubah tulisannya ketika push button di tekan. Setelah ditekan maka tulisan menjadi kembali tulisan awalnya. LCD
diletakan di PortB sedangkan push button ada di PortD.2.
Compiler yang dipakai adalah Codevision AVR dan simulasi Proteus.
Jika ada yang ingin men-download program dan simulasinya, silahkan ke link berikut ini:
http://www.4shared.com/rar/MR1DHptO/Button_merubah_tulisan.html


Berikut Listing Program di Codevision AVR
/*****************************************************
Chip type : ATmega8535
Program type : Application
AVR Core Clock frequency: 12.000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 128
*****************************************************/

#include (mega8535.h)
#include (lcd.h)
#asm
.equ __lcd_port=0x18 ;PORTB
#endasm
void main(void)
{
PORTB=0x00;
DDRB=0x00;
PORTD=0x04; //untuk memfungsikan portD.2
DDRD=0x00;
ACSR=0x80;
SFIOR=0x00;
lcd_init(16);

while (1)
{
if (PIND.2==0)
{
lcd_gotoxy(1,0);
lcd_putsf("Belajar Mikro ");
lcd_gotoxy(1,1);
lcd_putsf("Codevision AVR ");
}
else
{
lcd_gotoxy(1,0);
lcd_putsf(" WELCOME ");
lcd_gotoxy(1,1);
lcd_putsf("Mikrokontroler ");
}
}
}