LCD1602液晶秒表C51程序.docx
- 文档编号:5626967
- 上传时间:2022-12-29
- 格式:DOCX
- 页数:8
- 大小:17.08KB
LCD1602液晶秒表C51程序.docx
《LCD1602液晶秒表C51程序.docx》由会员分享,可在线阅读,更多相关《LCD1602液晶秒表C51程序.docx(8页珍藏版)》请在冰豆网上搜索。
LCD1602液晶秒表C51程序
LCD1602液晶秒表C51程序
此程序是基于51hei单片机开发板上面写的,如需要移植到自己的电路上,修改相应的端口即可,开发板完整的电路图下载:
点这里(注意:
只需要看1602部分即可,其他部分可以忽略)
/**
***********************************************************************
*@filemain.c
*@authorxr
*@date2014年5月8日22:
11:
33--2014年5月9日12:
03:
49
*@versionV1.2.3
*@briefLCD1602液晶跑表单片机STC89C52RCMCU晶振11.0592MHZ
***********************************************************************
*/
#include;
/*系统时钟*/
#defineSYS_XTAL(11059200UL/12)
/*定时器T0重载值*/
unsignedcharthr0,tlr0;
unsignedcharthr1,tlr1;
/*跑表计数*/
unsignedchartimer[9]={0,0,0,0,0,0,0,0,0};//分别表示跑表的各个位上的数字
bitflag10ms=0;
externbitstopflag;//跑表走停标志位
externvoidInitalLCD1602();
externvoidLcdShowStr(unsignedcharx,unsignedchary,unsignedchar*str);
externvoidKeyDriver();
externvoidKeyScan();
voidDisplayTimer();
voidConfigTimer0(unsignedintxms);
voidConfigTimer1(unsignedintxms);
/*主函数main()*/
voidmain(void)
{
ConfigTimer0(10);//定时10ms
ConfigTimer1
(1);
InitalLCD1602();
LcdShowStr(0,0,"stopwatch");
LcdShowStr(2,1,"0000000.00s");//液晶初始化显示
LcdShowStr(10,0,"stop!
");
while
(1)
{
KeyDriver();
DisplayTimer();
if((flag10ms==1)&&(stopflag==1))
{
flag10ms=0;
timer[0]++;
if(timer[0]>;9)
{
timer[0]=0;
timer[1]++;
if(timer[1]>;9)
{
timer[1]=0;
timer[2]++;
if(timer[2]>;9)
{
timer[2]=0;
timer[3]++;
if(timer[3]>;9)
{
timer[3]=0;
timer[4]++;
if(timer[4]>;9)
{
timer[4]=0;
timer[5]++;
if(timer[5]>;9)
{
timer[5]=0;
timer[6]++;
if(timer[6]>;9)
{
timer[6]=0;
timer[7]++;
if(timer[7]>;9)
{
timer[7]=0;
timer[8]++;
if(timer[8]>;9)
{
timer[8]=0;
}
}
}
}
}
}
}
}
}
}
}
}
/*将跑表时间显示到液晶上*/
voidDisplayTimer()
{
unsignedcharstr[20];
/*分解timer*/
str[0]=timer[8]+'0';
str[1]=timer[7]+'0';
str[2]=timer[6]+'0';
str[3]=timer[5]+'0';
str[4]=timer[4]+'0';
str[5]=timer[3]+'0';
str[6]=timer[2]+'0';
str[7]='.';
str[8]=timer[1]+'0';
str[9]=timer[0]+'0';
str[10]='\0';
LcdShowStr(2,1,str);
}
/*定时器T0配置*/
voidConfigTimer0(unsignedintxms)
{
unsignedlongtmp;
tmp=(SYS_XTAL*xms)/1000;
tmp=65536-tmp+18;
thr0=(unsignedchar)(tmp>;>;8);
tlr0=(unsignedchar)tmp;
TMOD&=0xF0;//清零T0控制位
TMOD|=0x01;//定时器方式1
TH0=thr0;
TL0=tlr0;
TR0=1;//开启timer0
ET0=1;//开启T0中断
EA=1;//开启总中断
}
/*配置定时器T1*/
voidConfigTimer1(unsignedintxms)
{
unsignedlongtmp;
tmp=(SYS_XTAL*xms)/1000;
tmp=65536-tmp+18;
thr1=(unsignedchar)(tmp>;>;8);
tlr1=(unsignedchar)tmp;
TMOD&=0x0F;
TMOD|=0x10;
TH1=thr1;
TL1=tlr1;
TR1=1;
ET1=1;
EA=1;
}
/*定时器T0中断服务*/
voidTimer0_ISP()interrupt1
{
TH0=thr0;
TL0=tlr0;
flag10ms=1;//定时10ms
}
/*定时器T1中断服务*/
voidTimer1_ISP()interrupt3
{
TH1=thr1;
TL1=tlr1;//定时1ms
KeyScan();
}
/**
***********************************************************************
*@fileLcd1602.c
*@authorxr
*@date2014年5月7日13:
33:
17
*@versionV1.2.3
*@briefLCD1602液晶底层驱动
***********************************************************************
*/
#include;
//LCD1602_IO
sbitLCD1602_RS=P1^0;
sbitLCD1602_RW=P1^1;
sbitLCD1602_EN=P1^5;
#defineLCD1602_DBP0
/*液晶忙碌等待*/
voidLCD1602Wait()
{
unsignedcharsta;
LCD1602_DB=0xFF;//总线拉高,检测液晶状态字
LCD1602_RS=0;
LCD1602_RW=1;
do
{
LCD1602_EN=1;
sta=LCD1602_DB;
LCD1602_EN=0;//避免液晶输出数据
}while(sta&0x80);//状态字最高位STA7==0空闲,1忙碌
}
/*液晶写命令*/
voidLCD1602WriteCmd(unsignedcharcmd)
{
LCD1602Wait();
LCD1602_RS=0;
LCD1602_RW=0;
LCD1602_EN=0;
LCD1602_DB=cmd;
LCD1602_EN=1;
LCD1602_EN=0;
}
/*液晶写数据*/
voidLCD1602WriteData(unsignedchardat)
{
LCD1602Wait();
LCD1602_RS=1;
LCD1602_RW=0;
LCD1602_EN=0;
LCD1602_DB=dat;
LCD1602_EN=1;
LCD1602_EN=0;
}
/*液晶初始化*/
voidInitalLCD1602()
{
LCD1602WriteCmd(0x38);
LCD1602WriteCmd(0x0C);
LCD1602WriteCmd(0x06);
LCD1602WriteCmd(0x01);//清屏
}
/*写数据到液晶上,字符串str,坐标(x,y),地址addr*/
voidLcdShowStr(unsignedcharx,unsignedchary,unsignedchar*str)
{
unsignedcharaddr;
if(y==0)
{
addr=0x00+x;
}
else
{
addr=0x40+x;
}
LCD1602WriteCmd(addr|0x80);
while(*str!
='\0')
{
LCD1602WriteData(*str++);
}
}
/**
***********************************************************************
*@filekeyboard.c
*@authorxr
*@date2014年5月8日22:
11:
33--2014年5月9日12:
03:
49
*@versionV1.2.3
*@brief按键驱动单片机STC89C52RCMCU晶振11.0592MHZ
***********************************************************************
*/
#include;
/*按键输出输入端口定义*/
sbitKEY_IN1=P2^4;
sbitKEY_IN2=P2^5;
sbitKEY_IN3=P2^6;
sbitKEY_IN4=P2^7;
sbitKEY_OUT1=P2^3;
sbitKEY_OUT2=P2^2;
sbitKEY_OUT3=P2^1;
sbitKEY_OUT4=P2^0;
externunsignedchartimer[9];//分别表示跑表的各个位上的数字
/*按键当前状态*/
unsignedcharvolatilekeySta[4][4]={{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};
/*按键对应标准PC键盘编码*/
constunsignedcharcodekeyCodeMap[4][4]={
{'1','2','3',0x26},/*数字键1,2,3和向上键*/
{'4','5','6',0x25},/*数字键4,5,6和向左键*/
{'7','8','9',0x28},/*数字键7,8,9和向下键*/
{'0',0x1B,0x0D,0x27}/*数字键0和向右键*/
};
bitstopflag=0;//跑表走停标志位0停止,1运行
voidKeyAction(unsignedcharkeycode);
voidLcdShowStr(unsignedcharx,unsignedchary,unsignedchar*str);
/*按键驱动函数*/
voidKeyDriver()
{
/*上一次按键的备份值*/
staticunsignedcharkeybackup[4][4]={{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};
unsignedchari,j;
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
if(keySta[i][j]!
=keybackup[i][j])//当前按键状态和上一次的按键状态不同
{//按键有动作
if(keybackup[i][j]!
=0)//上一次按键是弹起
{
KeyAction(keyCodeMap[i][j]);//当前按键是想、按下
}
keybackup[i][j]=keySta[i][j];//备份当前按键值
}
}
}
}
/*按键扫描函数*/
voidKeyScan()
{
unsignedchari=0;
staticunsignedcharkeyout=0;//按键行索引
staticunsignedcharkeybuf[4][4]={{0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF},
{0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF}
};
/*按键消抖*/
keybuf[keyout][0]=(keybuf[keyout][0]<<1)|KEY_IN1;
keybuf[keyout][1]=(keybuf[keyout][1]<<1)|KEY_IN2;
keybuf[keyout][2]=(keybuf[keyout][2]<<1)|KEY_IN3;
keybuf[keyout][3]=(keybuf[keyout][3]<<1)|KEY_IN4;
/*更新按键的值*/
for(i=0;i<4;i++)
{
if((keybuf[keyout][i]&0x1F)==0x1F)
{
//五次检测按键的值都是1
keySta[keyout][i]=1;
}
elseif((keybuf[keyout][i]&0x1F)==0x00)
{
//五次检测的按键值都是0
keySta[keyout][i]=0;
}
}
/*按键行索引++*/
keyout++;
keyout&=0x03;//到4归零
/*根据按键索引选择行按键进行扫描*/
switch(keyout)
{
case0:
KEY_OUT1=0;KEY_OUT4=1;//选择第一行按键
case1:
KEY_OUT2=0;KEY_OUT1=1;
case2:
KEY_OUT3=0;KEY_OUT2=1;
case3:
KEY_OUT4=0;KEY_OUT3=1;
default:
break;
}
}
/*按键动作函数*/
voidKeyAction(unsignedcharkeycode)
{
unsignedchari=0;
if(keycode==0x1B)//ESC
{
/*跑表复位*/
stopflag=0;
for(i=0;i<9;i++)
{
timer[i]=0;
}
LcdShowStr(2,1,"0000000.00s");
LcdShowStr(10,0,"reset!
");
}
elseif(keycode==0x0D)//回车键跑表走停
{
if(stopflag==0)
{
stopflag=1;
LcdShowStr(10,0,"start!
");
}
else
{
stopflag=0;
LcdShowStr(10,0,"stop!
");//多写入一个空格
}
}
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- LCD1602 液晶 秒表 C51 程序