刚学51单片机IIC以及万年历的源码
下面直接放东西,就是个简单的万年历,请各位大神指教
单片机源程序如下:
- /*
- LCD12864和PCF8563显示时间 !!!
- 徐逸夫
- 2016-5-16 ~ 5-18
- */
- /* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序 */
- #include <STC15.H>
- #include <stdio.h>
- #include "GPIO.h"
- #include "12864.h"
- #include "LCD_draw.h"
- #include "IIC.h"
- #include "Infrared.h"
- sbit HC595_SER = P4^0; //pin 14 SER data input
- sbit HC595_LCLK = P5^4; //pin 12 RCLk store (latch) clock
- sbit HC595_SCLK = P4^3; //pin 11 SRCLK Shift data clock
- /************* 红外接收程序变量声明 **************/
- //sbit P_IR_RX = P3^6; //定义红外接收输入IO口
- u8 IR_SampleCnt; //采样计数
- u8 IR_BitCnt; //编码位数
- u8 IR_UserH; //用户码(地址)高字节
- u8 IR_UserL; //用户码(地址)低字节
- u8 IR_data; //数据原码
- u8 IR_DataShit; //数据移位
- bit P_IR_RX_temp; //Last sample
- bit B_IR_Sync; //已收到同步标志
- bit B_IR_Press; //安键动作发生
- u8 IR_code; //红外键码
- u16 UserCode; //用户码
- /*****************************************************/
- u8 week0[] = {"一"},week1[] = {"二"},week2[] = {"三"};
- u8 week3[] = {"四"},week4[] = {"五"},week5[] = {"六"},week6[] = {"天"}; //星期几的字符集
- u8 code num2char[] = {"0123456789"}; //数字转化为ASCII字符
- u8 Time_num[] = {"00-00-00"}; //时分秒的数字形式
- u8 YMD_num[] = {"00-00-00"}; //year,month,day的数字形式
- u16 msecond; //毫秒计数
- bit B_1ms; //1ms标志位
- struct POINT_CLOCK //结构体 RTC变量时分秒
- {
- u8 hour;
- u8 minute;
- u8 second;
- }RTC_Time,RTC_Time_Now;
- struct NUM_CLOCK //结构体 RTC变量year,month,day的扩充
- {
- u8 year;
- u8 month;
- u8 week;
- u8 day;
- }More_Time;
- void DisableHC595(void); //关闭595显示
- void ReadRTC(); //读取PCF8563的时间
- void WriteRTC(); //更改PCF8563的时间
- void init_ClockCirle(); //初始化表盘和刻度
- void Display_Pointer(struct POINT_CLOCK AA); //指针显示
- void Display_ThreePointer(); //指针式时钟显示
- void Display_Number(struct POINT_CLOCK AA,struct NUM_CLOCK BB); //右侧LCD数字显示
-
- void DisableHC595(void) //关闭595显示
- {
- u8 i;
- HC595_SER = 1;
- for(i=0; i<20; i++)
- {
- HC595_SCLK = 1;
- HC595_SCLK = 0;
- }
- HC595_LCLK = 1;
- HC595_LCLK = 0; //锁存输出数据
- HC595_LCLK = 1;
- HC595_LCLK = 0; //锁存输出数据
- }
- /********************** 读RTC函数 ************************/
- void ReadRTC(void)
- {
- u8 tmp[7];
- ReadNbyte(2, tmp, 7);
- RTC_Time_Now.second = ((tmp[0] >> 4) & 0x07) * 10 + (tmp[0] & 0x0f);
- RTC_Time_Now.minute = ((tmp[1] >> 4) & 0x07) * 10 + (tmp[1] & 0x0f);
- RTC_Time_Now.hour = ((tmp[2] >> 4) & 0x03) * 10 + (tmp[2] & 0x0f);
- More_Time.day = ((tmp[3] >> 4) & 0x03) * 10 + (tmp[3] & 0x0f);
- More_Time.week = ((tmp[4] >> 4) & 0x00) * 10 + (tmp[4] & 0x07);
- More_Time.month = ((tmp[5] >> 4) & 0x01) * 10 + (tmp[5] & 0x0f);
- More_Time.year = ((tmp[6] >> 4) & 0x0f) * 10 + (tmp[6] & 0x0f);
- }
- /********************** 写RTC函数 ************************/
- void WriteRTC()
- {
- u8 tmp[7];
- tmp[0] = ((RTC_Time_Now.second / 10) << 4) + (RTC_Time_Now.second % 10);
- tmp[1] = ((RTC_Time_Now.minute / 10) << 4) + (RTC_Time_Now.minute % 10);
- tmp[2] = ((RTC_Time_Now.hour / 10) << 4) + (RTC_Time_Now.hour % 10);
- tmp[3] = ((More_Time.day / 10) << 4) + (More_Time.day % 10);
- tmp[4] = ((More_Time.week / 10) << 4) + (More_Time.week % 10);
- tmp[5] = ((More_Time.month / 10) << 4) + (More_Time.month % 10);
- tmp[6] = ((More_Time.year / 10) << 4) + (More_Time.year % 10);
- WriteNbyte(2, tmp, 7);
- }
- void init_ClockCirle() //初始化表盘
- {
- u8 i;
- draw_Circle(32,32,31,0);//画圆 圆心坐标(32,32) 半径31,空心圆
- for(i=0;i<60;i++)
- {
- if((i%5)==0) //画刻度
- {
- draw_Line(RTC_X(32,28,i),RTC_Y(32,28,i),RTC_X(32,30,i),RTC_Y(32,30,i));
- }
- }
- }
- /*========================================================================
- *name:Display_Pointer(struct POINT_CLOCK AA)
- *function:显示时、分、秒指针
- *参 数:结构体: 时分秒
- *注: 秒针长24 分针长17 秒针长12
- =========================================================================*/
- void Display_Pointer(struct POINT_CLOCK AA) //指针显示 ,作为Display_ThreePointer()的子函数
- {
- draw_Line(RTC_X(32,24,AA.second),RTC_Y(32,24,AA.second),32,32); //秒针
- draw_Line(RTC_X(32,17,AA.minute),RTC_Y(32,17,AA.minute),32,32); //分针
- draw_Line(RTC_X(32,12,AA.minute/12+5*(AA.hour%12)),RTC_Y(32,12,AA.minute/12+5*(AA.hour%12)),32,32); //时针
- }
- /*========================================================================
- *name:Display_ThreePointer(struct POINT_CLOCK AA,unsigned char color)
- *function:显示时、分、秒指针
- *参 数: 结构体0:存放上一个时分秒 两者不同时,刷新显示
- 结构体1:存放这一个时分秒
- =========================================================================*/
- void Display_ThreePointer() //左侧LCD指针式时钟显示
- {
- if(RTC_Time.second!=RTC_Time_Now.second) //秒刷新
- {
- dele_Line(RTC_X(32,24,RTC_Time.second),RTC_Y(32,24,RTC_Time.second),32,32);
- }
- if(RTC_Time.minute!=RTC_Time_Now.minute) //分刷新
- {
- dele_Line(RTC_X(32,17,RTC_Time.minute),RTC_Y(32,17,RTC_Time.minute),32,32);
- }
- if((RTC_Time.minute/12+5*(RTC_Time.hour%12))!=(RTC_Time_Now.minute/12+5*(RTC_Time_Now.hour%12))) //时刷新显示
- {
- dele_Line(RTC_X(32,12,RTC_Time.minute/12+5*(RTC_Time.hour%12)),RTC_Y(32,12,RTC_Time.minute/12+5*(RTC_Time.hour%12)),32,32);
- }
- Display_Pointer(RTC_Time_Now); //现在的指针式时钟显示
- RTC_Time=RTC_Time_Now;
- }
- void Display_Number(struct POINT_CLOCK AA,struct NUM_CLOCK BB) //右侧LCD数字显示
- {
- lcdwritecmd(0x30); //普通文本模式
- ReadRTC();
- Time_num[0]=num2char[AA.hour/10],Time_num[1]=num2char[AA.hour%10];
- Time_num[3]=num2char[AA.minute/10],Time_num[4]=num2char[AA.minute%10];
- Time_num[6]=num2char[AA.second/10],Time_num[7]=num2char[AA.second%10];
- lcdshowstr(4,2,Time_num); //时分秒的数字显示
- YMD_num[0]=num2char[BB.year/10],YMD_num[1]=num2char[BB.year%10];
- YMD_num[3]=num2char[BB.month/10],YMD_num[4]=num2char[BB.month%10];
- YMD_num[6]=num2char[BB.day/10],YMD_num[7]=num2char[BB.day%10];
- lcdshowstr(4,1,YMD_num); //年月日的数字显示
- lcdshowstr(4,3,"星期"); //星期几的显示
- switch (BB.week)
- {
- case 0:lcdshowstr(6,3,week0);break; case 1:lcdshowstr(6,3,week1);break; case 2:lcdshowstr(6,3,week2);break;
- case 3:lcdshowstr(6,3,week3);break; case 4:lcdshowstr(6,3,week4);break; case 5:lcdshowstr(6,3,week5);break;
- case 6:lcdshowstr(6,3,week6);break; default:lcdshowstr(6,3,"几");break;
- }
- }
- void AutoTime() //时间自动调整,分针时针的加减调整和进位
- {
- if (IR_code == 7||IR_code == 21||IR_code == 64||IR_code == 68)
- {
- if(IR_code == 7)
- {
- if(RTC_Time_Now.minute == 0)
- {
- RTC_Time_Now.minute = 59;
- if(RTC_Time_Now.hour == 0)
- {
- RTC_Time_Now.hour = 23;
- }else RTC_Time_Now.hour--;
- }else RTC_Time_Now.minute--;
- WriteRTC();IR_code=0;
- }
- if(IR_code == 21)
- {
- if(++RTC_Time_Now.minute >= 60)
- {
- RTC_Time_Now.minute = 0;
- if(++RTC_Time_Now.hour >= 24) RTC_Time_Now.hour = 0;
- }
- WriteRTC();IR_code=0;
- }
- if(IR_code == 64)
- {
- if(++RTC_Time_Now.hour >= 24)
- {
- RTC_Time_Now.hour = 0;
- }
- WriteRTC();IR_code=0;
- }
- if(IR_code == 68)
- {
- if(RTC_Time_Now.hour == 0)
- {
- RTC_Time_Now.hour = 23;
- }else RTC_Time_Now.hour--;
- WriteRTC();IR_code=0;
- }
- }
- }
- void Timer0Init(void) //1毫秒@11.0592MHz
- {
- AUXR |= 0x80; //定时器时钟1T模式
- TMOD &= 0xF0; //设置定时器模式
- TH0 = 0xFC;
- TL0 = 0xF6;
- ET0 = 1; //Timer0 interrupt enable
- TR0 = 1; //定时器0开始计时
- }
- void Interrupt_Timer0() interrupt 1
- {
- B_1ms = 1; //1ms扫描显示一位
- IR_RX_NEC(); //扫描红外遥控
- }
- void main()
- {
- bit error;
- GPIO();
- DisableHC595(); //禁止掉学习板上的HC595显示,省电
- Timer0Init();EA=1;
- lcdinit(); //初始化
- lcd_cls(); //清屏
- init_ClockCirle(); //画出表盘
- ReadRTC();
- error = 1; //初始化默认更改时间
- if(RTC_Time_Now.second >= 60) error = 1; //错误
- if(RTC_Time_Now.minute >= 60) error = 1; //错误
- if(RTC_Time_Now.hour >= 24) error = 1; //错误
- if(error) //有错误, 默认12:00:00
- {
- RTC_Time_Now.second = 58;RTC_Time_Now.minute = 59;RTC_Time_Now.hour = 22; //更改为2016-5-18
- More_Time.day = 18;More_Time.week = 2;More_Time.month = 5 ;More_Time.year = 16; // 22:59:58
- WriteRTC(); //写入时间到PCF8563
- }
- while(1)
- { //根据接收到的键值 对时间进行改变
- AutoTime();
- if(B_1ms) //1ms到
- {
- B_1ms = 0;
- if(B_IR_Press) //检测到收到红外键码
- {
- B_IR_Press = 0;
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
IIC以及万年历.zip
(106.44 KB, 下载次数: 129)
|