标题:
单片机12864时钟制作资料下载 代码注释详细
[打印本页]
作者:
liuzhen18
时间:
2017-5-28 00:57
标题:
单片机12864时钟制作资料下载 代码注释详细
12864时钟资料包(附件中可下载完整版的代码 而且注释非常详细):
0.png
(40.61 KB, 下载次数: 40)
下载附件
2017-5-28 17:26 上传
单片机源程序如下:
#include "Initial.h"
#include "ds1302.h"
#include "12864.h"
#include "IC.h"
#include "HongWai.h"
#include "Alarm.h"
/**********************************************************
函数名: Initial()
函数功能: 用于单片机开机后的第一次初始化
入口参数:无
出口参数:无
**********************************************************/
void Initial()
{
Initial_12864(); //12864的初始化
Write_12864_DS1302_Constant(); //写12864的固定部分
g_Alarm_min = Read_Add_24c02(1); //首次从24C02中读取数据 闹钟的时分
g_Alarm_hour = Read_Add_24c02(2);
Initial_IIC(); //24c02的初始化
Initial_HW_Time(); //初始化红外的定时器
g_Alarm_Flag1 = 0;
g_Alarm_Flag2 = 0;
g_HongWai_Work_Flag = 0;
g_Uart_Work_Flag = 0;
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
红外遥控部分:
/***************************************************************
文件说明:本文件主要处理红外因定时器与串口有重合
的部分,故定时器0中采用判断与标志位处理
在调用本模块时只需修改 Ir_work(void)
并在主函数中调用 IRR_Work()以便让整个C文件工作
**************************************************************/
#include "HongWai.h"
#include "Control.h"
#include "ds1302.h"
#include "12864.h"
#include "Initial.h"
#include "Uart.h"
#include "Alarm.h"
bit g_HongWai_Work_Flag; //红外是否工作标志位的标志位
uchar T0_Count; //T0的计数变量主要用于在串口工作时统计5s的时间
/**********************************************
以下是红外的变量
***********************************************/
uchar irtime;
bit irpro_ok,irok;
uchar IRcord[4];
uchar irdata[33];
/*********************************************
函数名: Initial_HW_Time()
函数功能: 初始化红外的定时器
入口参数: 无
出口参数: 无
备 注:
*********************************************/
void Initial_HW_Time()
{
/* 因与显示的频率有一定的冲突故将备份如下
TMOD = 0x12; //定时器0工作方式2,TH0是重装值,TL0是初值
TH0 = 0x00; //重载值
TL0 = 0x00; //初始化值
ET0 = 1; //开中断
TR0 = 1; //开定时器0
IT0 = 1; //指定外部中断0下降沿触发,INT0 (P3.2)
EX0 = 1; //使能外部中断
TH1 = 0x3c; //50ms 12MHZ晶振
TL1 = 0xB0;
ET1 = 1; //使能T1
TR1 = 1;
EA = 1; //开总中断
***************************************/
TMOD = 0x02; //定时器0工作方式2,TH0是重装值,TL0是初值
TH0 = 0x00; //重载值
TL0 = 0x00; //初始化值
ET0 = 1; //开中断
TR0 = 1; //开定时器0
IT0 = 1; //指定外部中断0下降沿触发,INT0 (P3.2)
EX0 = 1; //使能外部中断
EA = 1; //开总中断
}
/*********************************************
函数名: T0_Time(void) interrupt 1
函数功能: 定时器0中断处理
入口参数; 无
出口参数: 无
备 注: 因定时器处理与串口重叠
本函数利用标志位g_Uart_Work_Flag
把两者分开
*********************************************/
void T0_Time (void) interrupt 1 using 1
{
static Count_5S = 0;
if(g_Uart_Work_Flag == 0) //如果没有串口工作则计红外的时间
{
irtime++; //用于计数2个下降沿之间的时间
}
else //否则统计5s的时间
{
TH0 = 0x3c; //定时50ms 12M晶振
TL0 = 0xB0;
T0_Count ++;
if(T0_Count >= 20)
{
T0_Count = 0;
g_Run_Time_Uart_Flag = 1;
Count_5S ++;
if(Count_5S >= 5)
{
Count_5S = 0;
g_Send_Uart_Flag = 1;
}
}
}
}
/*******************************************
函数名: EX0_Ser(void) interrupt 0
函数功能: 外部中断0服务函数
入口参数: 无
出口参数: 无
********************************************/
void EX0_Ser(void) interrupt 0
{
static unsigned char i; //接收红外信号处理
static bit startflag; //是否开始处理标志位
if(startflag)
{
if(irtime < 65 &&irtime >= 33 )//引导码 TC9012的头码,9ms+4.5ms
{
i = 0;
}
irdata[i] = irtime;//存储每个电平的持续时间,用于以后判断是0还是1
irtime = 0;
i++;
if(i == 33)
{
irok = 1;
i = 0;
}
}
else
{
irtime = 0;
startflag = 1;
}
}
/****************************************************
函数名: Ir_work(void)
函数功能: 兼键值处理函数
入口参数: 无
出口参数: 无
备 注: 本函数主要用于处理按下遥控后的处理
处理操作标志位,是本文件中很核心的一个函数
*****************************************************/
void Ir_work(void)
{
switch(IRcord[2]) //判断第三个数码值
{
case 0x0c: //1 功能位置增加 显示相应的按键值
{
g_HongWai_Work_Flag = !g_HongWai_Work_Flag;//对红外的标志位进行取反
g_Alarm_Flag1 = 0; //对闹钟的两个标志位清零,让程序稳定
g_Alarm_Flag2 = 0;
g_Turn_Poem_Flag = 0;
Initial_12864(); //12864的初始化
if(g_HongWai_Work_Flag == 0)
{
Write_12864_DS1302_Constant(); //写12864的固定部分
}
}
/**********************************************************
case 0x18: DataPort = table[1]; break;//2
case 0x5e: DataPort = table[2]; break;//3
case 0x08: DataPort = table[3]; break;//4
case 0x1c: DataPort = table[4]; break;//5
case 0x5a: DataPort = table[5]; break;//6
case 0x42: DataPort = table[6]; break;//7
case 0x52: DataPort = table[7]; break;//8
case 0x4a: DataPort = table[8]; break;//9
case 0x0d: DataPort = table[9]; break;//200++
case 0x09: DataPort = table[0]; break;//EQ 显示相应的按键值
case 0x45: DataPort = 0x00; break;//CH-
case 0x46: DataPort = 0xff; break;//CH
case 0x47: DataPort = 0x00; break;//CH+
case 0x44: DataPort = 0xff; break;//后退
case 0x40: DataPort = 0x00; break;//前进
case 0x43: DataPort = 0x02; break;//暂停
case 0x07: DataPort = 0x00; break;//-
case 0x15: DataPort = 0xff; break;//+
case 0x16: DataPort = 0xff; break;//0
case 0x19: DataPort = 0xf0; break;//100+
default: break;
**************************************************************/
}
irpro_ok = 0; //处理完成标志
}
/***************************************************
函数名: Ircordpro(void)
函数功能: 红外码值处理函数 红外码值处理
入口参数: 无
出口参数: 无
备 注 :
****************************************************/
void Ircordpro(void)
{
uchar i, j, k;
uchar cord,value;
k = 1;
for(i = 0;i < 4;i++) //处理4个字节
{
for(j = 1;j <= 8;j++) //处理1个字节8位
{
cord = irdata[k];
if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差
{
value |= 0x80;
}
if(j<8)
{
value >>= 1;
}
k++;
}
IRcord[i] = value;
value = 0;
}
irpro_ok = 1; //处理完毕标志位置1
}
/******************************************************
函数名: IRR_Work(void)
函数功能: 调用整个c文件 以便让整个文件函数工作
入口参数: 无
出口参数: 无
备 注:
******************************************************/
void IRR_Work()
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
串口:
/***********************************************************
本文件主要用来写串口通信
注:统计5s时间的函数写在红外里面了
若调用本文件的定时器 定期写在最后 在工程中我把
定时器屏蔽掉
***********************************************************/
#include "Uart.h"
#include "ds1302.h"
#include "HongWai.h"
#include "12864.h"
#include "Alarm.h"
bit g_Recieve_Flag;
bit g_Run_Time_Uart_Flag; //串口调试的时候时间走动的时候标志位
bit g_Send_Uart_Flag; //串口发送给电脑的标志位
uchar Recieve_Time_Data; //接受的时间数据
uchar g_Num_Uart; //统计串口接收的次数
/*********************************************************
函数名: Initial_Uart()
函数功能:初始化串口
入口参数:无
出口参数:无
备 注: 12M晶振 600bps
*********************************************************/
void Initial_Uart() //初始化串口
{
TMOD = 0x21; //串行口通信时要把定时器打开,设置定时器工作方式
TH0 = (65536 - 45872) / 256;//装初值
TL0 = (65536 - 45872) % 256;
TH1 = 0xcc; //自动重装波特率为600bps 12M晶振
TL1 = 0x98;
TR1 = 1; //打开定时器1
ET0 = 1; //
SM0 = 0; //设置串行口工作方式1,要与TMOD相对应
SM1 = 1;
EA = 1; //打开总中断
ES = 1; //打开串行口中断
REN = 1; //允许串行口接受,当TMOD = 0x21时要在设置好SM0,SM1后再写
}
/****************************************************************
函数名称: Ser_Uart()
函数功能: 主要用于串口的中断服务
入口参数: 无
出口参数: 无
备 注: 进入计算机通信中断后设定标志位
*****************************************************************/
void Ser_Uart() interrupt 4
{
RI = 0;
Recieve_Time_Data = SBUF; //把接收的数据给时间标志位
if(Recieve_Time_Data == 'r')
{
g_Num_Uart = 0;
}
else
{
Recieve_Time_Data = Recieve_Time_Data - '0';
g_Num_Uart ++;
}
g_Recieve_Flag = 1; //串口服务的标志主要用于接收
}
/***********************************************************
函数名称: Uart_Process()
函数功能: 串口处理
入口参数: 无
出口参数: 无
备 注: 本函数主要通过处理g_Recieve_Flag g_Send_Uart_Flag
g_Run_Time_Uart_Flag来达到执行相应函数的目的
***********************************************************/
void Uart_Process()
{
if(g_Recieve_Flag == 1) //如果出现标志位置1 则进行接收的处理
{
g_Recieve_Flag = 0;
ES = 0;
TI = 1;
switch(g_Num_Uart) //通过判断串口发送的次数来进行相应的处理
{
case 1: break;
case 2: break;
case 3: g_year = Recieve_Time_Data * 10; break;
case 4: g_year = Recieve_Time_Data + g_year; break;
case 5: g_month = Recieve_Time_Data * 10; break;
case 6: g_month = Recieve_Time_Data + g_month; break;
case 7: g_date = Recieve_Time_Data * 10; break;
case 8: g_date = Recieve_Time_Data + g_date; break;
case 9: g_hour = Recieve_Time_Data * 10; break;
case 10: g_hour = Recieve_Time_Data + g_hour; break;
case 11: g_min = Recieve_Time_Data * 10; break;
case 12: g_min = Recieve_Time_Data + g_min; break;
case 13: g_sec = Recieve_Time_Data * 10; break;
case 14: //对数据进行最后一次处理并退出串口中断服务
{
g_sec = Recieve_Time_Data + g_sec;
Write_sfm(6,g_sec); //把调节的数据写在液晶屏上
Locate_pos(2,2); //显示位置重新回到调节处
g_Num_Uart = 0;
g_Uart_Work_Flag = 0; //串口工作的标志位清零退出串口工作
g_Set_DS1302_Num = 0;
Write_1302_Date (); //把数据写进DS1302
Write_12864_DS1302_Constant(); //把显示DS1302时间的固定部分写在液晶上
Initial_HW_Time (); //初始化红外的定时器
break;
}
default: //为了让程序稳定 对一些标志位继续处理
{
g_Num_Uart = 0;
g_Uart_Work_Flag = 0; //串口工作的标志位清零退出串口工作
g_Set_DS1302_Num = 0;
Write_1302_Date (); //把数据写进DS1302
Write_12864_DS1302_Constant(); //把显示DS1302时间的固定部分写在液晶上
Initial_HW_Time (); //初始化红外的定时器
}
}
if(g_Num_Uart >= 15) //增加程序的稳定性
{
g_Num_Uart = 0;
}
while(!TI);
TI = 0;
ES = 1;
}
if(g_Send_Uart_Flag == 1) //进行发送给电脑数据的处理 发送后DS1302便会更改
{
g_Send_Uart_Flag = 0;
ES = 0;
TI = 1;
printf("\n\n\n 现在时间是\n");
printf("\n 20%c%c年%c%c月%c%c日 %c%c时%c%c分%c%c秒\n",
g_year / 10 + '0', g_year % 10 + '0',
g_month / 10 + '0', g_month % 10 + '0',
g_date / 10 + '0', g_date % 10 + '0',
g_hour / 10 + '0', g_hour % 10 + '0',
g_min / 10 + '0', g_min % 10 + '0',
g_sec / 10 + '0', g_sec % 10 + '0');
while(!TI);
TI = 0;
ES = 1;
}
if(g_Run_Time_Uart_Flag == 1) //到达一秒的时间对DS1302的时间进行读取更新
{
g_Run_Time_Uart_Flag = 0;
Read_All_DS1302_Date(); //读取DS1302的所有数据
Display_DS1302_Time(); //把读取的数据显示在液晶上
}
}
/*******************************************************
函数名: T0_Time (void) interrupt 1 using 1
函数功能: 定时器0的中断处理
入口参数: 无
出口参数: 无
void T0_Time (void) interrupt 1 using 1
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
/*******************************************************
文件说明:本文件主要用来写DS1302与闹铃相应
的按键按下之后对相应的数值进行处理的函数
********************************************************/
#include "Control.h"
#include "Delay.h"
#include "ds1302.h"
#include "12864.h"
#include "IC.h"
#include "Alarm.h"
/**************************************************
函数名: Di()
函数功能: 制造蜂鸣器的声音
入口参数: 无
出口参数: 无
备 注:
*************************************************/
void Di()
{
uint i;
for(i = 1;i < 50; i ++)
{
beep = 0;
DelayUs2x(i * 10);
beep = 1;
DelayUs2x( ( 50 - i) * 5);
}
for(i = 1;i < 50; i++)
{
beep = 1;
DelayUs2x(i * 10);
beep = 0;
DelayUs2x( ( 50 - i) * 5);
}
}
/*************************************************
函数名: Locate_DS1302()
函数功能: 用于调整DS1302时间时 定位游标
与提示改变的项目
入口参数: 无
出口参数: 无
备 注:
*************************************************/
void Locate_DS1302()
{
Remind_DS1302_Exchange(g_Set_DS1302_Num); //提示DS1302改变的项目
switch(g_Set_DS1302_Num) //定位光标
{
case 1: Locate_pos(2,6); break; //第一次按下光标到秒位置
case 2: Locate_pos(2,4); break; //第二次按下光标到分钟位置
case 3: Locate_pos(2,2); break; //第三次按下光标到小时位置
case 4: Locate_pos(2,1); break; //第四次按下光标到星期位置
case 5: Locate_pos(1,6); break; //第五次按下光标到日位置
case 6: Locate_pos(1,4); break; //第六次按下光标到月位置
case 7: Locate_pos(1,2); break; //第七次按下光标到年位置
default: //返回界面并对标志位进行处理
{
g_Set_DS1302_Num = 0;
Initial_12864();
Initial_12864(); //初始化12864
Write_12864_DS1302_Constant(); //写12864固定的部分
Write_1302_Date(); //写入 存储数据
g_Alarm_Flag1 = 0;
g_Alarm_Flag2 = 0;
}
}
if(g_Set_DS1302_Num >= 8) //增加程序的稳定性
{
g_Set_DS1302_Num = 0;
}
}
/************************************************
函数名: Increase_DS1302()
函数功能: 用于处理调整DS1302的数值之时
对调整的项目进行数值增加
入口参数:无
出口参数:无
备 注:
************************************************/
void Increase_DS1302()
{
Remind_DS1302_Exchange(g_Set_DS1302_Num); //提示改变的项目
switch(g_Set_DS1302_Num)
{
case 1: //增大调整秒
{
g_sec ++;
if(g_sec >= 60) //到达一分钟的时间
{
g_sec = 0;
}
Write_sfm(6,g_sec); //把调节的数据写在液晶屏上
Locate_pos(2,6); //显示位置重新回到调节处
break;
}
case 2: //增大调整分钟
{
g_min ++;
if(g_min >= 60) //到达一小时的时间
{
g_min = 0;
}
Write_sfm(4,g_min); //把调节的数据写在液晶屏上
Locate_pos(2,4); //显示位置重新回到调节处
break;
}
case 3: //增大调整小时
{
g_hour ++;
if(g_hour >= 24)
{
g_hour = 0;
}
Write_sfm(2,g_hour); //把调节的数据写在液晶屏上
Locate_pos(2,2); //显示位置重新回到调节处
break;
}
case 4: //增大调整星期
{
g_week ++;
if(g_week >= 8)
{
g_week = 1;
}
Write_week(g_week); //把调节的数据写在液晶屏上
Locate_pos(2,1); //显示位置重新回到调节处
break;
}
case 5: //增大调整日期
{
g_date ++;
if(g_date >= 31)
{
g_date = 1;
g_month ++;
if(g_month >= 13)//到达一年的时间
{
g_month = 1;
g_year++;
if(g_year >= 20)
{
g_year = 9;
}
}
}
Write_nyr(6,g_date); //把调节的数据写在液晶屏上
Locate_pos(1,6); //显示位置重新回到调节处
break;
}
case 6: //增大调整月份
{
g_month ++;
if(g_month >= 12)
{
g_month = 1;
g_year ++;
if(g_year >= 20)
{
g_year = 9;
}
}
Write_nyr(4,g_month); //把调节的数据写在液晶屏上
Locate_pos(1,4); //显示位置重新回到调节处
break;
}
case 7: //增大调整年
{
g_year ++;
if(g_year >= 20)
{
g_year = 9;
}
Write_nyr(2,g_year); //把调节的数据写在液晶屏上
Locate_pos(1,2); //显示位置重新回到调节处
break;
}
}
}
/***********************************************
函数名: Decrease_DS1302()
函数功能: 用于处理调整DS1302的数值之时
对调整的项目进行数值减小
入口参数:无
出口参数:无
备 注:
/***********************************************/
void Decrease_DS1302()
{
switch(g_Set_DS1302_Num)
{
case 1: //减小调整秒
{
g_sec --;
if(g_sec <= 0)
{
g_sec = 59;
}
Write_sfm(6,g_sec); //把调节的数据写在液晶屏上
Locate_pos(2,6); //显示位置重新回到调节处
break;
}
case 2: //减小调整分钟
{
g_min --;
if(g_min <= 0)
{
g_min = 59;
}
Write_sfm(4,g_min); //把调节的数据写在液晶屏上
Locate_pos(2,4); //显示位置重新回到调节处
break;
}
case 3: //减小调整小时
{
g_hour --;
if(g_hour <= 0)
{
g_hour = 23;
}
Write_sfm(2,g_hour); //把调节的数据写在液晶屏上
Locate_pos(2,2); //显示位置重新回到调节处
break;
}
case 4: //减小调整星期
{
g_week --;
if(g_week <= 0)
{
g_week = 7;
}
Write_week(g_week); //把调节的数据写在液晶屏上
Locate_pos(2,1); //显示位置重新回到调节处
break;
}
case 5: //减小调整日期
{
g_date --;
if(g_date <= 0)
{
g_date = 31;
}
Write_nyr(6,g_date); //把调节的数据写在液晶屏上
Locate_pos(1,6); //显示位置重新回到调节处
break;
}
case 6: //减小调整月份
{
g_month --;
if(g_month <= 0)
{
g_month = 12;
g_year --;
if(g_year <= 8)
{
g_year = 20;
}
}
Write_nyr(4,g_month); //把调节的数据写在液晶屏上
Locate_pos(1,4); //显示位置重新回到调节处
break;
}
case 7: //减小调整年
{
g_year --;
if(g_year <= 8)
{
g_year = 20;
}
Write_nyr(2,g_year); //把调节的数据写在液晶屏上
Locate_pos(1,2); //显示位置重新回到调节处
break;
}
}
}
/************************************************
函数名: void Locate_A()
函数功能: 给变项目时对闹钟的调整项目进行提示
并定位改变的项目
入口参数:无
出口参数:无
备 注:
************************************************/
void Locate_A()
{
switch(g_Set_Alarm_Num)
{
case 1: Write_Remind_Alarm_Time(1); break; //设置分钟
case 2: Write_Remind_Alarm_Time(2); break; //定位小时
}
}
/************************************************
函数名: void A_Increase()
函数功能: 在调整闹铃的数值时对相应的时分
进行增加
入口参数: 无
出口参数: 无
备 注:
************************************************/
void A_Increase()
{
switch(g_Set_Alarm_Num)
{
case 1: //增加闹钟分钟的时间
{
g_Alarm_min ++;
if(g_Alarm_min >= 60)
{
g_Alarm_min = 0;
}
Write_Remind_Alarm_Time (1); //读取设置后的闹铃时间
Write_Add_24c02 (1,g_Alarm_min); //24C02存数据
break;
}
case 2: //增加闹钟小时的时间
{
g_Alarm_hour ++;
if(g_Alarm_hour >= 24)
{
g_Alarm_hour = 0;
}
Write_Remind_Alarm_Time (2); //读取设置后的闹铃时间
Write_Add_24c02 (2,g_Alarm_hour); //24C02存数据
break;
}
}
}
/************************************************
函数名: A_Decrease()
函数功能: 调整闹铃时对闹铃的小时与分钟进行
减小
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载(完整源码打包):
我的超级时钟.zip
(163.52 KB, 下载次数: 97)
2017-5-28 00:56 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
dragon19790000
时间:
2017-5-28 22:03
不错,值得学习!!!
作者:
wjwjwjwj
时间:
2017-6-16 08:13
好东西值得收藏
作者:
875427704
时间:
2019-1-6 10:00
12864是带字库的吗
作者:
原来如鸟
时间:
2019-1-6 15:43
这就是我一直想要找的,好东西啊
作者:
leezll
时间:
2019-10-11 06:15
不错,值得学习!!!
作者:
leezll
时间:
2019-10-11 06:32
没有电路图啊!!!
作者:
94情节
时间:
2019-10-11 14:09
代码很棒,值得学习,谢谢
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1