📄 ds1302+lcd1602-c51.c
字号:
/*******************************************************************/
/* */
/* - DS1302时钟显示与定时控制 */
/* */
/* LCD1602显示 */
/*---------------------湖北汽车工业学院----------------------------*/
/*--------------------------电信系----钟蕾-----------------------------*/
/******************************************************************/
#include<reg51.h>
#include<intrins.h>
#include"AT2402.H"
#define ALARM_NUM 8
#define uchar unsigned char
#define uint unsigned int
sbit LCD_RS = P2^0; //REST的信号
sbit LCD_RW = P2^1; //
sbit LCD_EN = P2^2;
sbit K1 = P1^4; //开关
sbit K2 = P1^5;
sbit K3 = P1^6;
sbit K4 = P1^7;
//*******************************************
sbit reset = P1^2; //DS1302的复位信号
sbit sclk = P1^0; //DS1302的时钟信号
sbit io = P1^1; //IO口信号 数据线
//*******************************************
/////****************************************
//24c04的定义****************************
//sbit sclk;
//******************************************
sbit BEEP = P3^7;
bit flag=1, hour=0, min=0, sec=0, num=0;
bit year=0, month=0, day=0, week=0;
bit alarm_flag=0;
uchar timecount=0, count=0;
uchar k=0;
uchar str1[]=" - - Week: ";
uchar str2[]="Time: ";
uchar str3[]="Alarm: ";
uchar str4[]="Alarm_num: ";
uchar init [] ={0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //
uchar init1[] ={0x00,0x00};
uchar init2[] ={0x00,0x59,0x23,0x01,0x05,0x01,0x06}; //星期0x01
//秒, 分, 时, 日, 月,星期,年
//******************************************
struct alarm
{
char s; //秒
char m; //分
char h; // 时
}alarm2={0x00,0x00,0x00}; //定义结构数组
//********************************************************************************
uchar code mytab[8] = {0x01,0x1b,0x1d,0x19,0x1d,0x1b,0x01,0x00}; //小喇叭
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();}; //延时作用
void Set_W1302(uchar addr); // 设定值写入DS1302
void Set_Flash(uchar row,uchar col); // 被设置数据闪动
void Set_place(uchar row,uchar col); // 指定位置显示
void Play_nowtime(); // 显示当前时间
void key_set(uchar num,uchar row,uchar col ); // 键设定函数
void alarm_time(); // 报警时间设定
void Play_alarmtime(); // 报警时间显示
void Time_compare(); // 时间比较
void write_byte(uchar inbyte);
void init_24c02(void); //初始化24c02
/******************************************************************/
void delay1(int ms) //延时函数
{
unsigned char y;
while(ms--)
{
for(y = 0; y<250; y++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
/**********以下为读写24c02的函数***********************************************/
/**********************************************************/
//写的子函数
/**********************************************************/
void write_byte(uchar inbyte)
{
uchar i;
for(i=0;i<8;i++)
{
sclk=0; //写的时候低电平改变数据
if(inbyte&0x01)
io=1; //数据线
else
io=0;
sclk=1; //写的时候高电平,把数据写入ds1302
_nop_();
inbyte=inbyte>>1;
}
}
/******************************************************************/
/* */
/*检查LCD忙状态 */
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 */
/* */
/******************************************************************/
bit lcd_busy()
{
bit result;
LCD_RS = 0; //指令寄存器
LCD_RW = 1; //读数据
LCD_EN = 1; //使能信号
delayNOP();
result = (bit)(P0&0x80);//读取信号
LCD_EN = 0;
return(result);
}
/*********************************************************/
/* */
/*写指令数据到LCD */
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */
/* */
/*********************************************************/
void lcd_wcmd(uchar cmd)
{
while(lcd_busy());
LCD_RS = 0;
LCD_RW = 0;//写数据
LCD_EN = 0; //不动作
_nop_();
_nop_();
P0 = cmd; //指令数据
delayNOP();
LCD_EN = 1; //高位使能
delayNOP();
LCD_EN = 0;
}
/*********************************************************/
/* */
/*写显示数据到LCD */
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */
/* */
/*********************************************************/
void lcd_wdat(uchar dat)
{
while(lcd_busy());
LCD_RS = 1; //写入数据寄存器
LCD_RW = 0;
LCD_EN = 0;
P0 = dat; //写入数据
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
/*********************************************************/
/* */
/* LCD初始化设定 */
/* */
/*********************************************************/
void init_lcd()
{
delay1(15);
lcd_wcmd(0x01); //清除LCD的显示内容
lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据
delay1(5);
lcd_wcmd(0x38);
delay1(5);
lcd_wcmd(0x38);
delay1(5);
lcd_wcmd(0x0c); //显示开,关光标
delay1(5);
lcd_wcmd(0x06); //移动光标
delay1(5);
lcd_wcmd(0x01); //清除LCD的显示内容
delay1(5);
}
/*********************************************************/
//延时函数
/*********************************************************/
void delay()
{
uchar j;
for(j=250;j>0;j--);
}
/*********************************************************/
/* */
/* 写字符串函数 */
/* */
/*********************************************************/
void write_str(uchar addr,uchar *p)
{
uchar i=0;
lcd_wcmd(addr); //写入指令数据
while(p[i]!='\0')
{
lcd_wdat(p[i]);//写入数据
i++;
}
}
/*********************************************************/
/* */
/* 设定显示位置 */
/* */
/*********************************************************/
void write_position(uchar row,uchar col)
{
uchar place;
if(row==1)
{
place=0x80+col-1;
lcd_wcmd(place); //位置指令数据
}
else
{
place=0xc0+col-1;
lcd_wcmd(place);
}
}
/*********************************************************/
/* */
/*自定义字符写入CGRAM */
/* */
/*********************************************************/
void writetab()
{
unsigned char i;
lcd_wcmd(0x40); //写CGRAM
for (i = 0; i< 8; i++)
lcd_wdat(mytab[i]);
}
/**********************************************************/
/**********************************************************/
//读的子函数
/**********************************************************/
uchar read_byte() //sclk的下跳沿读数据
{
uchar i,temp=0;
io=1; //设置为输入口
for(i=0;i<7;i++)
{
sclk=0;
if(io==1)
temp=temp|0x80;
else
temp=temp&0x7f;
sclk=1; //产生下跳沿
temp=temp>>1;
}
return (temp);
}
/**********************************************************/
// 往ds1302的某个地址写入数据
/**********************************************************/
void write_ds1302(uchar cmd,uchar indata)
{
sclk=0;
reset=1;
write_byte(cmd);
write_byte(indata);
sclk=0;
reset=0;
}
/**********************************************************/
// 读ds1302某地址的的数据
/**********************************************************/
uchar read_ds1302(uchar addr)
{
uchar backdata;
sclk=0;
reset=1;
write_byte(addr); //先写地址
backdata=read_byte(); //然后读数据
sclk=0;
reset=0;
return (backdata);
}
/**********************************************************/
// 设置初始时间
/**********************************************************/
void set_ds1302(uchar addr,uchar *p,uchar n) //写入n个数据
{
write_ds1302(0x8e,0x00); //写控制字,允许写操作
for(;n>0;n--)
{
write_ds1302(addr,*p);
p++;
addr=addr+2;
}
write_ds1302(0x8e,0x80); //写保护,不允许写
}
/**********************************************************/
// 读取当前时间
/**********************************************************/
void read_nowtime(uchar addr,uchar *p,uchar n) //读出N个数据
{
for(;n>0;n--)
{
*p=read_ds1302(addr);
p++;
addr=addr+2;
}
}
/**********************************************************/
// 初始化DS1302
/**********************************************************/
void init_ds1302()
{
reset=0;
sclk=0;
write_ds1302(0x80,0x00);
write_ds1302(0x90,0xa6); //一个二极管+4K电阻充电
write_ds1302(0x8e,0x80); //写保护控制字,禁止写
}
/**********************************************************/
/* */
/* 蜂鸣器响一声 */
/* */
/**********************************************************/
void beep()
{
unsigned char y;
for (y=0;y<100;y++)
{
delay();
BEEP=!BEEP; //BEEP取反
}
BEEP=1; //关闭蜂鸣器
delay1(50);
}
/**********************************************************/
/* */
/* :闪动函数 */
/* */
/**********************************************************/
void flash()
{
if(flag)
{
write_position(2,9);
lcd_wdat(':');
write_position(2,12);
lcd_wdat(':');
}
else
{
write_position(2,9);
lcd_wdat(0x20); //写显示数据到LCD
write_position(2,12);
lcd_wdat(0x20);
}
}
void init_24c02(void)
{
int i;
for(i=0;i<8;i++)
{
Write_One_Byte(0x00+i*0x02,0x59);
Write_One_Byte(0x01+i*0x02,0x23);
}
Write_One_Byte(0xaf,0x08);
}
/**********************************************************/
// 主函数
/**********************************************************/
void main()
{
P1=0xff;
TMOD=0x01;
TH0=0x4c; //50ms定时
TL0=0x00;
EA=1;
ET0=1;
TR0=1;
init_lcd(); //初始化LCD
write_str(0x80,str1); //液晶显示提示信息
write_str(0xc0,str2); //液晶显示提示信息
init_ds1302(); //初始化ds1302
init_24c02(); //初始化24c02
writetab(); //自定义字符写入CGRAM
delay1(5);
write_position(2,16);
lcd_wdat(0x00); //显示自定义字符小喇叭
while(1)
{
//---------------------------------------------------------
if(!K1)
{
if(!K2)
{
set_ds1302(0x80,init2,7); //设置初始时间,日期,年 ,月
beep();
}
if(!K3)
{
delay1(35); //消除抖动
if(!K3)
{
write_str(0xc0,str3); //显示报警信息
if(alarm_flag) //alarm_flag=1,开定时
{
write_position(2,16);
lcd_wdat(0x00); //显示自定义字符小喇叭
}
write_str(0x80,str4);
k=Read_One_Byte(0xaf);
do
{
count=k;
num=1;
while(num) //写入闹钟个数
{
key_set(8,1,14);
if(!K4)
{
delay1(35);
if(!K4)
{
Set_place(1,14);
k=(init1[0]<<4|init1[1]);
Play_alarmtime(); //查看报警时间
beep();
num=0;
}
}
}
// Play_alarmtime(); //查看报警时间
}while(k>=1);
beep();
delay1(700);
write_str(0x80,str1);
write_str(0xc0,str2); //显示时间信息
if(alarm_flag) //alarm_flag=1,开定时
{
write_position(2,16);
lcd_wdat(0x00); //显示自定义字符小喇叭
}
}
}
if(!K4)
{
delay1(35); //消除抖动
if(!K4)
{
// for(k=0;k<ALARM_NUM;)
// {
alarm_time(); //K4键设定报警时间
// k=k+2;
// }
if(alarm_flag) //alarm_flag=1,开定时
{
write_position(2,16);
lcd_wdat(0x00); //显示自定义字符小喇叭
}
}
}
}
//---------------------------------------------------------
if(!K4)
{
delay1(35); //消除抖动
if(!K4)
{
beep();
alarm_flag=~alarm_flag;
if(alarm_flag) //alarm_flag=1,开定时
{
write_position(2,16);
lcd_wdat(0x00); //显示自定义字符小喇叭
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -