最近在用LCD12864做一个数字时钟,时间部分已经基本搞定,就是往里面添加温度显示时,虽然可以显示温度,但是显示一会后就出现乱码了,而且添加在主函数里延时过大,影响功能按键的使用。
求大神帮忙看一下。时间显示,按键控制,温度显示,闹钟设置,AD转换识别系统, 还有一个我未实现的用串口来设置初始时间的问题。
#include<reg52.h>
#include<intrins.h>
#include<stdlib.h>
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P3^5; //定义DS18B20数据线引脚端
char a,d2,d1,d0;
float f_temp;
uint i,j,temp,low,high;
/*端口定义*/
#define LCD_data P0
#include"24c02.h"
sbit RS = P2^7;
sbit RW = P2^6;
sbit EN = P2^5;
sbit s1 = P3^2; //SW1定义为--功能键
sbit s2 = P3^3; //SW2定义为--增大键
sbit s3 = P3^4; //SW3定义为--减小键
sbit feng = P3^2;//蜂鸣器
/************************************************/
sbit adwr = P2^1; //定义A/D的WR端口
sbit adrd = P2^2; //定义A/D的RD端口
sbit adcs = P3^6;
/***********************************************/
uchar code dis1[]={" 现在时间 "};//10
uchar code dis2[]={" -- -- "};
uchar code dis3[]={" : : "};
uchar code dis4[]={"现在温度: 00.0度"}; //6
uchar t=0,s1num;
char miao,shi,fen,ri,yue,nian;
void delay(uint z) //延时
{
uint r,w;
for(r=0;r<z;r++)
for(w=0;w<110;w++);
}
/*写指令数据到LCD*/
/*RS=0,RW=0,E=高脉冲,D0--D7=指令码。*/
void write_cmd(uchar cmd)
{
RS = 0;
RW = 0;
EN = 0;
P0 = cmd;
delay(5);
EN = 1;
delay(5);
EN = 0;
}
/*写显示数据到LCD*/
/*RS=1,RW=0,E=高脉冲,D0--D7=数据*/
void write_dat(uchar dat) //写入
{
RS = 1;
RW = 0;
EN = 0;
P0 = dat;
delay(5);
EN = 1;
delay(5);
EN = 0;
}
/*设置显示位置*/
void lcd_pos(uchar X,uchar Y) //方便主函数调用点地址
{
uchar pos;
if(X==0)
{X=0x80;}
else if(X==1)
{X=0x90;}
else if(X==2)
{X=0x88;}
else if(X==3)
{X=0x98;}
pos = X+Y;
write_cmd(pos); //显示地址
}
void write_sfm(uchar app,uchar add,uchar date) //写时分秒函数
{
uchar shi,ge;
shi = date/10; //分解一个2位数的十位和个位
ge = date%10;
lcd_pos(app,add); //设置显示位置
write_dat(0x30+shi); //送去液晶显示十位
write_dat(0x30+ge); //送去液晶显示个位
}
void init() /*LCD初始化设定*/
{
uint g;
write_cmd(0X30); //基本指令操作
delay(5);
write_cmd(0X0C); //显示开,关光标
delay(5);
write_cmd(0X01); //清除LCD的显示内容
delay(5);
fen = 0; //初始化分钟变量值
miao = 0;
shi = 0;
s1num = 0;
init_24c02();
//
lcd_pos(1,0);
g = 0;
while(dis2[g]!=' ') //
{
write_dat(dis2[g]); //显示字符
g++;
}
lcd_pos(2,0);
g = 0;
while(dis3[g]!=' ') //
{
write_dat(dis3[g]); //显示字符
g++;
}
//
miao = read_add(1); //首次上电从AT4C02中读取存储的数据
fen = read_add(2);
shi = read_add(3);
ri = read_add(4); //首次上电从AT4C02中读取存储的数据
yue = read_add(5);
nian = read_add(6);
write_sfm(2,5,miao);
write_sfm(2,3,fen);
write_sfm(2,1,shi);
write_sfm(1,5,ri);
write_sfm(1,3,yue);
write_sfm(1,1,nian);
TMOD=0x01; //设置定时器1为工作方式1
TH0=(65536-45872)/256;
TL0=(65536-45872)%256;
ET0 = 1; //开定时器1中断
TR0 = 1; //启动定时器1
EA = 1; //开总中断
}
void bell() //蜂鸣器定时
{
if(shi == 12)
{ if(fen == 12)
{
feng = 0;
delay(1000);
feng = 1;
delay(1000);
}
}
else
feng = 1;
}
void ad()
{ uchar adva1;
adcs = 0;
adwr = 1;
_nop_();
adwr = 0;
_nop_();
adwr = 1;
delay(40);
P1 = 0xff;
adrd = 1;
_nop_();
adrd = 0;
_nop_();
adva1 = P1;
adrd = 1;
if(adva1 < 102)
{
write_cmd( 0x08 );
}//关了不可再打开,但加判断就会影响显示
//设想 关了后 再次调整ad,然后按建就可显示
// else
// {
// write_cmd( 0x0c );
// }
}
void dat_dis()
{
lcd_pos(3,5); //显示温度
write_dat(0x30+d2);
write_dat(0x30+d1);
lcd_pos(3,6); //显示温度
write_dat(0x2e); //写入“.”号
write_dat(0x30+d0);
}
void init_temp()
{
DQ=0; //拉低总线,产生复位信号
i=80;while(i>0)i--; //延时480~960us
DQ=1; //拉高总线
i=4;while(i>0)i--; //延时15~60us
while(DQ); //等待产生应答脉冲
i=70;while(i>0)i--; //延时至少480us
}
//------------------获温部分:写函数-------------------------------
void wr_temp(uchar dat) //写1个字节
{
bit testb;
for(j=8;j>0;j--)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) //写1
{
DQ=0; //拉低总线,产生写时间隙
i++; //延时大于1us
DQ=1; //拉高总线
i=8;while(i>0)i--; //延时至少60us,供DS18B20采样
}
else //写0
{
DQ=0; //拉低总线,产生写时间隙
i=8;while(i>0)i--; //保持至少60us,供DS18B20采样
DQ=1; //拉高总线
i++;i++;
}
}
}
//------------------获温部分:读函数-------------------------------
uchar rd_temp() //读1个字节
{
bit b; //定义存放接收到的1个字节
uchar i_b;
uchar rdbyte;
for(j=8;j>0;j--)
{
DQ=0; //拉低总线,产生读时隙
i++; //延时大于1us
DQ=1; //释放总线
i++;i++; //给一定时间让总线释放
b=DQ; //读取数据
i=8;while(i>0)i--; //延时至少60us
i_b=b;
rdbyte=(i_b<<7)|(rdbyte>>1); //将读取到得一位值左移7位,存放读取的数据变量rdbyte右移1位
}
return rdbyte;
}
//----------------------温度获取函数---------------------------
void get_temp()
{
init_temp(); //初始化,复位并获取应答信号
wr_temp(0xcc); //跳过ROM
wr_temp(0x44); //开始温度转换
delay(1000); //等待温度转换完成
init_temp(); //将DS18B20复位
wr_temp(0xcc); //跳过ROM
wr_temp(0xbe); //读暂存器
low=rd_temp(); //读取低8位
high=rd_temp(); //读取高8位
temp=high;
temp<<=8;
temp=temp|low; //将读取的低8位和高8位合并
f_temp=temp*0.0625; //温度在寄存器中为12位 分辨率位0.0625°
temp=f_temp*10+0.5; //精确到十分位,四舍五入
d2=temp/100; //显示数据:十位
d1=temp%100/10; //显示数据:个位
d0=temp%10; //显示数据:十分位
}
void xianshi()
{ uchar g;
lcd_pos(0,0);
g = 0;
while(dis1[g]!=' ') //
{
write_dat(dis1[g]); //显示字符
g++;
}
lcd_pos(3,0);
g = 0;
while(dis4[g]!=' ') //
{
write_dat(dis4[g]); //显示字符
g++;
}
}
void keyscan() //键盘扫描函数
{
if(s1==0)
{
delay(5);
if(s1==0) //确认功能键被按下
{
s1num++; //功能键按下次数计数
delay(5);
while(!s1); //释放确认
if(s1num==1) //第一次被按下时
{
TR0 = 0; //关闭定时器
lcd_pos(2,5); //光标移动到秒位置
write_cmd(0x0f); //光标开始闪烁
}
if(s1num==2) //第二次按下光标闪烁定位到分钟位置
{
lcd_pos(2,3);
}
if(s1num==3) //第三次按下光标闪烁定位到小时位置
{
lcd_pos(2,1);
}
if(s1num==4) //第三次按下光标闪烁定位到小时位置
{
lcd_pos(1,5);
}
if(s1num==5) //第三次按下光标闪烁定位到小时位置
{
lcd_pos(1,3);
}
if(s1num==6) //第三次按下光标闪烁定位到小时位置
{
lcd_pos(1,1);
}
if(s1num==7) //第四次按下
{
s1num = 0; //记录按键数清0
write_cmd(0x0c); //取消光标闪烁
TR0 = 1; //启动定时器时钟开始走
}
}
}
if(s1num!=0)
{
if(s2==0)
{
delay(5);
if(s2==0)
{
delay(5);
while(!s2);
if(s1num==1)
{
miao++;
if(miao==60)
miao = 0;
write_sfm(2,5,miao);
lcd_pos(2,5);
write_add(1,miao);
}
if(s1num==2)
{
fen++;
if(fen==60)
fen = 0;
write_sfm(2,3,fen);
lcd_pos(2,3);
write_add(2,fen);
}
if(s1num==3)
{
shi++;
if(shi==24)
shi = 0;
write_sfm(2,1,shi);
lcd_pos(2,1);
write_add(3,shi);
}
if(s1num==4)
{
ri++;
if(ri==31)
ri = 0;
write_sfm(1,5,ri);
lcd_pos(1,5);
write_add(4,ri);
}
if(s1num==5)
{
yue++;
if(yue==13)
yue = 0;
write_sfm(1,3,yue);
lcd_pos(1,3);
write_add(5,yue);
}
if(s1num==6)
{
nian++;
if(nian==100)
nian = 0;
write_sfm(1,1,nian);
lcd_pos(1,1);
write_add(6,nian);
}
}
}
if(s3==0)
{
delay(5);
if(s3==0)
{
while(!s3);
if(s1num==1)
{
miao--;
if(miao==-1)
miao = 59;
write_sfm(2,5,miao);
lcd_pos(2,5);
write_add(1,miao);
}
if(s1num==2)
{
fen--;
if(fen==-1)
fen = 59;
write_sfm(2,3,fen);
lcd_pos(2,3);
write_add(2,fen);
}
if(s1num==3)
{
shi--;
if(shi==-1)
shi = 23;
write_sfm(2,1,shi);
lcd_pos(2,1);
write_add(3,shi);
}
if(s1num==4)
{
ri--;
if(ri==-1)
ri = 30;
write_sfm(1,5,ri);
lcd_pos(1,5);
write_add(4,ri);
}
if(s1num==5)
{
yue--;
if(yue==-1)
yue = 12;
write_sfm(1,3,yue);
lcd_pos(1,3);
write_add(5,yue);
}
if(s1num==6)
{
nian--;
if(nian==-1)
nian = 99;
write_sfm(1,1,nian);
lcd_pos(1,1);
write_add(6,nian);
}
}
}
}
}
void main() //主函数
{
//delay(10);
init();
xianshi();
while(1)
{
keyscan();
if(s1num==0)
{
get_temp();
dat_dis();
bell();
}
ad();
}
}
void
timer0() interrupt 1 //中断
{
TH0 = (65536-45000) / 256;
TL0 = (65536-45000) % 256;
t++;
if(t == 20)
{
t = 0;
miao++;
if(miao == 60)
{
miao = 0;
fen++;
if(fen == 60)
{
fen = 0;
shi++;
if(shi == 24)
{
shi = 0;
ri++;
if(ri == 31)
{
ri = 0;
yue++;
if(yue == 13)
{
yue = 0;
nian++;
if(nian == 100)
{
nian = 0;
}
write_sfm(1,1,nian);
write_add(6,nian);
}
write_sfm(1,3,yue);
write_add(5,yue);
}
write_sfm(1,5,ri);
write_add(4,ri);
}
write_sfm(2,1,shi);
write_add(3,shi);
}
write_sfm(2,3,fen);
write_add(2,fen);
}
write_sfm(2,5,miao);
write_add(1,miao);
}
}
多谢提醒,模块化的我也看过一些,就是自己编写的时候除了点问题,若是简单的在12864上显示文字,还是能编写的,可是就是不知道为什么,编写一个可控制时钟时就是编译不了,貌似是调用函数时出了点问题,一大堆警告没错误,且生成不了HEX文件,作为一个初学者,相当的苦恼。
C语言模块化编程(我见过最好的).pdf 下载积分: 积分 -1 分
1.28 MB, 下载次数: 358, 下载积分: 积分 -1 分
一周热门 更多>