📄 57点阵电子钟程序.c
字号:
#include <w78e58.h> //库函数调用
#include <intrins.h> //库函数调用
#define uint unsigned int
#define uchar unsigned char
sbit DS1302_CLK = P3^5; //实时时钟时钟线引脚
sbit DS1302_IO = P3^6; //实时时钟数据线引脚
sbit DS1302_RST = P3^7; //实时时钟复位线引脚
sbit BAT = P3^3;
sbit ACC7 = ACC^7;
char hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year,hide_naom,hide_naoh; //秒,分,时到日,月,年位闪的计数
sbit Set = P1^7; //模式切换键
sbit Up = P1^6; //加法按钮
sbit DQ = P3^4; //温度传送数据IO口
sbit s_n = P4^3;
char done,count,temp,flag,up_flag,b,press;
uchar temp_value; //温度值
uchar TempBuffer[5],week_value[5];
uchar naom=0,naoh=0,naoString[5];
uchar code design[18][7]={0xf3,0xed,0xed,0xfed,0xed,0xed,0xf3, //0 1 5*7点阵数码表
0xfb,0xf3,0xfb,0xfb,0xfb,0xfb,0xf1, //1 2
0xf3,0xed,0xfd,0xfb,0xf7,0xef,0xe1, //2 3
0xf3,0xed,0xfd,0xf3,0xfd,0xed,0xf3, //3 4
0xfb,0xf3,0xeb,0xeb,0xe1,0xfb,0xfb, //4 5
0xe1,0xef,0xe3,0xed,0xfd,0xed,0xf3, //5 6
0xf3,0xed,0xef,0xe3,0xed,0xed,0xf3, //6 7
0xe1,0xfd,0xfd,0xfb,0xf7,0xf7,0xf7, //7 8
0xf3,0xed,0xed,0xf3,0xed,0xed,0xf3, //8 9
0xf3,0xed,0xed,0xf1,0xfd,0xed,0xf3, //9 10
0xff,0xf3,0xf3,0xff,0xf3,0xf3,0xff, //: 11
0xff,0xff,0xff,0xff,0xff,0xf3,0xf3, //. 12
0xff,0xff,0xff,0xe1,0xff,0xff,0xff, //- 13
0xef,0xf9,0xf7,0xf7,0xf7,0xf7,0xf9, //'C 14
0xee,0xed,0xeb,0xe7,0xeb,0xed,0xee, //k 15
0xee,0xee,0xea,0xea,0xe0,0xe4,0xf5, //w 16
0xff,0xff,0xff,0xff,0xff,0xff,0xff, //灭灯 17
0xe0,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb}; //t 18
//*****************延时程序**************************
void Delay1ms(unsigned int count) //延时
{
unsigned int i,j;
for(i=0;i<count;i++)
for(j=0;j<120;j++);
}
void mdelay(uint delay) //延时子程序
{
uint i;
for(;delay>0;delay--)
{
for(i=0;i<62;i++)
{;}
}
}
//*******************显示子程序*********************
//Port Definitions**********************************************
sbit SER_595=P0^7; //595串行数据输入
sbit RCLK_595=P0^6; //位时钟脉冲
sbit SRCLK_595=P0^5; //出锁存器控制脉冲
sbit E_138=P2^3; //使能端
sbit A_138=P2^0; //138数据输入
sbit B_138=P2^1;
sbit C_138=P2^2;
void OUT_595(void) //595数据输出
{
RCLK_595=0;
_nop_();
_nop_();
RCLK_595=1; //上升沿将数据送到输出锁存器
_nop_();
_nop_();
RCLK_595=0;
}
void WR_595(unsigned char *str) //595数据输入
{
int i,j,k=4,temp,c;
for (i=0;i<5;i++)
{
switch(str[k]) //将字符转为数字
{
case '0':c=0;break;
case '1':c=1;break;
case '2':c=2;break;
case '3':c=3;break;
case '4':c=4;break;
case '5':c=5;break;
case '6':c=6;break;
case '7':c=7;break;
case '8':c=8;break;
case '9':c=9;break;
case ':':c=10;break;
case '.':c=11;break;
case '-':c=12;break;
case 'c':c=13;break;
case 'k':c=14;break;
case 'w':c=15;break;
case 'm':c=16;break;
case 't':c=17;break;
}
temp=design[c][b];
k--;
for (j=0;j<5;j++)
{
if(temp&0x01)
{
SER_595=1;
}
else
SER_595=0;
temp=temp>>1;
SRCLK_595=1; //上升沿发生移位
_nop_();
_nop_();
SRCLK_595=0;
}
}
}
void WR_LED(unsigned char *str)
{
int a,j;
SRCLK_595=0,a=0,b=0; //LED_Write
for (j=0;j<7;j++)
{
a++;
E_138=0;
WR_595(str);
OUT_595();
P2=a;
E_138=1;
b++;
mdelay(1);
}
}
void Print(unsigned char *str) //将字符输出到LED显示
{
WR_LED(str);
}
/***********DS1302时钟部分子程序******************/
typedef struct __SYSTEMTIME__ //定义事件结构体
{
unsigned char Second;
unsigned char Minute;
unsigned char Hour;
unsigned char Week;
unsigned char Day;
unsigned char Month;
unsigned char Year;
unsigned char YearString[5];
unsigned char DateString[5];
unsigned char TimeString[5];
unsigned char WeekString[5];
}SYSTEMTIME; //定义的时间类型
SYSTEMTIME CurrentTime;
#define AM(X) X
#define PM(X) (X+12) // 转成24小时制
#define DS1302_SECOND 0x80 //时钟芯片的寄存器位置,存放时间
#define DS1302_MINUTE 0x82
#define DS1302_HOUR 0x84
#define DS1302_WEEK 0x8A
#define DS1302_DAY 0x86
#define DS1302_MONTH 0x88
#define DS1302_YEAR 0x8C
void DS1302InputByte(unsigned char d) //实时时钟写入一字节(内部函数)
{
unsigned char i;
ACC = d;
for(i=8; i>0; i--)
{
if(ACC&0x01)
{
DS1302_IO = 1; //相当于汇编中的 RRC
}
else DS1302_IO = 0;
DS1302_CLK = 1;
DS1302_CLK = 0;
ACC = ACC >> 1;
}
}
unsigned char DS1302OutputByte(void) //实时时钟读取一字节(内部函数)
{
unsigned char i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; //相当于汇编中的 RRC
ACC7 = DS1302_IO;
DS1302_CLK = 1;
DS1302_CLK = 0;
}
return(ACC);
}
void Write1302(unsigned char ucAddr, unsigned char ucDa) //ucAddr: DS1302地址, ucData: 要写的数据
{
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(ucAddr); // 地址,命令
DS1302InputByte(ucDa); // 写1Byte数据
DS1302_CLK = 1;
DS1302_RST = 0;
}
unsigned char Read1302(unsigned char ucAddr) //读取DS1302某地址的数据
{
unsigned char ucData;
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(ucAddr|0x01); // 地址,命令
ucData = DS1302OutputByte(); // 读1Byte数据
DS1302_CLK = 1;
DS1302_RST = 0;
return(ucData);
}
void DS1302_GetTime(SYSTEMTIME *Time) //获取时钟芯片的时钟数据到自定义的结构型数组
{
unsigned char ReadValue;
ReadValue = Read1302(DS1302_SECOND);
Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_MINUTE);
Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_HOUR);
Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_DAY);
Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_WEEK);
Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_MONTH);
Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_YEAR);
Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
}
void YearToStr(SYSTEMTIME *Time) //将时间年,月,日,星期数据转换成显示字符串,放到数组里String[]
{
if(hide_year<2) //这里的if,else语句都是判断位闪烁,<2显示数据,>2就不显示
{
Time->YearString[0] = 'm';
Time->YearString[1] = '2';
Time->YearString[2] = '0';
Time->YearString[3] = Time->Year/10 + '0';
Time->YearString[4] = Time->Year%10 + '0';
}
else
{
Time->YearString[0] = 'm';
Time->YearString[1] = '2';
Time->YearString[2] = '0';
Time->YearString[3] = 'm';
Time->YearString[4] = 'm';
}
}
void DateToStr(SYSTEMTIME *Time)
{ if(hide_month<2)
{
Time->DateString[0] = Time->Month/10 + '0';
Time->DateString[1] = Time->Month%10 + '0';
}
else
{
Time->DateString[0] = 'm';
Time->DateString[1] = 'm';
}
Time->DateString[2] = '-';
if(hide_day<2)
{
Time->DateString[3] = Time->Day/10 + '0';
Time->DateString[4] = Time->Day%10 + '0';
}
else
{
Time->DateString[3] = 'm';
Time->DateString[4] = 'm';
}
}
void WeekToStr(SYSTEMTIME *Time)
{
if(hide_week<2)
{
week_value[0] = 'w';
week_value[1] = 'k';
week_value[2] = 'm';
week_value[3] = 'm';
week_value[4] = Time->Week%10 + '0'; //星期的数据另外放到 week_value[]数组里
}
else
{
week_value[0] = 'w';
week_value[1] = 'k';
week_value[2] = 'm';
week_value[3] = 'm';
week_value[4] = 'm';
}
}
void TimeToStr(SYSTEMTIME *Time) //将时,分数据转换成显示字符放到数组 TimeString[];
{ if(hide_hour<2)
{
Time->TimeString[0] = Time->Hour/10 + '0';
Time->TimeString[1] = Time->Hour%10 + '0';
}
else
{
Time->TimeString[0] = 'm';
Time->TimeString[1] = 'm';
}
Time->TimeString[2] = ':';
if(hide_min<2)
{
Time->TimeString[3] = Time->Minute/10 + '0';
Time->TimeString[4] = Time->Minute%10 + '0';
}
else
{
Time->TimeString[3] = 'm';
Time->TimeString[4] = 'm';
}
}
void naoToStr(void) //将时,分数据转换成显示字符放到数组 TimeString[];
{ if(hide_naoh<2)
{
naoString[0] = naoh/16+ '0';
naoString[1] = naoh%16+ '0';
}
else
{
naoString[0] = 'm';
naoString[1] = 'm';
}
naoString[2] = ':';
if(hide_naom<2)
{
naoString[3] = naom/16+ '0';
naoString[4] = naom%16+ '0';
}
else
{
naoString[3] = 'm';
naoString[4] = 'm';
}
}
void Initial_DS1302(void) //时钟芯片初始化
{
unsigned char Second=Read1302(DS1302_SECOND);
if(Second&0x80) //判断时钟芯片是否关闭
{
Write1302(0x8e,0x00); //写入允许
Write1302(0x8c,0x00); //以下写入初始化时间 日期:09/01/01.星期: 1. 时间: 01:00:00
Write1302(0x88,0x00);
Write1302(0x86,0x00);
Write1302(0x8a,0x00);
Write1302(0x84,0x00);
Write1302(0x82,0x00);
Write1302(0x80,0x00);
Write1302(0x8e,0x80); //禁止写入
}
}
/***********ds18b20子程序*************************/
void delay_18B20(unsigned int i) //ds18b20延迟子函数(晶振12MHz)
{
while(i--);
}
void Init_DS18B20(void) //ds18b20初始化函数
{
unsigned char x=0;
DQ = 1; //DQ复位
delay_18B20(8); //稍做延时
DQ = 0; //单片机将DQ拉低
delay_18B20(80); //精确延时 大于 480us
DQ = 1; //拉高总线
delay_18B20(14);
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay_18B20(20);
}
unsigned char ReadOneChar(void) //ds18b20读一个字节
{
uchar i=0;
uchar dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
delay_18B20(4);
}
return(dat);
}
void WriteOneChar(uchar dat) //ds18b20写一个字节
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay_18B20(5);
DQ = 1;
dat>>=1;
}
}
void ReadTemp(void) //读取ds18b20当前温
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -