Ejemplo de control de un lcd de 4bit en IAR AVR .Crear lcd.c
/* Codigo para manejar LCD 4bits de 2 lineas 20*2 ó 16*2 soporta para iar o comp
atible con visionavr y Winavr para ATmega8 */
// Modificar esta dirección por la donde se copie el archivo
#include "C:\Documents and Settings\Rapido\Mis documentos\nuevo avr\delay_iar.h"
#ifdef LCD_PORTB // E=P0 RS=P1 RW=GND pines 4 al 7 bus de datos
#define PORT_LCD PORTB
#define DDR_LCD DDRB
#define FO 0xf0
#define OF 0x0f
#define D 4
#define R 0
#endif
#ifdef LCD_PORTD
#define PORT_LCD PORTD
#define DDR_LCD DDRD
#define FO 0xf0
#define OF 0x0f
#define D 4
#define R 0
#endif
#ifdef LCD_PORTC // E pin0 RS pin1 RW a tierra ,pin2 a pin5 bus de datos
#define PORT_LCD PORTC
#define DDR_LCD DDRC
#define FO 0x3c
#define OF 0x03
#define D 2
#define R 2
#endif
/* Modo de cursor y movimiento */
#define INCREMENTA_CURSOR 1
#define DECREMENTA_CURSOR 0
#define DESPLASAMINTO 1
#define NORMAL 0
// LCD modo 4bits P.0=e P.1=rs
void _nop(char a){
while(a){
asm("nop\n");
asm("nop\n");
asm("nop\n");
asm("nop\n");
a-=1;
}
}
void datos(char t){
char b;
DDR_LCD=0xff;
PORT_LCD|=1; // E bit 0 E=1
PORT_LCD|=2; // RS=1
PORT_LCD = PORT_LCD&OF;// data E=P.0 RS=P.1
b=(t>>R)&FO;
PORT_LCD |=b;
_nop(40);
PORT_LCD &= 254; // desabilita E
_nop(10);
PORT_LCD = PORT_LCD&OF;
PORT_LCD |= 1; // habilita E
PORT_LCD |= t<<D; // 3 a data E=P.0 RS=P.1
_nop(40);
PORT_LCD &= 254;
};
void control(char a){
char b;
DDR_LCD=0xff;
PORT_LCD &=253; // RS=0
PORT_LCD = PORT_LCD&OF;// 3 a data E=P.0 RS=P.1
_nop(2);
PORT_LCD |= 1; // habilita E
b=(a>>R)&FO;
PORT_LCD |= b; // 3 a data E=P.0 RS=P.1
_nop(255);
PORT_LCD &= 254; // desabilita E
_nop(255);
PORT_LCD = PORT_LCD&OF;
PORT_LCD |= 1; // habilita E
PORT_LCD |= a<<D;
_nop(255);
PORT_LCD &= 254;
}
void lcd_init(){
char b[]={2,44,12,6,128},i,a;
DDR_LCD=0xff; //PORT salida
PORT_LCD&=0x00; // RS=0
delay_ms(1);
control(3);
delay_ms(5);
for(i=0;i<=4;i++){
a=b
;
control(a);
delay_ms(5);
}
}
void lcd_putsf(const char *a){
char b;
b=*a;
while(b){
datos(b);
delay_ms(2);
a+=1;
b=*a;
}
}
void lcd_put(char *a){
char b;
b=*a;
while(b){
datos(b);
delay_ms(2);
a+=1;
b=*a;
}
}
void lcd_clear(){
control(1);
delay_ms(15);
}
void lcd_gotoxy(char x,char y){
if((x<=20)&&(y==0)){
x=128+x;
control(x);
delay_ms(1);
}
if((x<=20)&&(y==1)){
x=192+x;
control(x);
delay_ms(1);
}
}
void lcd_putchar(char a){
datos(a);
delay_ms(5);
}
void lcd_cursor_i_d_desplazar(char c,char d){
/* c=1 incrementa cursor c=0 decrementa cursor ,d=1 desplaza cursor cada vez que escribe dato en negro d=0
modo normal */
if((c<2)&&( d<2)){
c=c<<1;
d=(c|d)|4;
control(d);
delay_ms(1);
}
}
void lcd_cursor_display(char c,char d){ /* c=1 desplaza visualización c=0 cursor, d=1 deplaza derecha d=0 desplaza
izquierda */
if((c<2)&&(d<2)){
c=c<
;
d=d<<2;
d=(d|c)|16;
control(d);
delay_ms(1);
}
}
Para el retardo hacerlo por separado delay.c o delay.h para iar
#include <iom8.h>
#ifndef CLOCK
#define CLOCK 4
#endif
#ifdef CLOCK
// 1ms a 1MHZ
void delay_1mMHZ(){
asm(
"push R17\n"
"push R18\n"
"ldi R17, $03\n"
"WGLOOP0: ldi R18, $6C\n"
"WGLOOP1: dec R18\n"
"brne WGLOOP1\n"
"dec R17\n"
"brne WGLOOP0\n"
"pop R17\n"
"pop R18\n");
}
// ajuste segun lo definido por el #deine CLOCK N,(N=# entero aproximado)
void delay_1ms(){
char a,t;
t=(char)CLOCK;
for(a=0;a<t;a++)
delay_1mMHZ();
}
// Delay en ms segun el clock en valores enteros preciciòn 99%
void delay_ms(unsigned int t){
while(t){
delay_1ms();
t-=1;
}
}
#endif
Ejemplo de programa principal
#include <iom8.h>
#define CLOCK 8
#define LCD_PORTC
#include "C:\Documents and Settings\Rapido\Mis documentos\nuevo avr\iar_lcd.c"
int main(void){
char a;
lcd_init();
lcd_putsf("hola");
lcd_gotoxy(0,1);
lcd_putsf("Modo 6 hilos ");
}
//el pin RW a tierra.