发布网友 发布时间:2022-04-22 06:32
共1个回答
热心网友 时间:2023-07-22 20:49
我给你一份,我之前写过的程序。
/*
* LCD1602 时钟
*
* author:
* date:2011.2.22
*/
#include "main.h"
#include "ds1302.h"
#include "LCD1602.h"
sbitdelua = P2^6;
sbitwelua = P2^7;
uint8 Time[7]={55,59,11,22,2,2,11};//秒分时日月周年10-08-15 11:59:55
uint8 T_tmp[7];
uint8 Num, T_n=0;
void delay(uint16 n)
{
while (n--);
}
/*
* 初始化系统定时器
*/
void systimer_init(void)
{
TMOD &= 0x0F;
TMOD |= 0x10;
TH1 = 0xDC; // 定时10ms
TL1 = 0x00;
TR1 = 0;
ET1 = 0;
EA = 1;
}
/*
* 判断键值
*/
/*
uint8 scan_key(void)
{
uint8 val=0;
KeyOut1 = 0;
KeyOut2 = 1;
KeyOut3 = 1;
KeyOut4 = 1;
if(KeyIn4 == 0)
{
delay(KEY_DELAY);
if (KeyIn4 == 0)
{
val = K_ADD;
}
}
while((KeyIn1 == 0)||(KeyIn2 == 0)||(KeyIn3 == 0)||(KeyIn4 == 0));
KeyOut1 = 1;
KeyOut2 = 0;
KeyOut3 = 1;
KeyOut4 = 1;
if(KeyIn4 == 0)
{
delay(KEY_DELAY);
if(KeyIn4 == 0)
val = K_LEFT;
}
while ((KeyIn1 == 0)||(KeyIn2 == 0)||(KeyIn3 == 0)||(KeyIn4 == 0));
KeyOut1 = 1;
KeyOut2 = 1;
KeyOut3 = 0;
KeyOut4 = 1;
if (KeyIn4 == 0)
{
delay(KEY_DELAY);
if (KeyIn4 == 0)
val = K_SUB;
}
while ((KeyIn1 == 0)||(KeyIn2 == 0)||(KeyIn3 == 0)||(KeyIn4 == 0));
KeyOut1 = 1;
KeyOut2 = 1;
KeyOut3 = 1;
KeyOut4 = 0;
if (KeyIn2 == 0)
{
delay(KEY_DELAY);
if (KeyIn2 == 0)
val = K_SET;
}
if (KeyIn3 == 0)
{
delay(KEY_DELAY);
if (KeyIn3 == 0)
val = K_ENTER;
}
if (KeyIn4 == 0)
{
delay(KEY_DELAY);
if (KeyIn4 == 0)
val = K_RIGHT;
}
while ((KeyIn1 == 0)||(KeyIn2 == 0)||(KeyIn3 == 0)||(KeyIn4 == 0));
return val;
}
*/
/*
* 启动clock数字闪烁
*/
void start_flash(void)
{
T_n = 0;
switch (Num)
{
case 0: w_data(6, Time[0]); break;
case 1: w_data(3, Time[1]); break;
case 2: w_data(0, Time[2]); break;
default: break;
}
TH1 = 0xDC; // 定时10ms
TL1 = 0x00;
TR1 = 1;
ET1 = 1;
}
/*
* 停止clock数字闪烁
*/
void stop_flash(void)
{
ET1 = 0;
TR1 = 0;
switch (Num)
{
case 0: w_data(6, Time[0]); break;
case 1: w_data(3, Time[1]); break;
case 2: w_data(0, Time[2]); break;
default: break;
}
}
/*
* 更新LCD时间
*/
void refresh_clock(void)
{
if (Time[0] != T_tmp[0]) // 更新秒
{
T_tmp[0] = Time[0];
w_data(6, Time[0]);
}
if (Time[1] != T_tmp[1]) // 更新分
{
T_tmp[1] = Time[1];
w_data(3, Time[1]);
}
if (Time[2] != T_tmp[2]) // 更新时
{
T_tmp[2] = Time[2];
w_data(0, Time[2]);
}
}
/*
* 时钟设置
*/
void set_clock(void)
{
uint8 k_val, flag=0;
Num = 0;
while (1)
{
//k_val = scan_key();
if (k_val == 0)
{
if (flag == 0)
{
start_flash();
flag = 1;
}
continue;
}
flag = 0;
stop_flash();
if (k_val == K_ENTER)
{
set_time(Time);
break;
}
switch (k_val)
{
case K_ADD:
if (Num == 2)
{
if (Time[Num] >= 23)
Time[Num] = 0;
else
Time[Num]++;
}
else
{
if (Time[Num] >= 59)
Time[Num] = 0;
else
Time[Num]++;
}
break;
case K_SUB:
if (Num == 2)
{
if (Time[Num] == 0)
Time[Num] = 23;
else
Time[Num]--;
}
else
{
if (Time[Num] == 0)
Time[Num] = 59;
else
Time[Num]--;
}
break;
case K_LEFT:
if (Num >= 2)
Num = 0;
else
Num++;
break;
case K_RIGHT:
if (Num == 0)
Num = 2;
else
Num--;
break;
default: break;
}
refresh_clock();
}
}
main()
{
uint8 k_val;
delua = 0;
welua = 0;
systimer_init();
LCD1602_init();
set_time(Time); //初始时间设定
w_string(0, " : : ");
w_data(0, Time[2]); // 时
w_data(3, Time[1]); // 分
w_data(6, Time[0]); // 秒
while (1)
{
read_time(Time);
refresh_clock();
//k_val = scan_key();
if (k_val == K_SET)
set_clock();
}
}
void time1_isr() interrupt 3
{
ET1 = 0;
TH1 = 0xDC; // 定时10ms
TL1 = 0x00;
T_n++;
if (T_n == 50) // 0.5s
{
switch (Num)
{
case 0: clear_data(6); break;
case 1: clear_data(3); break;
case 2: clear_data(0); break;
default: break;
}
}
else if (T_n >= 100) // 1s
{
T_n = 0;
switch (Num)
{
case 0: w_data(6, Time[0]); break;
case 1: w_data(3, Time[1]); break;
case 2: w_data(0, Time[2]); break;
default: break;
}
}
ET1 = 1;
}
/*
* LCD1602显示
*
*/
#include "main.h"
#include "LCD1602.h"
/**
* 等待繁忙标志
*/
/*
void wait(void)
{
P0 = 0xFF;
do
{
RS = 0;
RW = 1;
EN = 0;
EN = 1;
}while (BUSY == 1);
EN = 0;
}
*/
void Delay_1ms(unsigned int Time)
{
unsigned int x, y;
for(x = Time; x > 0; x--)
for(y = 120; y > 0; y--);
}
/**
* 写数据
*/
void w_dat(uint8 dat)
{
RS = 1;
P0 = dat;
Delay_1ms(5);
EN = 1;
Delay_1ms(5);
EN = 0;
}
/**
* 写命令
*/
void w_cmd(uint8 cmd)
{
RS = 0;
P0 = cmd;
Delay_1ms(5);
EN = 1;
Delay_1ms(5);
EN = 0;
}
/**
* 发送字符串到LCD
*/
void w_string(uint8 addr_start, uint8 *p)
{
w_cmd(addr_start | 0x80);
while (*p != '\0')
{
w_dat(*p++);
}
}
/**
* 发送数字到LCD(00~99)
*/
void w_data(uint8 addr_start, uint8 dat)
{
w_cmd(addr_start | 0x80);
w_dat(dat%100/10 + '0');
w_dat(dat%10 + '0');
}
/**
* 显示两位空白
*/
void clear_data(uint8 addr_start)
{
w_cmd(addr_start | 0x80);
w_dat(' ');
w_dat(' ');
}
/**
* 初始化1602
*/
void LCD1602_init(void)
{
w_cmd(0x38); // 16*2显示,5*7点阵,8位数据接口
w_cmd(0x0C); // 显示器开、光标开、光标允许闪烁
w_cmd(0x06); // 文字不动,光标自动右移
w_cmd(0x01); // 清屏
}
/*
* DS1302 突发方式,连读,连写
*
*/
#include "main.h"
#include "ds1302.h"
/**
* 写一个字节
*/
void write_ds1302_byte(uint8 dat)
{
uint8 i;
for (i=0;i<8;i++)
{
SDA = dat & 0x01;
SCK = 1;
dat >>= 1;
SCK = 0;
}
}
/**
* 读一个字节
*/
uint8 read_ds1302_byte(void)
{
uint8 i, dat=0;
for (i=0;i<8;i++)
{
dat >>= 1;
if (SDA)
dat |= 0x80;
SCK = 1;
SCK = 0;
}
return dat;
}
void reset_ds1302(void)
{
RST = 0;
SCK = 0;
RST = 1;
}
/**
* 清除写保护
*/
void clear_ds1302_WP(void)
{
reset_ds1302();
RST = 1;
write_ds1302_byte(0x8E);
write_ds1302_byte(0);
SDA = 0;
RST = 0;
}
/**
* 设置写保护
*/
void set_ds1302_WP(void)
{
reset_ds1302();
RST = 1;
write_ds1302_byte(0x8E);
write_ds1302_byte(0x80);
SDA = 0;
RST = 0;
}
/**
* 设定时钟数据
*/
void set_time(uint8 *timedata)
{
uint8 i, tmp;
for (i=0; i<7; i++) // 转化为BCD格式
{
tmp = timedata[i] / 10;
timedata[i] = timedata[i] % 10;
timedata[i] = timedata[i] + tmp*16;
}
clear_ds1302_WP(); //清除写保护
reset_ds1302(); //初始化端
RST = 1; //使能拉高
write_ds1302_byte(DS1302_W_ADDR); //时钟突发寄存器写寄存器
for (i=0; i<7; i++)
{
write_ds1302_byte(timedata[i]);
delay(10);
}
write_ds1302_byte(0);
SDA = 0;
RST = 0;
set_ds1302_WP(); //设置写保护
}
/**
* 读时钟数据
*/
void read_time(uint8 *timedata)
{
uint8 i, tmp;
clear_ds1302_WP();
reset_ds1302();
RST = 1;
write_ds1302_byte(DS1302_R_ADDR);
for (i=0; i<7; i++)
{
timedata[i] = read_ds1302_byte();
delay(10);
}
SDA = 0;
RST = 0;
set_ds1302_WP();
for (i=0; i<7; i++) // 转化为正常格式
{
tmp = timedata[i] / 16;
timedata[i] = timedata[i] % 16;
timedata[i] = timedata[i] + tmp*10;
}
}