|
先贴一下程序吧
#include
#include
#include //其中有nop函数的定义
#define uchar unsigned char
#define uint unsigned int
/* sbit lcdRS=P1^3; //定义数据命令选择端
sbit lcdRW=P1^4; //定义读写选择端
sbit lcdEN=P1^5; //定义使能端 */
sbit xuan=P3^1; //申明U3锁存器的锁存端 //该锁存器输入D接P1,输出Q
sbit ST=P3^6;
sbit EOC=P3^3;
sbit OE=P3^7;
sbit CLOCK=P3^2;
uint a,b,c,d,VOL;
unsigned char code dis1[]={"Vol:"}; //第一行要显示的字符
uchar dis2[]= { "Angel:"}; //第二行
//*******************************************
// 延时x ms
//*******************************************
void delayms(uint xms)
{
uint i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
//*******************************************
// 判断lcd1602是否处于忙的状态,即读忙
//*******************************************
uchar lcd1602_ReadBusy()
{
uchar temp;
xuan=1; //打开U3锁存端
P1=0x10; //P1=000 10 000 //lcdRS=0; lcdRW=1; //RS=0选择指令寄存器;RW=1读
xuan=0; //关闭U3锁存端
_nop_();
P0=0xff; //读某IO口数据前,先将该口置为1
_nop_();
xuan=1;
P1=0x30; //P1=00 1 10000 //lcdEN=1; //E端使能端,E从高电平到低电平时(1--0),lcd执行命令
xuan=0;
_nop_();
temp=P0; //读取此时lcd1602的状态字
_nop_();
xuan=1;
P1=0x10; //P1=00 0 10000 //lcdEN=0;
xuan=0;
return (temp&0x80); //如果忙
/*状态字为temp(8位2进制数)的最高位,最高位为1表示禁止读写,为0表示允许读写,
即temp&0x80得1表示忙,得0表示不忙*/
}
//*******************************************
// 写命令
//*******************************************
void lcd1602_WriteCom(uchar com)
{
while(lcd1602_ReadBusy()); //判忙
xuan=1;
P1=0x00; //P1=000 00 000 //lcdRS=0;lcdRW=0; //指令;写
xuan=0;
_nop_();
P0=com; //准备发送命令
_nop_();
xuan=1;
P1=0x20; //P1=00 1 00000 //lcdEN=1;
xuan=0;
_nop_();
_nop_();
xuan=1;
P1=0x00; //P1=00 0 00000 //lcdEN=0;
xuan=0;
_nop_();
_nop_();
}
//*******************************************
// 写数据
//*******************************************
void lcd1602_WriteData(uchar dat)
{
while(lcd1602_ReadBusy()); //判忙
xuan=1;
P1=0x08; //P1=000 01 000 //lcdRS=1; lcdRW=0; //数据;写
xuan=0;
_nop_();
P0=dat;
_nop_();
xuan=1;
P1=0x28; //P1=00 1 01000 //lcdEN=1;
xuan=0;
_nop_();
_nop_();
xuan=1;
P1=0x08; //P1=00 0 01000 //lcdEN=0;
xuan=0;
_nop_();
_nop_();
}
//*******************************************
// lcd初始化函数
//*******************************************
void lcd1602_init()
{
delayms(15);
lcd1602_WriteCom(0x38); //显示模式设置
delayms(5);
lcd1602_WriteCom(0x38);
delayms(5);
lcd1602_WriteCom(0x38);
lcd1602_WriteCom(0x0c); //显示开及光标设置
lcd1602_WriteCom(0x06); //显示光标移动设置
lcd1602_WriteCom(0x01); //显示清屏
}
//*******************************************
// lcd显示
//*******************************************
void display(void)
{
uint i,j;
lcd1602_init();
lcd1602_WriteCom(0x80); //0x80是第一行的第一个字符的地址
for(i=0;i<10;i++)
lcd1602_WriteData(dis1[i]);
lcd1602_WriteCom(0x80+0x40); //0xc0是第二行的第一个字符的地址 //表示的方法有很多,可以用0xc0,0x80+0x40,0x80|0x40等等
for(j=0;j<10;j++)
lcd1602_WriteData(dis2[j]);
}
//*******************************************
// ad0808转换数据并显示
//*******************************************
void readtemp()
{
OE=0; //ad输出允许OE,高有效
ST=0;ST=1;ST=0; //ad转换启动ST,高有效 //启动转换
while(!EOC); //EOC转换结束,高有效,即相当while(EOC==0)或while(1) //等待转换结果
OE=1; //允许输出
a=P1;
OE=0; //关闭输出
delayms(10);
VOL=a*1.0/256*500; //不太懂?
b=VOL/100;
c=VOL/10%10;
d=VOL%10;
lcd1602_WriteCom(0x85); //(0x80+0x05) 05是第一行第六列
lcd1602_WriteData(b+48);
lcd1602_WriteData(0x2e); //小数点
lcd1602_WriteData(c+48);
lcd1602_WriteData(d+48);
lcd1602_WriteData('V');
}
void main()
{
lcd1602_init();
TMOD=0x01; //设定时器1工作方式0,13位定时/计数器;定时器0工作方式1,16位定时/计数器
TH0=(65536-2)/256;
TL0=(65536-2)%256;
TR0=1; //启动定时器0
ET0=1; //开定0中断
EA=1; //开总中断
CLOCK=0;
display();
while(1)
{
readtemp();
}
}
void t0(void) interrupt 1 using 0 //这个中断左右是使CLOCK产生500kHZ的脉冲
{
TH0=(65536-2)/256;
TL0=(65536-2)%256;
CLOCK=!CLOCK; //ADC0809时钟信号
}
|
|