#include<reg51.h>
#include "LCD1602.h"
#include "DS1302.h"
#define uchar unsigned char
#define uint unsigned int
sbit speaker=P2^4
bit key_flag1=0,key_flag2=0
SYSTEMTIME adjusted
uchar sec_add=0,min_add=0,hou_add=0,day_add=0,mon_add=0,yea_add=0
uchar data_alarm[7]={0}
/************键盘控制******************************/
int key_scan() //扫描是否有键按下
{ int i=0
uint temp
P1=0xf0
temp=P1
if(temp!=0xf0)
i=1
else
i=0
return i
}
uchar key_value() //确定按键的值
{
uint m=0,n=0,temp
uchar value
uchar v[4][3]={'2','1','0','5','4','3','8','7','6','b','a','9'}
P1=0xfe temp=P1if(temp!=0xfe)m=0
P1=0xfdtemp=P1 if(temp!=0xfd)m=1
P1=0xfbtemp=P1 if(temp!=0xfb)m=2
P1=0xf7temp=P1 if(temp!=0xf7)m=3
P1=0xeftemp=P1 if(temp!=0xef)n=0
P1=0xdftemp=P1 if(temp!=0xdf)n=1
P1=0xbftemp=P1 if(temp!=0xbf)n=2
value=v[m][n]
return value
}
/***************************设置闹铃函数*******************************/
void naoling(void)
{
uchar i=0,l=0,j
init1602()
while(key_flag2&&i<12)
if(key_scan()){j=key_value()write_data(j)if(i%2==0)data_alarm[l]=(j-'0')*10else {data_alarm[l]+=(j-'0')l++}i++delay(600)}
write_com(0x01)
}
uchar according(void)
{ uchar k
if(data_alarm[0]==adjusted.Year&&data_alarm[1]==adjusted.Month&&data_alarm[2]==adjusted.Day&&data_alarm[3]==adjusted.Hour&&data_alarm[4]==adjusted.Minute&&data_alarm[5]==adjusted.Second)
k=1
else k=0
return k
}
void speak(void)
{uint i=50
while(i)
{speaker=0
delay(1)
speaker=1
delay(1)
i--
}
}
void alarm(void)
{uint i=10
while(i)
{
speak()
delay(10)
i--
}
}
/**************************修改时间 *** 作********************************/
void reset(void)
{
sec_add=0
min_add=0
hou_add=0
day_add=0
mon_add=0
yea_add=0
}
void adjust(void)
{
if(key_scan()&&key_flag1)
switch(key_value())
{case '0':sec_add++break
case '1':min_add++break
case '2':hou_add++break
case '3':day_add++break
case '4':mon_add++break
case '5':yea_add++break
case 'b':reset()break
default: break
}
adjusted.Second+=sec_add
adjusted.Minute+=min_add
adjusted.Hour+=hou_add
adjusted.Day+=day_add
adjusted.Month+=mon_add
adjusted.Year+=yea_add
if(adjusted.Second>59) adjusted.Second=adjusted.Second%60
if(adjusted.Minute>59) adjusted.Minute=adjusted.Minute%60
if(adjusted.Hour>23) adjusted.Hour=adjusted.Hour%24
if(adjusted.Day>31) adjusted.Day=adjusted.Day%31
if(adjusted.Month>12) adjusted.Month=adjusted.Month%12
if(adjusted.Year>100) adjusted.Year=adjusted.Year%100
}
/**************************中断处理函数*********************************/
void changing(void) interrupt 0 using 0 //需要修改时间和日期,或者停止修改
{
if(key_flag1)key_flag1=0
else key_flag1=1
}
void alarming(void) interrupt 3 using 0 //需要设置闹铃或者停止设置
{
if(key_flag2)key_flag2=0
else key_flag2=1
}
/********************************主函数***********************************/
main()
{uint i
uchar *l
uchar p1[]="D:",p2[]="T:"
SYSTEMTIME T
EA=1
EX0=1
IT0=1
EA=1
EX1=1
IT1=1
init1602()
Initial_DS1302()
while(1)
{ write_com(0x80)
write_string(p1,2)
write_com(0xc0)
write_string(p2,2)
DS1302_GetTime(&T)
adjusted.Second=T.Second
adjusted.Minute=T.Minute
adjusted.Hour=T.Hour
adjusted.Week=T.Week
adjusted.Day=T.Day
adjusted.Month=T.Month
adjusted.Year=T.Year
for(i=0i<9i++)
{
adjusted.DateString[i]=T.DateString[i]
adjusted.TimeString[i]=T.TimeString[i]
}
adjust()
if(key_flag2)naoling()
if(according())alarm()
DateToStr(&adjusted)
TimeToStr(&adjusted)
write_com(0x82)
write_string(adjusted.DateString,8)
write_com(0xc2)
write_string(adjusted.TimeString,8)
delay(10)
}
(二)头文件1 显示模块 LCD1602.H
#ifndef LCD_CHAR_1602_2009_5_9
#define LCD_CHAR_1602_2009_5_9
#define uchar unsigned char
#define uint unsigned int
sbit lcdrs = P2^0
sbit lcdrw = P2^1
sbit lcden = P2^2
void delay(uint z)// 延时
{
uint x,y
for(x=zx>0x--)
for(y=110y>0y--)
}
void write_com(uchar com) // 写入指令数据到 lcd
{
lcdrw=0
lcdrs=0
P0=com
delay(5)
lcden=1
delay(5)
lcden=0
}
void write_data(uchar date) // 写入字符显示数据到 lcd
{
lcdrw=0
lcdrs=1
P0=date
delay(5)
lcden=1
delay(5)
lcden=0
}
void init1602() // 初始化设定
{
lcdrw=0
lcden=0
write_com(0x3C)
write_com(0x0c)
write_com(0x06)
write_com(0x01)
write_com(0x80)
}
void write_string(uchar *pp,uint n)
{
int i
for(i=0i<ni++)
write_data(pp[i])
}
#endif
(三)头文件2 时钟模块 DS1302.H
#ifndef _REAL_TIMER_DS1302_2009_5_20_
#define _REAL_TIMER_DS1302_2003_5_20_
sbit DS1302_CLK = P2^6 //实时时钟时钟线引脚
sbit DS1302_IO = P2^7 //实时时钟数据线引脚
sbit DS1302_RST = P2^5 //实时时钟复位线引脚
sbit ACC0 = ACC^0
sbit ACC7 = ACC^7
typedef struct SYSTEM_TIME
{
unsigned char Second
unsigned char Minute
unsigned char Hour
unsigned char Week
unsigned char Day
unsigned char Month
unsigned char Year
unsigned char DateString[9] //用这两个字符串来放置读取的时间
unsigned char TimeString[9]
}SYSTEMTIME//定义的时间类型
#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
#define DS1302_RAM(X) (0xC0+(X)*2)//用于计算 DS1302_RAM 地址的宏
/******内部指令**********/
void DS1302InputByte(unsigned char d) //实时时钟写入一字节(内部函数)
{
unsigned char i
ACC = d
for(i=8i>0i--)
{
DS1302_IO = ACC0
DS1302_CLK = 1
DS1302_CLK = 0
ACC = ACC >>1//因为在前面已经定义了ACC0 = ACC^0以便再次利用DS1302_IO = ACC0
}
}
unsigned char DS1302OutputByte(void) //实时时钟读取一字节(内部函数)
{
unsigned char i
for(i=8i>0i--)
{
ACC = ACC >>1
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_SetProtect(bit flag)//是否写保护
{
if(flag)
Write1302(0x8E,0x10)
else
Write1302(0x8E,0x00)
}
void DS1302_SetTime(unsigned char Address, unsigned char Value)// 设置时间函数
{
DS1302_SetProtect(0)
Write1302(Address, ((Value/10)<<4 | (Value%10))) //将十进制数转换为BCD码
}//在DS1302中的与日历、时钟相关的寄存器存放的数据必须为BCD码形式
void DS1302_GetTime(SYSTEMTIME *Time)
{
unsigned char ReadValue
ReadValue = Read1302(DS1302_SECOND)
Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)//将BCD码转换为十进制数
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)
}
unsigned char *DataToBCD(SYSTEMTIME *Time)
{
unsigned char D[8]
D[0]=Time->Second/10<<4+Time->Second%10
D[1]=Time->Minute/10<<4+Time->Minute%10
D[2]=Time->Hour/10<<4+Time->Hour%10
D[3]=Time->Day/10<<4+Time->Day%10
D[4]=Time->Month/10<<4+Time->Month%10
D[5]=Time->Week/10<<4+Time->Week%10
D[6]=Time->Year/10<<4+Time->Year%10
return D
}
void DateToStr(SYSTEMTIME *Time)
{
//将十进制数转换为液晶显示的ASCII值
Time->DateString[0] = Time->Year/10 + '0'
Time->DateString[1] = Time->Year%10 + '0'
Time->DateString[2] = '-'
Time->DateString[3] = Time->Month/10 + '0'
Time->DateString[4] = Time->Month%10 + '0'
Time->DateString[5] = '-'
Time->DateString[6] = Time->Day/10 + '0'
Time->DateString[7] = Time->Day%10 + '0'
Time->DateString[8] = '\0'
}
void TimeToStr(SYSTEMTIME *Time)
{
//将十进制数转换为液晶显示的ASCII值
Time->TimeString[0] = Time->Hour/10 + '0'
Time->TimeString[1] = Time->Hour%10 + '0'
Time->TimeString[2] = ':'
Time->TimeString[3] = Time->Minute/10 + '0'
Time->TimeString[4] = Time->Minute%10 + '0'
Time->TimeString[5] = ':'
Time->TimeString[6] = Time->Second/10 + '0'
Time->TimeString[7] = Time->Second%10 + '0'
Time->DateString[8] = '\0'
}
void Initial_DS1302(void)
{
unsigned char Second
Second=Read1302(DS1302_SECOND)
if(Second&0x80) //初始化时间
DS1302_SetTime(DS1302_SECOND,0)
}
void DS1302_TimeStop(bit flag) // 是否将时钟停止
{
unsigned char Data
Data=Read1302(DS1302_SECOND)
DS1302_SetProtect(0)
if(flag)
Write1302(DS1302_SECOND, Data|0x80)
else
Write1302(DS1302_SECOND, Data&0x7F)
}
#endif
【八】电子表、万年历系列[1]单片机公交车环境监测及时间显示系统
功能描述:
1、按键调时间
2、带备用电池(断电继续走时)
3、监测噪声和温湿度并实时显示
4、超过报警值蜂鸣器会响
☆已作出的实物优酷视频演示地址:
http://v.youku.com/v_show/id_XMTQ3OTMxMDUwMA==.html
[2]单片机语音报时电子表
功能描述:
1、按键调试设置闹钟
2、带备用电池(断电继续走时)
3、整点语音报时
☆已作出的实物优酷视频演示地址:
http://v.youku.com/v_show/id_XMTQ3OTMwMjM0OA==.html
[3]单片机红外遥控电子表语音报时语音播报温湿度
功能描述:
1、红外遥控调时间设定闹钟
2、带备用电池(断电继续走时)
3、整点语音报时语音播报温湿度
4、按键遥控语音报时语音播报温湿度
☆已作出的实物优酷视频演示地址:
http://v.youku.com/v_show/id_XMTQ3OTMxMTUyOA==.html
[4]单片机红外遥控电子表语音报时格林威治时间双显示
功能描述:
1、红外遥控调时间设定闹钟
2、带备用电池(断电继续走时)
3、整点语音报时语音播报温湿度
4、按键遥控语音报时语音播报温湿度
☆已作出的实物优酷视频演示地址:
http://v.youku.com/v_show/id_XMTQ3OTMxMTUyOA==.html
[5]单片机多功能万年历电子表系统节日提醒温湿度显示
功能描述:
1、按键调时间,设置闹钟
2、带备用电池(断电继续走时)
3、阳历、农历节日提醒;可显示上午、中午、晚上、午夜、深夜等时间段
4、温湿度实时显示(可替换其他传感器数据显示)
5、功能扩展:语音播报万年历、温湿度等。(此项功能为扩展功能,需要需补差价)
☆已作出的实物优酷视频演示地址:
http://v.youku.com/v_show/id_XMTU0MjI4OTExNg==.html
【二十】GPS授时定位系统系列
[1]GPS自动授时系统 语音报时/播报温湿度
实现功能:
1.可设置授时模式为自动授时和手动更新
2.可脱离GPS数据利用本地时钟芯片准确走时
3.可设置静音模式、整点报时和自动语音播报温湿度及其混合模式等四种语音工作模式
4.可以切换显示本地时间和温湿度数据和GPS卫星时间数据和定位数据
5.经过分析GPS数据,利用算法缩短了解析时间在秒级时间内就能获取到GPS时间数据(正常情况下,完成定位需要几分钟以上)
6.(亮点)利用算法自动计算星期参数和农历参数,程序内部算法输入任何阳历日期数据即可得到准确的星期数据和农历数据
7.利用12864串口工作模式,节省了8个IO
8.可根据需求进行功能定制
☆已作出的实物优酷视频演示地址:
http://v.youku.com/v_show/id_XMjUzMzcyNTkyOA==.html
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)