|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区
您需要 登录 才可以下载或查看,没有账号?立即注册
×
现在玩51的人少了,把两年前的笔记发上来赚点积分,
曾用这个程序,c语言写了个1602秒表,不用中断定时,只用软件延时,达到17分钟5秒的误差
这5秒的误差应理解成晶振的误差和温度引起的原因
/*****************************************/
/*项目名:lcd1602显示程序
/*程序名:
/*公司名称:
/*创始人: 日期:2011-12-28
/*修改人: 日期:
/*功能描述:写入1个字符和写入字符串
/*其他说明:
/*版本:1.0
/*****************************************/
#include<AT89X51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit RS=P2^5;//寄存器选择位,1602的第4脚。
sbit RW=P2^6;//读写选择位,1602的第5脚。
sbit E=P2^7;//使能信号位,1602的第6脚。
sbit BF=P0^7; //忙碌标志位,,将BF位定义为P0.7引脚
uchar code lcdstring[]={"LCD1602"};
/*****************************************/
/*函数名:delayms()
/*功能描述:延时
/*函数说明:最高65535ms,最低1ms
/*调用函数:无
/*全局变量:无
/*输入:unsigned int t
/*返回:无
/*设计者:张周伟 日期:2011-12-19
/*修改者: 日期:
/*版本:1.0
/*****************************************/
void delayms(uint t)
{
uchar i;
while(t--)for(i=0;i<120;i++);
}
/*****************************************************
函数功能:判断液晶模块的忙碌状态
返回值:result。result=1,忙碌;result=0,不忙
***************************************************/
uchar BusyTest(void)
{
bit result;
RS=0; //根据规定,RS为低电平,RW为高电平时,可以读状态
RW=1;
E=1; //E=1,才允许读写
_nop_(); //空操作
_nop_();
_nop_();
_nop_(); //空操作四个机器周期,给硬件反应时间
result=BF; //将忙碌标志电平赋给result
E=0; //将E恢复低电平
return result;
}
/*****************************************************
函数功能:将模式设置指令或显示地址写入液晶模块
入口参数:dictate
***************************************************/
void WriteInstruction (unsigned char dictate)
{
while(BusyTest()==1); //如果忙就等待
RS=0; //根据规定,RS和R/W同时为低电平时,可以写入指令
RW=0;
E=0; //E置低电平(根据表8-6,写指令时,E为高脉冲,
// 就是让E从0到1发生正跳变,所以应先置"0"
_nop_();
_nop_(); //空操作两个机器周期,给硬件反应时间
P0=dictate; //将数据送入P0口,即写入指令或地址
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四个机器周期,给硬件反应时间
E=1; //E置高电平
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四个机器周期,给硬件反应时间
E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/*****************************************************
函数功能:指定字符显示的实际地址
入口参数:x
***************************************************/
void WriteAddress(unsigned char x)
{
WriteInstruction(x|0x80); //显示位置的确定方法规定为"80H+地址码x"
}
/*****************************************************
函数功能:将数据(字符的标准ASCII码)写入液晶模块
入口参数:y(为字符常量)
***************************************************/
void WriteData(unsigned char y)
{
while(BusyTest()==1);
RS=1; //RS为高电平,RW为低电平时,可以写入数据
RW=0;
E=0; //E置低电平(根据表8-6,写指令时,E为高脉冲,
// 就是让E从0到1发生正跳变,所以应先置"0"
P0=y; //将数据送入P0口,即将数据写入液晶模块
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四个机器周期,给硬件反应时间
E=1; //E置高电平
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四个机器周期,给硬件反应时间
E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/*****************************************************
函数功能:对LCD的显示模式进行初始化设置
***************************************************/
void LcdInitiate(void)
{
delayms(15); //延时15ms,首次写指令时应给LCD一段较长的反应时间
WriteInstruction(0x38); //显示模式设置:001(0/1数据总线4位/8位)(0/1显示1行/2行)(0/1每字符5x7点阵/5x10)xx
delayms(5); //延时5ms ,给硬件一点反应时间
WriteInstruction(0x38);
delayms(5);
WriteInstruction(0x38); //连续三次,确保初始化成功
delayms(5);
WriteInstruction(0x06); //显示模式设置:显示开,无光标,光标不闪烁 000001(0/1光标左移/右移)(0/1写入新数据后显示屏不移动/显示屏右移1个字符)
delayms(5);
WriteInstruction(0x0c); //显示模式设置:光标右移,字符不移 00001(0/1显示器关/开)(0/1无光标/有光标)(0/1光标闪/不闪)
delayms(5);
WriteInstruction(0x01); //清屏幕指令,将以前的显示内容清除
delayms(5);
// 移动方向设置:显示屏或光标 0001()()xx
//(0)(0)=光标左移1格,ac-1()() //(0)(1)=光标右移1格,ac+1
//(1)(0)=显示器上的字符全部左移1格,光标不动 //(1)(1)=显示器上的字符全部右移1格,光标不动
}
//主程序
/*void main()
{
uchar lcdi=0;
LcdInitiate(); //调用LCD初始化函数
delayms(10); //延时10ms,给硬件一点反应时间
WriteAddress(0x00); //写入一个字符
WriteData('L');
WriteAddress(0x01); //写入一个字符
WriteData('C');
WriteAddress(0x02); //写入一个字符
WriteData('D');
WriteAddress(0x40); //写入字符串 //第二行第一个位置开始显示
while(lcdstring[lcdi]!='\0')
{
WriteData(lcdstring[lcdi]);
lcdi++; //指向下字符数组一个元素
}
delayms(100);
while(1);
} *//// |
|