icc avr LCD1602显示屏程序
扫描二维码
随时随地手机看文章
入口参数说明:
//controlport
//#defineSET_RSsbi(PORTB,5)
//#defineCLR_RScbi(PORTB,5)
//#defineOUT_RSsbi(DDRB,5)
//#defineSET_RWsbi(PORTB,6)
//#defineCLR_RWcbi(PORTB,6)
//#defineOUT_RWsbi(DDRB,6)
//#defineSET_Esbi(PORTB,7)
//#defineCLR_Ecbi(PORTB,7)
//#defineOUT_Esbi(DDRB,7)
//dataport
//#defineSET_D4sbi(PORTD,4)
//#defineCLR_D4cbi(PORTD,4)
//#defineOUT_D4sbi(DDRD,4)
//#defineSET_D5sbi(PORTD,5)
//#defineCLR_D5cbi(PORTD,5)
//#defineOUT_D5sbi(DDRD,5)
//#defineSET_D6sbi(PORTD,6)
//#defineCLR_D6cbi(PORTD,6)
//#defineOUT_D6sbi(DDRD,6)
//#defineSET_D7sbi(PORTD,7)
//#defineCLR_D7cbi(PORTD,7)
//#defineOUT_D7sbi(DDRD,7)
//busyport
//#defineGET_BFgbi(PIND,7)
//#defineOUT_BFsbi(DDRD,7)
//#defineIN_BFcbi(DDRD,7)
----------------------------------------------------------------------
接口定义:
LCD1602ATmega16
1.GND--------GND
2.VCC--------VCC
3.V0--------V0
4.RS--------由外部程序定义
5.R/W--------由外部程序定义
6.E--------由外部程序定义
7.D0--------NC
8.D1--------NC
9.D2--------NC
10.D3--------NC
11.D4--------由外部程序定义
12.D5--------由外部程序定义
13.D6--------由外部程序定义
14.D7--------由外部程序定义
15.LED+--------VCC
16.LED---------GND
说明:
(1)使用ATmega16的7根IO口操作LCD1602
(2)该程序的优点是:7根IO可任意定义,不需分布在固定的一组PORT口上
(3)该程序的缺点是:IO定义的写法较为繁琐
----------------------------------------------------------------------
待定参数说明:
//#defineDELAY(){_nop_();_nop_();_nop_();}
----------------------------------------------------------------------
对外变量说明:
----------------------------------------------------------------------
对外函数说明:
----------------------------------------------------------------------
10101010101010101010101010101010101010101010101010101010101010101010*/
#ifndefLCD1602_H
#defineLCD1602_H
#include"D:ICC_HCmmICC.H"
/*待定参数*/
#defineDELAY(){NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();}
/*不考虑移植性的写法*/
//uint8bdatabdat;
//sbitbdat0=bdat^0;
//sbitbdat1=bdat^1;
//sbitbdat2=bdat^2;
//sbitbdat3=bdat^3;
//sbitbdat4=bdat^4;
//sbitbdat5=bdat^5;
//sbitbdat6=bdat^6;
//sbitbdat7=bdat^7;
/*考虑移植性的写法*/
uint8bdat;
#definebdat0(bdat&0x01)
#definebdat1(bdat&0x02)
#definebdat2(bdat&0x04)
#definebdat3(bdat&0x08)
#definebdat4(bdat&0x10)
#definebdat5(bdat&0x20)
#definebdat6(bdat&0x40)
#definebdat7(bdat&0x80)
#defineCGRAM00x00
#defineCGRAM10x01
#defineCGRAM20x02
#defineCGRAM30x03
#defineCGRAM40x04
#defineCGRAM50x05
#defineCGRAM60x06
#defineCGRAM70x07
#defineTRUE1
#defineFALSE0
boolLCD1602Err=FALSE;
/*--------------------------------------------------------------------
函数名称:LCD1602读读读读读忙~
函数功能:都说是读读读读读忙咯~
注意事项:对于高速CPU,应加延时,好像是废话~
提示说明:无
输入:
返回:无
--------------------------------------------------------------------*/
voidbusy(void)
{
uint16busyCounter=0;
boolbusySta;//用于探测lcdbusystatus
IN_BF;
SET_D4;
SET_D5;
SET_D6;
SET_D7;
DELAY();
CLR_RS;
DELAY();
SET_RW;
DELAY();
do
{
SET_E;
DELAY();
/*这里读取AC4-AC6位及BF的值,程序不需记录AC4-AC6的值,所以不存储*/
busySta=(bool)GET_BF;
CLR_E;
DELAY();
/*读取"BUSY"时,"D4-D7"状态可能已经改变,必须再次设为输出"1"*/
SET_D4;
SET_D5;
SET_D6;
SET_D7;
DELAY();
SET_E;
DELAY();
/*这里读取AC0-AC3位的值,程序不需记录AC0-AC3的值,所以不存储*/
CLR_E;
DELAY();
if(busyCounter==1000)
{
LCD1602Err=TRUE;//标识LCD1602错误,方便上缴系统报错
return;//避免由于LCD1602错误而导致程序阻塞
}
busyCounter++;
}
while(busySta);
LCD1602Err=FALSE;
CLR_E;
OUT_BF;
}
/*--------------------------------------------------------------------
函数名称:LCD1602写操作
函数功能:
注意事项:对于高速CPU,应加延时,好像是废话~
提示说明:无
输入:
返回:无
--------------------------------------------------------------------*/
voidwrite(boolflag,uint8dat)//flag=0:command,flag=1:data
{
bdat=dat;
busy();
if(flag)
SET_RS;
else
CLR_RS;
DELAY();
CLR_RW;
DELAY();
if(bdat4)
SET_D4;
else
CLR_D4;
if(bdat5)
SET_D5;
else
CLR_D5;
if(bdat6)
SET_D6;
else
CLR_D6;
if(bdat7)
SET_D7;
else
CLR_D7;
DELAY();
SET_E;
DELAY();
CLR_E;
DELAY();
if(bdat0)
SET_D4;
else
CLR_D4;
if(bdat1)
SET_D5;
else
CLR_D5;
if(bdat2)
SET_D6;
else
CLR_D6;
if(bdat3)
SET_D7;
else
CLR_D7;
DELAY();
SET_E;
DELAY();
CLR_E;
DELAY();
}
/*--------------------------------------------------------------------
函数名称:LCD1602读操作
函数功能:
注意事项:对于高速CPU,应加延时,好像是废话~
提示说明:无
输入:
返回:无
--------------------------------------------------------------------*/
//voidread(uint8adr)
//{
//}
/*--------------------------------------------------------------------
函数名称:LCD1602设置CGRAM内容
函数功能:
注意事项:对于高速CPU,应加延时,好像是废话~
提示说明:调用LCD1602_setCG(0,userCh),则写入用户定义的字符"userCh"
输入:"adr"数据范围:0-8,"buf"为用户需要写入的字符"userCh"
返回:无
--------------------------------------------------------------------*/
voidLCD1602_setCGRAM(uint8adr,constuint8buf[8])
{
uint8i;
write(0,0x40+adr*8);
for(i=0;i<8;i++)
write(1,buf[i]);
/*不得采样下面写法,因为传入的是数组,最后一个不是’ ’*/
//while(*buf)
//write(1,*buf++);
}
/*--------------------------------------------------------------------
函数名称:LCD1602命令设置
函数功能:
注意事项:对于高速CPU,应加延时,好像是废话~
提示说明:
输入:"CLR_SCR"/"GO_HOME"/"AC_INC"/"AC_DEC"...
返回:无
--------------------------------------------------------------------*/
//----function------1--------0----LcdWordPos--
//dispEn|Enable|DISAble|bit2
//cursorEn|Enable|Disable|bit1
//blinkEn|Enable|Disable|bit0
//------------------------------------------------------
//isACinc|INC_AC|DEC_AC|bit1
//shiftEn|Enable|Disable|bit0
//------------------------------------------------------
voidLCD1602_setCmd(uint8*str)
{
staticbooldispEn=0;
staticboolcursorEn=0;
staticboolblinkEn=0;
staticboolshiftEn=0;
staticboolisACinc=0;
if(!strcmp(str,"CLR_SCR"))//clearscreen
write(0,0x01);
elseif(!strcmp(str,"GO_HOME"))//setACgohome
write(0,0x02);
/*--------------------------------------------------
isACinc&shiftEn共用一个命令设置
--------------------------------------------------*/
elseif(!strcmp(str,"INC_AC"))//setACasincmode
{
isACinc=1;
if(shiftEn)
write(0,0x07);
else
write(0,0x06);
}
elseif(!strcmp(str,"DEC_AC"))//setACasdecmode
{
isACinc=0;
if(shiftEn)
write(0,0x05);
else
write(0,0x04);
}
elseif(!strcmp(str,"EN_SHIFT"))//enableshift
{
shiftEn=1;
if(isACinc)
write(0,0x07);
else
write(0,0x06);
}
elseif(!strcmp(str,"DIS_SHIFT"))//disableshift
{
shiftEn=0;
if(isACinc)
write(0,0x05);
else
write(0,0x04);
}
/*--------------------------------------------------
dispEn&cursorEn&blinkEn共用一个命令设置
--------------------------------------------------*/
elseif(!strcmp(str,"OPEN_LCD"))//opernlcd
{
dispEn=1;
if(cursorEn)
if(blinkEn)
write(0,0x0F);
else
write(0,0x0E);
else
if(blinkEn)
write(0,0x0D);
else
write(0,0x0C);
}
elseif(!strcmp(str,"CLOSE_LCD"))//closelcd
{
dispEn=0;
if(cursorEn)
if(blinkEn)
write(0,0x0B);
else
write(0,0x0A);
else
if(blinkEn)
write(0,0x09);
else
write(0,0x08);
}
elseif(!strcmp(str,"OPEN_CURS"))//opencursor
{
cursorEn=1;
if(dispEn)
if(blinkEn)
write(0,0x0F);
else
write(0,0x0E);
else
if(blinkEn)
write(0,0x0B);
else
write(0,0x0A);
}
elseif(!strcmp(str,"CLOSE_CURS"))//closecursor
{
cursorEn=0;
if(dispEn)
if(blinkEn)
write(0,0x0D);
else
write(0,0x0C);
else
if(blinkEn)
write(0,0x09);
else
write(0,0x08);
}
elseif(!strcmp(str,"EN_BLINK"))//enableblinkcursor
{
blinkEn=1;
if(dispEn)
if(cursorEn)
write(0,0x0F);
else
write(0,0x0D);
else
if(cursorEn)
write(0,0x0B);
else
write(0,0x09);
}
elseif(!strcmp(str,"DIS_BLINK"))//disableblinkcursor
{
blinkEn=0;
if(dispEn)
if(cursorEn)
write(0,0x0E);
else
write(0,0x0C);
else
if(cursorEn)
write(0,0x0A);
else
write(0,0x08);
}
/*--------------------------------------------------
dispEn&cursorEn&blinkEn共用一个命令设置
--------------------------------------------------*/
elseif(!strcmp(str,"RIGHT_SCR"))//rightshiftscreen
write(0,0x1c);
elseif(!strcmp(str,"LEFT_SCR"))//leftshiftscreen
write(0,0x18);
elseif(!strcmp(str,"RIGHT_CURS"))//rightshiftcursor
write(0,0x14);
elseif(!strcmp(str,"LEFT_CURS"))//leftshiftcursor
write(0,0x10);
}
/*--------------------------------------------------------------------
函数名称:LCD1602初始化
函数功能:
注意事项:
提示说明:无
输入:
返回:无
--------------------------------------------------------------------*/
voidLCD1602_init(void)
{
OUT_RS;
OUT_RW;
OUT_E;
OUT_D4;
OUT_D5;
OUT_D6;
OUT_D7;
delay50ms(1);
CLR_D7;
CLR_D6;
SET_D5;
SET_D4;
DELAY();
CLR_RS;
DELAY();
CLR_RW;
SET_E;
DELAY();
CLR_E;
delay50us(200);
SET_E;
DELAY();
CLR_E;
delay50us(200);
SET_E;
DELAY();
CLR_E;
delay50us(200);
CLR_D7;
CLR_D6;
SET_D5;
CLR_D4;
DELAY();
SET_E;
DELAY();
CLR_E;
DELAY();
LCD1602_setCmd("OPEN_LCD");
LCD1602_setCmd("CLR_SCR");
LCD1602_setCmd("INC_AC");
//LCD1602_setCmd("OPEN_CURS");
//LCD1602_setCmd("GO_HOME");
}
/*--------------------------------------------------------------------
宏名称:设置AC值
宏功能:设置AC值啦
注意事项:
提示说明:
输入:
返回:无
--------------------------------------------------------------------*/
#defineLCD1602_setAC(adr)write(0,adr)
/*--------------------------------------------------------------------
函数名称:输出一个字符
函数功能:
注意事项:对于高速CPU,应加延时,好像是废话~
提示说明:调用LCD1602_putc(0x80,’A’),则在第一行第一个字符处输出’A’
输入:
返回:无
--------------------------------------------------------------------*/
voidLCD1602_putc(uint8adr,uint8ch)
{
write(0,adr);
write(1,ch);
}
/*--------------------------------------------------------------------
函数名称:输出一个字符串
函数功能:
注意事项:无
提示说明:调用LCD1602_puts(0x80,"waveShare"),则从第一行第一个位置开始输出"waveShare"
输入:
返回:无
--------------------------------------------------------------------*/
voidLCD1602_puts(uint8startAdr,uint8*str)
{
/*
while(*str)
{
LCD1602_putc(addr++,*str++);
}
*/
//LCD1602_setCmd("AC++");
write(0,startAdr);
while(*str)
write(1,*str++);
}
/*--------------------------------------------------------------------
函数名称:输出一个数值(带0)
函数功能:有时候你可能不是需要"123",而是需要"00123"吧
注意事项:无
提示说明:调用LCD1602_putd0(0x8F,123,5),则从0x8B开始到0X8F输出"00123"
输入:
返回:无
--------------------------------------------------------------------*/
//forexample:dat=123,length=6,output000123
voidLCD1602_putd0(uint8endAdr,uint32dat,uint8length)
{
sint8i;
speaData(dat,length);
//LCD1602_setCmd("AC++");
write(0,endAdr-length+1);
for(i=length-1;i>=0;i--)
write(1,dataElem[i]+0x30);
}
/*--------------------------------------------------------------------
函数名称:输出一个数值(不带0)
函数功能:
注意事项:无
提示说明:调用LCD1602_putd(0x8F,123,5),则从0x8B开始到0X8F输出"123"
输入:
返回:无
--------------------------------------------------------------------*/
voidLCD1602_putd(uint8endAdr,uint32dat,uint8length)
{
sint8i;
sint8effectLen;
if(dat>999999)
effectLen=7;
elseif(dat>99999)
effectLen=6;
elseif(dat>9999)
effectLen=5;
elseif(dat>999)
effectLen=4;
elseif(dat>99)
effectLen=3;
elseif(dat>9)
effectLen=2;
else
effectLen=1;
speaData(dat,effectLen);
//LCD1602_setCmd("AC++");
if(length>effectLen)
{
write(0,endAdr-length+1);
for(i=length-effectLen-1;i>=0;i--)
write(1,’’);
}
for(i=effectLen-1;i>=0;i--)
{
if(i==0||dataElem[i])
{
write(0,endAdr-i);
for(;i>=0;i--)
write(1,dataElem[i]+0x30);
}
}
}
/*--------------------------------------------------------------------
函数名称:输出一个混合串
函数功能:
注意事项:最好不要加载这个函数,因为它将占用将近1K空间
提示说明:调用LCD1602_sprintf(0x8F,12AB,4),则从0x8B开始到0X8F输出"12ABok"
输入:
返回:无
--------------------------------------------------------------------*/
//voidLCD1602_sprintf(uint8startAdr,uint32dat,uint8length)
//{
///*clearthedisplayareafirsthere!*/
////LCD1602_puts(addr,"");
//sprintf(t,"%luok",dat);
////LCD1602_setCmd("AC++");
//LCD1602_puts(addr,t);
//}
#endif