标题:
LCD12864和PCF8563 IIC总线(万年历)显示时间的单片机源码
[打印本页]
作者:
biaji
时间:
2018-6-3 13:58
标题:
LCD12864和PCF8563 IIC总线(万年历)显示时间的单片机源码
刚学51单片机IIC以及万年历的源码
下面直接放东西,就是个简单的万年历,请各位大神指教
0.png
(47.63 KB, 下载次数: 72)
下载附件
2018-6-4 02:48 上传
单片机源程序如下:
/*
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)
2018-6-3 13:57 上传
点击文件名下载附件
简单的万年历
下载积分: 黑币 -5
作者:
zxy2266
时间:
2020-3-1 12:35
PCF8563就是595的程序吧,我一直在找这个
作者:
chinarenxx
时间:
2020-3-28 16:44
刚好有个8583的时钟芯片,下载来试试看学习下。
作者:
maijinzhi
时间:
2020-3-28 22:18
刚好有个8583的时钟芯片,学习下。
作者:
2541959167
时间:
2020-12-7 16:06
刚好用到,感谢大佬
作者:
小强快跑
时间:
2022-2-18 03:39
硬件i2c oled pcf 8563
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1