//**************START*******************************************************************//
//Description :LCD时钟显示功能主程序
//FileName :main.c
//Author :.F.G Wang
//Date :2009/02/10
//CPU :PIC16F877A
//Function :以I2C总线方式向PCF8563芯片写入初值,以BCD码方式存储,读取转化成2位数字方式LCD显示
// 通过串口接收时间数据可以调整设定显示时间
//Compiler :ICD 2, MAPLAB IDE v8.10
//Version :V1.00A Build 2009/02/10
//**************END**********************************************************************//
//*=========================================================================================*/
//* Change Log: */
//* ----------------------------------------------------------------------------------- */
//* | Version | Date | By | Changes | */
//* |----------|----------|----------|--------------------------------------------------| */
//* | | | | | */
//* | | | | | */
//* |----------|----------|----------|--------------------------------------------------| */
//* | | | | | */
//* | | | | | */
//* |----------|----------|----------|--------------------------------------------------| */
//* | | | | | */
//* | | | | | */
//* | | | | | */
//* ----------------------------------------------------------------------------------- */
//*******************************************************************************************/
//****************************************文件包含***************************************
#include <pic.h>
//********************************宏定义*****************************************
#define uchar unsigned char
#define uint unsigned int
//****************************************外部函数声明**************************************
extern void ISendByte(uchar sla,uchar c); //I2C方式向一个器件地址发一个字节
extern uchar IRcvBytes(uchar sla,uchar count,uchar *buff); //I2C方式从器件地址接收连续字节
extern void delay(unsigned char dly); //延时函数,提供必要的延时
extern void LCMWriteCom(unsigned int uCom); //写命令函数
extern void LCMInit(void); //芯片初始化函数
extern void LCMWriteData(unsigned int uData); //写数据函数
//****************************************内部函数声明**************************************
void get_time(void);
void usart_ini(void);
//***************************************全局变量声明**************************************
unsigned char k,m,n=0; //定义循环变量
uchar time_ini[]={0x12,0x30,0x30}; //时间初始化数组,时/分/秒
uchar time_ini_dataup[]={0x00,0x00,':',0x00,0x00,':',0x00,0x00}; //时间初始化更新数组,字符格式输入
uchar time[3]; //实时时间数据存放数组
unsigned int time_display[6]; //待显示的6个时间数据:hhmmss
unsigned int time_display2[]={0x0110,0x0120,0x0138,0x0140,0x0158,0x0160}; //小时分钟秒之间以小数点间隔开
//****************************主函数*****************************************
int main(void)
{
delay(200);
delay(200);
delay(200);
delay(200);
delay(200);
INTCON=0x00; //关总中断
ADCON1=0x07; //单片机端口初始化,设置为数据IO口
PIE1=0; //PIE1的中断不使能
TRISA0=0; //RA0,RA1,RA2分配给LCD作CS,WR,DATA口使用
TRISA1=0; //RA3,RA5分配给时钟芯片PCF8563作SDA,SCL口使用
TRISA2=0;
//RA4口为ST触发电平,故不用
TRISA3=0;
TRISA5=0;
ISendByte(0x02,time_ini[2]); //写秒寄存器
ISendByte(0x03,time_ini[1]); //写分钟寄存器
ISendByte(0x04,time_ini[0]); //写小时寄存器
LCMInit();
usart_ini(); //串口通信初始化函数
GIE=1; //开放全局中断
PEIE=1; //使能外部中断
for(m=0;m<6;m++)
LCMWriteData(time_display2[m]);
while(1)
{
if(n==8) //判断接收8位数据完毕,hh:mm:ss
{
n=0;
time_ini[2]=(((time_ini_dataup[6]-'0')<<4)+(time_ini_dataup[7]-'0')); //2位接收到的字符数据组成BCD码数据
time_ini[1]=(((time_ini_dataup[3]-'0')<<4)+(time_ini_dataup[4]-'0'));
time_ini[0]=(((time_ini_dataup[0]-'0')<<4)+(time_ini_dataup[1]-'0'));
ISendByte(0x02,time_ini[2]); //重写秒寄存器
ISendByte(0x03,time_ini[1]); //重写分钟寄存器
ISendByte(0x04,time_ini[0]); //重写小时寄存器
RCIE=1; //关闭接收中断
}
IRcvBytes(0x02,0x03,time); //读分秒小时存入time数组中
get_time(); //将读出的分秒小时BCD数据转化成普通数据
for(k=0;k<6;k++)
{
switch(time_display[k])
{
case 0:
{
LCMWriteData(((k*2)<<4)+0x000b);LCMWriteData(((k*2+1)<<4)+0x0007);
} break;
case 1:
{
LCMWriteData(((k*2)<<4)+0x0000);LCMWriteData(((k*2+1)<<4)+0x0006);
} break;
case 2:
{
LCMWriteData(((k*2)<<4)+0x0000e);LCMWriteData(((k*2+1)<<4)+0x0005);
} break;
case 3:
{
LCMWriteData(((k*2)<<4)+0x000c);LCMWriteData(((k*2+1)<<4)+0x0007);
} break;
case 4:
{
LCMWriteData(((k*2)<<4)+0x0005);LCMWriteData(((k*2+1)<<4)+0x0006);
} break;
case 5:
{
LCMWriteData(((k*2)<<4)+0x000d);LCMWriteData(((k*2+1)<<4)+0x0003);
} break;
case 6:
{
LCMWriteData(((k*2)<<4)+0x000f);LCMWriteData(((k*2+1)<<4)+0x0003);
} break;
case 7:
{
LCMWriteData(((k*2)<<4)+0x0000);LCMWriteData(((k*2+1)<<4)+0x0007);
} break;
case 8:
{
LCMWriteData(((k*2)<<4)+0x000f);LCMWriteData(((k*2+1)<<4)+0x0007);
} break;
case 9:
{
LCMWriteData(((k*2)<<4)+0x000d);LCMWriteData(((k*2+1)<<4)+0x0007);
} break;
default:
{
LCMWriteData(((k*2)<<4)+0x000f);LCMWriteData(((k*2+1)<<4)+0x0001);
} break;
}
}
}
return 0;
}
/*********************************************************************
串口中断服务程序
函数名:interrupt usart()
功能:串口中断服务处理程序
*********************************************************************/
void interrupt usart(void)
{
if(RCIE&&RCIF) //判断是否为串口接收中断
{
time_ini_dataup[n++]=RCREG; //把接收到的数据存入时间初始化更新数组中
if(n==8)RCIE=0; //判断8位数据接收完毕,关接收使能中断
}
}
/********************************************************************
分秒小时数据转化函数
函数原型: void get_time(void);
功能: 将读出的存入在time数组中的分秒小时BCD数据转化成普通2进制格式
*********************************************************************/
void get_time(void)
{
time_display[0]=time[2]>>4;
time_display[1]=time[2]&0x0f;
time_display[2]=time[1]>>4;
time_display[3]=time[1]&0x0f;
time_display[4