📄 main.c
字号:
#include"reg52.h"
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar i=0;
uchar SHEZHI[15];
uchar init[7]={0x11,0x21,0x23,0x23,0x04,0x04,0x08};//秒,分,时,日,月,星期,年
void DISP_DATA(void);
//*******************LCD模块
#define LCD_DATA P0 //LCD的数据口
sbit LCD_BUSY=LCD_DATA^7; //LCD忙信号位
sbit LCD_RW=P3^5; //LCD读写控制
sbit LCD_RS=P3^4; //LCD寄存器选择
sbit LCD_EN=P3^6; //LCD使能信号
void LCD_check_busy(void) //检测LCD状态,看它是不是还在忙呢
{
while(1)
{
LCD_EN=0;
LCD_RS=0; //指令寄存器通信
LCD_RW=1; //read data
LCD_DATA=0xff;
LCD_EN=1;
if(!LCD_BUSY)break;
}
LCD_EN=0;
}
void LCD_cls(void) //LCD清屏
{
LCD_check_busy();
LCD_RS=0;
LCD_RW=0;
LCD_DATA=1;
LCD_EN=1;
LCD_EN=0;
}
void LCD_write_instruction(unsigned char LCD_instruction) //写指令到LCD
{
LCD_check_busy();
LCD_RS=0;
LCD_RW=0; //写数据
LCD_DATA=LCD_instruction;
LCD_EN=1;
LCD_EN=0;
}
void LCD_write_data(unsigned char LCD_data) //输出一个字节数据到LCD
{
LCD_check_busy();
LCD_RS=1;
LCD_RW=0;
LCD_DATA=LCD_data;
LCD_EN=1;
LCD_EN=0;
}
void LCD_set_position(unsigned char x) //LCD光标定位到x处
{
LCD_write_instruction(0x80+x);
}
void LCD_printc(unsigned char lcd_data) //输出一个字符到LCD
{
LCD_write_data(lcd_data);
}
void LCD_prints(unsigned char *lcd_string) //输出一个字符串到LCD
{
unsigned char i=0;
while(lcd_string[i]!=0x00)
{
LCD_write_data(lcd_string[i]);
i++;
}
}
void LCD_initial(void) //初始化LCD
{
LCD_write_instruction(0x3c);
LCD_write_instruction(0x0c);
LCD_write_instruction(0x06);//显示屏一定要不移动。
LCD_cls();
}
//*************************LCD模块结束
//键盘
uchar temp_OUT=0x0A;
uchar flag_san_key=0;
void delay1(void)
{
uint i;
for(i=300;i>0;i--);
}
void scan_key(void)
{
unsigned char i,temp1;
P1=0XF0;
for(i=0;i<4;i++)
{
P1=~(1<<i);
delay1();
temp1=P1&0xF0;
if(temp1!=0xF0)
{
delay1();
temp1=P1&0xF0;
switch(temp1)
{
case 0xe0:temp_OUT=3-(3-i)*1;SHEZHI[flag_san_key++]=temp_OUT;break; // 0 1 2 3
case 0xd0:temp_OUT=7-(3-i)*1;SHEZHI[flag_san_key++]=temp_OUT;break; // 4 5 6 7
case 0xb0:temp_OUT=11-(3-i)*1;SHEZHI[flag_san_key++]=temp_OUT;break; // 8 9 a b
case 0x70:temp_OUT=15-(3-i)*1;SHEZHI[flag_san_key++]=temp_OUT;break; // c d e f
default:break;//0x3f;
}
tt:temp1=P1&0xF0;
if(temp1!=0xF0)
{
;
goto tt;
}
}
}
}
void DISP_DATA(void)
{
scan_key();
if(temp_OUT!=0X0A)
{
init[6]=(SHEZHI[0]<<4)|SHEZHI[1];
init[5]=(SHEZHI[2]<<4)|SHEZHI[3];
init[4]=(SHEZHI[4]<<4)|SHEZHI[5];
init[3]=(SHEZHI[6]<<4)|SHEZHI[7];
init[2]=(SHEZHI[8]<<4)|SHEZHI[9];
init[1]=(SHEZHI[10]<<4)|SHEZHI[11];
init[0]=(SHEZHI[12]<<4)|SHEZHI[13];
//显示
LCD_set_position(1);
LCD_printc(0X32);
LCD_set_position(2);
LCD_printc(0X30);
LCD_set_position(3);
LCD_printc(0X30+init[6]/16);
LCD_set_position(4);
LCD_printc(0X30+init[6]%16);
LCD_set_position(5);
LCD_prints(" ");
//月日
LCD_set_position(7);
LCD_printc(0X30+init[4]/16);
LCD_set_position(8);
LCD_printc(0X30+init[4]%16);
LCD_set_position(9);
LCD_prints("-");
LCD_set_position(10);
LCD_printc(0X30+init[3]/16);
LCD_set_position(11);
LCD_printc(0X30+init[3]%16);
LCD_set_position(12);
LCD_prints(" ");
//星期
LCD_set_position(14);
LCD_printc(0X30+init[5]%16);
//时分秒
LCD_set_position(0X4E);
LCD_printc(0X30+init[0]%16);
LCD_set_position(0X4D);
LCD_printc(0X30+init[0]/16);
LCD_set_position(0X4C);
LCD_prints(":");
LCD_set_position(0x4B);
LCD_printc(0X30+init[1]%16);
LCD_set_position(0x4a);
LCD_printc(0X30+init[1]/16);
LCD_set_position(0X49);
LCD_prints(":");
LCD_set_position(0X48);
LCD_printc(0X30+init[2]%16);
LCD_set_position(0X47);
LCD_printc(0X30+init[2]/16);
}
}
//ds1302控制
sbit reset=P3^7;
sbit sclk=P2^6;
sbit io=P2^7;
void delay()
{uint j;
for(j=500;j>0;j--);
}
//-----------ds1302模块开始-------------------
//注意点:sclk的上升沿输入数据,sclk的下跳沿输出数据
//读写时都是从第0位开始
void write_byte(uchar inbyte)
{
uchar i;
for(i=8;i>0;i--)
{
sclk=0; //写的时候低电平改变数据
if(inbyte&0x01)
io=1;
else
io=0;
sclk=1; //写的时候高电平,把数据写入ds1302
_nop_();
inbyte=inbyte>>1;
}
}
uchar read_byte() //sclk的下跳沿读数据
{
uchar i,temp=0;
io=1; //设置为输入口
for(i=7;i>0;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)
{
reset=1;
write_byte(cmd);
write_byte(indata);
reset=0;
sclk=0;
}
//----------读ds1302某地址的的数据-----------------
uchar read_ds1302(uchar addr)
{
uchar backdata;
reset=1;
write_byte(addr);
backdata=read_byte();//先写地址,然后读数据
reset=0;
sclk=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)
{
for(;n>0;n--)
{
*p=read_ds1302(addr);
p++;
addr=addr+2;
}
}
void init_ds1302()
{
reset=0;
sclk=0;
write_ds1302(0x80,0x00);//写控制字,允许写
write_ds1302(0x90,0x00);//禁止涡流充电
}
//-----------ds1302模块结束-------------------
//- ----------公历转阴历结束-------------------
//LCD1602显示
void LCD1602_DISP(void)
{
uchar format=0;
if(SHEZHI[14]==0x0A)
{
flag_san_key=0;
set_ds1302(0x80,init,7);//设置初始时间,日期,年月
SHEZHI[14]=0x00;
for(format=0;format<14;format++)
{
SHEZHI[format]=0;
}
}
if(temp_OUT==0X0A)
{
read_nowtime(0x81,init,7); //读出当前时间,读出7个字节
//年
LCD_set_position(1);
LCD_printc(0X32);
LCD_set_position(2);
LCD_printc(0X30);
LCD_set_position(3);
LCD_printc(0X30+init[6]/16);
LCD_set_position(4);
LCD_printc(0X30+init[6]%16);
LCD_set_position(5);
LCD_prints(" ");
//月日
LCD_set_position(7);
LCD_printc(0X30+init[4]/16);
LCD_set_position(8);
LCD_printc(0X30+init[4]%16);
LCD_set_position(9);
LCD_prints("-");
LCD_set_position(10);
LCD_printc(0X30+init[3]/16);
LCD_set_position(11);
LCD_printc(0X30+init[3]%16);
LCD_set_position(12);
LCD_prints(" ");
//星期
LCD_set_position(14);
LCD_printc(0X30+init[5]%16);
//时分秒
LCD_set_position(0X4E);
LCD_printc(0X30+init[0]%16);
LCD_set_position(0X4D);
LCD_printc(0X30+init[0]/16);
LCD_set_position(0X4C);
LCD_prints(":");
LCD_set_position(0x4B);
LCD_printc(0X30+init[1]%16);
LCD_set_position(0x4a);
LCD_printc(0X30+init[1]/16);
LCD_set_position(0X49);
LCD_prints(":");
LCD_set_position(0X48);
LCD_printc(0X30+init[2]%16);
LCD_set_position(0X47);
LCD_printc(0X30+init[2]/16);
}
}
void main()
{
LCD_initial();
init_ds1302(); //初始化ds1302
set_ds1302(0x80,init,7);//设置初始时间,日期,年月
while(1)
{
DISP_DATA();
LCD1602_DISP();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -