标题:
将DS1302的时间在LCD1602上显示出来
[打印本页]
作者:
远方l
时间:
2018-6-11 22:02
标题:
将DS1302的时间在LCD1602上显示出来
在仿真上可以显示并可调,但是在单片机板子上不能实现,用的是不b104 的板子,用了按键调时间,闹钟这是程序
是不是在lcd1602上需要用ascii码值,但是我不知道该怎样改驱动里面的数据转换呀
#include<reg51.h>
#include<lcd1602.c>
#include<display.c>
#include<ds1302.c>
#include<key.c>
void timer0_isr()interrupt 1
{
TL0= (65536-2000)%256;
TH0= (65536-2000)/256;
cp++;
if(cp>=250) //半秒的时间
{
cp=0;
cp1++;
cp2++;
P0= 0xff;
}
if(cp1>= 2)
{
cp1= 0;
flash= ~flash;
if(key_flag> 8 || key_flag <= 0)
{
display();
}
else
display_key_scan();
P0= 0xff;
//FL1602_clear();
}
if(time[6]== hour && time[7] == min) //响闹钟的时间
{
buzzer= 0;
if(cp3>= 5000) //十秒钟后自动关闭
{
cp3= 0;
buzzer= 1;
cp4++;
}
if(cp4>= 3) //30秒后自动开启
{
cp4= 0;
buzzer= 0;
}
}
elsebuzzer = 1;
}
void timer0_init()
{
TMOD= 0x01;
TL0= (65536-2000)%256;
TH0= (65536-2000)/256;
EA= 1;
ET0= 1;
TR0= 1;
}
void main(void)
{
init_ds1302();
FL1602_init();
timer0_init();
FL1602_clear();
while(1)
{
buzzer= 0;
key_scan();
get_ds1302_time();
}
}
///////////////////////////////////////////////////////////////
这是ds1302
#include<reg51.h>
/*********************************************************************************/
//ds1302驱动
//2011年5月
/*********************************************************************************/
#define uchar unsigned char /*宏定义用uchar 代替unsignedchar*/
#define uint unsigned int /*宏定义用uint 代替 unsignedint*/
sbit ret = P3^7;
sbit scl = P3^6;
sbit sd = P3^4;
//uchar sec, min, hour, date, month, year,week;
void ds1302_init(void)
{
ret= 0;
scl= 0;
ret= 1;
}
/*********************************对DS1302写1字节函数*****************************/
void write_ds1302_onebyte(uchar dat)
{
uchari;
for(i= 0;i < 8;i++)
{
sd= dat & 0x01;
scl= 0;
scl= 1;
dat= dat >> 1;
}
}
/*********************************从DS1302读一字节函数*****************************/
uchar read_ds1302_onebyte(void)
{
uchari,dat;
for(i= 0;i < 8;i++)
{
scl= 1;
dat= dat >> 1;
scl= 0;
if(sd)dat= dat | 0x80;
}
return(dat);
}
/*****************************对DS1302的某一地址写一字节函数***********************/
void write_ds1302_add_dat(uchar add,uchardat)
{
ds1302_init();
write_ds1302_onebyte(add);
write_ds1302_onebyte(dat);
scl= 1;
ret= 0;
}
/*****************************从DS1302的某一地址读一字节函数***********************/
uchar read_ds1302_add_dat(uchar add) /*读1302数据*/
{
uchardat_temp;
ds1302_init();
write_ds1302_onebyte(add);
dat_temp= read_ds1302_onebyte();
scl= 1;
ret= 0;
return(dat_temp);
}
/********************************8421BCD码到十进制转换*****************************/
uchar BCD_DEC_conv(uchar x)
{
uchardec;
dec= 0x0f & x;
x= x >> 4;
dec = dec + x * 10;
return(dec);
}
/********************************十进制到8421BCD码转换*****************************/
uchar DEC_BCD_conv(uchar x)
{
ucharbcd;
bcd= x % 10;
x= x / 10;
x= x << 4;
bcd = bcd | x ;
return(bcd);
}
/*******************从ds1302中获得时间函数函数**********************/
void get_ds1302_time(void) //获取1302的时间数据(时、分、秒),存入time1数组中
{
uchard;
d= read_ds1302_add_dat(0x81); //读秒
sec= BCD_DEC_conv(d); //得到秒
d= read_ds1302_add_dat(0x83); //读分
min= BCD_DEC_conv(d); //得到分
d= read_ds1302_add_dat(0x85); //读小时
hour= BCD_DEC_conv(d); //得到小时
d= read_ds1302_add_dat(0x8b); //读周
week= BCD_DEC_conv(d); //得到周
d= read_ds1302_add_dat(0x87); //读日
date= BCD_DEC_conv(d); //得到日
d = read_ds1302_add_dat(0x89); //读月
month= BCD_DEC_conv(d); //得到月
d = read_ds1302_add_dat(0x8d); //读年
year= BCD_DEC_conv(d); //得到年
}
/*******************DS1302初始化函数hanshu*********************/
void init_ds1302(void)
{
write_ds1302_add_dat(0x8e,0x00); //写允许
write_ds1302_add_dat(0x80,DEC_BCD_conv(19)); //写年
write_ds1302_add_dat(0x84,DEC_BCD_conv(4)); //写月
write_ds1302_add_dat(0x82,DEC_BCD_conv(23)); //写日
write_ds1302_add_dat(0x80,DEC_BCD_conv(3)); //写星期
write_ds1302_add_dat(0x84,DEC_BCD_conv(10)); //写时
write_ds1302_add_dat(0x82,DEC_BCD_conv(12)); //写分
write_ds1302_add_dat(0x80,DEC_BCD_conv(16)); //写秒
write_ds1302_add_dat(0x8e, 0x80); //写保护
}
//////////////////////////////////////////////////////////
显示函数
#include<reg51.h>
//#include"key.c"
uchari,year,month,date,hour,week,min,sec,flash,cp1,key_flag,cp,cp2,cp3,cp4;
char time[9];
sbit buzzer = P3^2;
void display(void)
{
goto_row_column(1,4);//第一行
// display_string("20");//显示2
display_num(year);
display_string("/");
display_num(month);
display_string("/");
display_num(date);
goto_row_column(2,4);
display_num(hour);
if(flash)display_string(":"); else display_string(" ");
display_num(min);
if(flash)display_string(":"); else display_string(" ");
display_num(sec);
// delay(50000);
// // FL1602_clear();
// goto_row_column(1,4);
// display_string("20"); //显示2
// display_num(year);
// display_string("/"); //显示字母及符号的方式
// display_num(month);
// display_string("/");
// display_num(date);
// delay(50000);delay(50000);delay(50000);
// goto_row_column(2,4);
// display_num(hour);
// if(flash== 1) display_string("");
// else display_string(":");//冒号闪烁0x00if(flash== 0xff) 0x00 if(flash == 0xff )
// display_num(min);
// if(flash== 1 )display_string(" ");
// elsedisplay_string(":");//冒号闪烁
// display_num(sec);
// delay(50000);delay(50000);delay(50000);//delay(50000);
//
// i++;
// if(i> 100)i = 0;
}
void display_key_scan(void) //显示调整时的时间
{
if(key_flag > 6)
{
goto_row_column(1,0);
display_string("****ding nao****");
goto_row_column(2,4);
if(key_flag == 7) //调整时的小时
{
if(flash)
display_num(time[6]);
else
display_string(" ");
}
else
display_num(time[6]);
if(flash==0x00) //
display_string(":");
else
display_string("");
if(key_flag == 8) //
{
if(flash)
display_num(time[7]);
else
display_string(" ");
}
else
display_num(time[7]);
display_string(" ");
}
else //调整显示状态下的时分秒
{
goto_row_column(1,4);//第一行
if(key_flag== 1) //显示年的调整值并闪烁
{
if(flash)
display_num(time[0]);
else
display_string(" ");
}
else
display_num(time[0]);
display_string("/");
if(key_flag== 2) //显示月的调整值并闪烁
{
if(flash)
display_num(time[1]);
else
display_string(" ");
}
else
display_num(time[1]);
display_string("/");
if(key_flag== 3) //显示日的调整值并闪烁
{
if(flash)
display_num(time[2]);
else
display_string(" ");
}
else
display_num(time[2]);
goto_row_column(2,4);
if(key_flag== 4) //显示时的调整值并闪烁
{
if(flash)
display_num(time[3]);
else
display_string(" ");
}
else
display_num(time[3]);
if(flash) //冒号的显示并闪烁 == 0x00
display_string(":");
else
display_string("");
if(key_flag== 5) //显示分的调整值并闪烁
{
if(flash)
display_num(time[4]);
else
display_string(" ");
}
else
display_num(time[4]);
if(flash) //冒号的显示并闪烁==0x00
display_string(":");
else
display_string("");
if(key_flag== 6) //显示秒的调整值并闪烁
{
if(flash)
display_num(time[5]);
else
display_string(" ");
}
else
display_num(time[5]);
}
// FL1602_clear();
}
//////////////////////////////////////////
Lcd1602
#include<reg51.h> //这两个驱动均是正确的
#define uchar unsigned char
#define uint unsigned int
uchar num[] = "0123456789";
sbit RS = P1^7;
sbit RW = P1^6;
sbit E = P1^5;
void delay(uint x)
{
while(x--);
}
void write_command(uchar command) /*写指令函数*/
{
RW= 0;
RS= 0;
P0= command;
E= 1;
delay(100);
E= 0;
RW= 1;
}
void write_dat(uchar dat) /*写数据函数*/
{
RW= 0;
RS= 1;
P0= dat;
E= 1;
delay(100);
E= 0;
RW= 1;
}
void display_string(char *p) /*字符串函数*/
{
while(*p)
{
write_dat(*p);
p++;
}
}
void display_num(uchar x) //向lcd1602写数字变量
{
write_dat(num[x/ 10]);
write_dat(num[x% 10]);
}
void goto_row_column(uchar row, ucharcolumn) /*行列控制函数*/
{
if(row== 1)
{
write_command(0x80+ column);
delay(100);
}
elseif(row == 2)
write_command(0xc0 + column); // 0xC0
}
void FL1602_init(void) /*初始化函数*/
{
write_command(0x38); /*设置两行,每行16个字符,每个字符5*7点阵,8位数据接口*/
write_command(0x0f);
delay(100);
write_command(0x0c); /*设置开显示*/
write_command(0x06); /*设置当读或写一个字节后,地址指针加1,且光标加1*/
}
void FL1602_clear(void) /*清屏函数*/
{ /*设置清屏指令,单片机向1602的数据端口写入0x01后,1602自动将本身DDRAM的内容全部填入“空白”
的ASCII码20H,并将地址计数器AC的值设为0,同时光标归位,即将光标撤回液晶显示屏的左上方
,此时显示器无显示。*/
write_command(0x01);
write_command(0x02);
}
//////////////////////////////////////////////////////////////
按键部分
#include<reg51.h>
unsigned char seven_seg[] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char key_flag,i,j,year,month,date,hour,min,sec; //用一变量记载13按键按下的次数
code uchar key_scan_row[] ={0x7f,0xbf,0xdf,0xef};
code uchar key_value[] = {
0xee,0xed,0xeb,0xe7,
0xde,0xdd,0xdb,0xd7,
0xbe,0xbd,0xbb,0xb7,
0x7e,0x7d,0x7b,0x77
};
char time[9] ;
uchar key_mode; /*为了避免每次调整完一个数据后不再从ds1302中读取数据,即LCD1602上显示的数据位当前的调整值*/
void key_scan(void) //让键盘行线输出扫描数据
{
P2= key_scan_row[ i];
[ i]
if(P2!= key_scan_row[ i]) //[ i]如果有按键按下,P2口不是原来的扫描数据;
[ i]
{
delay(200);
for(j= 0;j < 16;j ++)
{
if(j == 13) //切换键&& key_flag >= 1
{
if(P2== key_value[j] )
{
delay(200);
key_flag++;
if(key_flag> 8) key_flag = 0;
key_mode++;
if(key_mode== 1)
{
time[0]= year;
time[1]= month;
time[2]= date;
time[3]= hour;
time[4]= min;
time[5]= sec;
}
}
}
if(j== 14)
{
if(P2== key_value[j] ) //加键
{
delay(200);
if(key_flag == 1) time[0] ++;if(time[0] >=100) time[0] = 0; //年
if(key_flag == 2) time[1] ++;if(time[1] >=13) time[1] = 1; //月
if(key_flag == 3) time[2] ++;if(time[2] >=31) time[2] = 1; //日
if(key_flag == 4) time[3] ++;if(time[3] >=24) time[3] = 0; //时
if(key_flag == 5) time[4] ++;if(time[4] >=60) time[4] = 0; //分
if(key_flag == 6) time[5] ++;if(time[5] >=60) time[5] = 0; //秒
if(key_flag == 7) time[6] ++;if(time[5] >=24) time[6] = 0; // 定时
if(key_flag == 8) time[7] ++;if(time[5] >=60) time[7] = 0; // 定分
}
}
if(j== 15)
{
if(P2== key_value[j] ) //减键
{
delay(200);
if(key_flag == 1) time[0] --;if(time[0] <0) time[0] = 99; //年
if(key_flag == 2) time[1] --;if(time[1] <1) time[1] = 12; //月
if(key_flag == 3) time[2] --;if(time[2] <1) time[2] = 31; //日
if(key_flag == 4) time[3] --;if(time[3] <0) time[3] = 23; //时
if(key_flag == 5) time[4] --;if(time[4] <0) time[4] = 59; //分
if(key_flag == 6) time[5] --;if(time[5] <0) time[5] = 59; //秒
if(key_flag == 7) time[6] --;if(time[5]<0) time[7] = 23; // 定时
if(key_flag == 8) time[7] --;if(time[5]<0) time[8] = 59; // 定分
}
}
if(j== 12) //退出键,退出模式
{
if(P2== key_value[j] )
{
delay(200);
key_flag= 0;
key_mode= 0;
write_ds1302_add_dat(0x8e,0x00); //写允许
write_ds1302_add_dat(0x8c,DEC_BCD_conv(time[0])); //写年
write_ds1302_add_dat(0x88,DEC_BCD_conv(time[1])); //写月
write_ds1302_add_dat(0x86,DEC_BCD_conv(time[2])); //写日
// write_ds1302_add_dat(0x8a,DEC_BCD_conv(time[3])); //写周
write_ds1302_add_dat(0x84,DEC_BCD_conv(time[3])); //写时
write_ds1302_add_dat(0x82,DEC_BCD_conv(time[4])); //写分
write_ds1302_add_dat(0x80,DEC_BCD_conv(time[5])); //写秒
write_ds1302_add_dat(0x8e,0x80); //写保护
}
}
if(j== 11) //直接调到定闹模式
{
if(P2== key_value[j] )
{
delay(200);
key_flag = 7;
if(key_flag > 8 )key_flag = 0;
}
}
if(j== 10) //关闭闹钟按键
{
if(P2== key_value[j] )
{
delay(200);
buzzer= 1;
}
}
}
while(P2!= key_scan_row[ i]);
[ i]
}
i++;
if(i>= 4)i = 0;
}
复制代码
作者:
zsyzdx
时间:
2018-6-12 08:50
不会是1602没有调节对比度吧,哈哈!!!!
作者:
小猫猫爱吃鱼
时间:
2018-6-12 09:06
发这么长的程序,也真是难为你了
作者:
lzts88
时间:
2018-6-12 10:50
LCD显示就是写点和清点, 有字模的, 没有就自己生成, 比如 0 , 在你设定的区域那些点显, 那些点不显就显示0了. 先调通显示这块就容易了
作者:
chaoxin
时间:
2018-6-12 11:46
写个asc码转10进制的函数就可以了。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1