📄 canlendar.c
字号:
/****************************************Copyright (c)**************************************************
** 广州周立功单片机发展有限公司
** 研 究 所
** 产品一部
**
** http://www.zlgmcu.com
**
**--------------文件信息--------------------------------------------------------------------------------
**文 件 名: Canlendar.C
**创 建 人: 肖 志 刚
**最后修改日期: 2008-4-3
**描 述: 利用定时器做一个万年历,时间和日期都以"**-**-**"形式显示
** 利用PC机通过串口对万年历进行修改,修改时间的时间保存在E2PARM中
** S1键可切换时间和日期的显示,蜂鸣器未用.
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#include "config.h"
#define BEEPCON (1<<7)
#define CAT24WC02 0xA0
#define ZLG7290 0x70
volatile uint8 Year;
volatile uint8 Month;
volatile uint8 Day;
volatile uint8 Hour;
volatile uint8 Min;
volatile uint8 Sec;
volatile uint8 Array_Mon[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
volatile uint8 switch_flag;
volatile uint8 rcv_flag;
uint8 rcv_buf[12];
volatile uint32 num=0;
void __irq IRQ_TIME0(void);
void __irq IRQ_UART0(void);
/****************************************************************************
* 名称:Time0_Init()
* 功能:定时器0初始化。
****************************************************************************/
void Time0_Init(void)
{
T0PR = 99;
T0MR0 = Fpclk / 100;
T0MCR = 0x03;
T0TCR = 0x03;
T0TCR = 0x01;
VICIntSelect = 0x00000000;
VICVectCntl0 = (1<<5)|4;
VICVectAddr0 = (uint32)IRQ_TIME0;
}
/****************************************************************************
* 名称:I2C_Init()
* 功能:I2C初始化。
****************************************************************************/
void I2C_Init(uint32 fi2c)
{
if(fi2c>400000) fi2c = 400000;
I2SCLH = (Fpclk/fi2c + 1) / 2;
I2SCLL = (Fpclk/fi2c) / 2;
I2CONCLR = 0x2c;
I2CONSET = 0x40;
VICVectCntl1 = (1<<5)|9;
VICVectAddr1 = (int)IRQ_I2C;
}
/****************************************************************************
* 名称:UART0_Init()
* 功能:I2C初始化。
****************************************************************************/
void UART0_Init(void)
{
uint32 baud;
uint32 Fdiv;
baud = 115200;
U0LCR = 0x83;
Fdiv = (Fpclk / 16) / baud;
U0DLM = Fdiv / 256;
U0DLL = Fdiv % 256;
U0LCR = 0x03;
U0FCR = 0x81;
U0IER = 0x01;
VICVectCntl2 = (1<<5)|6;
VICVectAddr2 = (uint32)IRQ_UART0;
VICIntEnable = (1<<4)|(1<<6)|(1<<9);
}
/****************************************************************************
* 名称:Disp_Time()
* 功能:数码管显示时间。
****************************************************************************/
void Disp_Time(void)
{
ZLG7290_Download(0, 0, 0, Sec % 10);
ZLG7290_Download(0, 0, 1, Sec / 10);
ZLG7290_SegOnOff(0x16, 1);
ZLG7290_Download(0, 0, 3, Min % 10);
ZLG7290_Download(0, 0, 4, Min / 10);
ZLG7290_SegOnOff(0x2e, 1);
ZLG7290_Download(0, 0, 6, Hour % 10);
ZLG7290_Download(0, 0, 7, Hour / 10);
}
/****************************************************************************
* 名称:Disp_Day()
* 功能:数码管显示日期。
****************************************************************************/
void Disp_Day(void)
{
ZLG7290_Download(0, 0, 0, Day % 10);
ZLG7290_Download(0, 0, 1, Day / 10);
ZLG7290_SegOnOff(0x16, 1);
ZLG7290_Download(0, 0, 3, Month % 10);
ZLG7290_Download(0, 0, 4, Month / 10);
ZLG7290_SegOnOff(0x2e, 1);
ZLG7290_Download(0, 0, 6, Year % 10);
ZLG7290_Download(0, 0, 7, Year / 10);
}
/****************************************************************************
* 名称:Modify_Time()
* 功能:将接收到串口以"080403121000"形式发过来的数据进行修改。
****************************************************************************/
void Modify_Time(void)
{
Sec = ((rcv_buf[10] - 48) * 10) + (rcv_buf[11] - 48);
Min = ((rcv_buf[8] - 48) * 10) + (rcv_buf[9] - 48);
Hour = ((rcv_buf[6] - 48) * 10) + (rcv_buf[7] - 48);
Day = ((rcv_buf[4] - 48) * 10) + (rcv_buf[5] - 48);
Month = ((rcv_buf[2] - 48) * 10) + (rcv_buf[3] - 48);
Year = ((rcv_buf[0] - 48) * 10) + (rcv_buf[1] - 48);
num = 0;
}
/****************************************************************************
* 名称:Disp_Day()
* 功能:数码管显示日期。
****************************************************************************/
void Refresh_Time(void)
{
if(switch_flag == 1) Disp_Time();
if(switch_flag == 0) Disp_Day();
}
/****************************************************************************
* 名称:Del_Key()
* 功能:时间与日期切换处理。
****************************************************************************/
void Del_Key(void)
{
uint8 key = 0;
IRcvStr(ZLG7290, SubKey, &key, 1);
if(key == 1)
{
switch_flag |= 0xfe;
switch_flag = (~switch_flag);
}
}
void DelayNS(uint32 dly)
{ uint32 i;
for(; dly>0; dly--)
for(i=0; i<5000; i++);
}
void SendByte(uint8 data)
{
U0THR = data;
}
void SendBuf(void)
{
uint8 i = 0;
while(i < num)
{
SendByte(rcv_buf[i++]);
}
num = 0;
while ((U0LSR&0x20) == 0);
}
/****************************************************************************
* 名称:main()
* 功能:主控程序。
****************************************************************************/
int main(void)
{
uint8 key,i;
uint8 disp_buf[8];
key = 0;
switch_flag = 1;
PINSEL0 = 0x00000055;
PINSEL1 = 0x00000000;
IO0DIR = BEEPCON;
IO0SET = BEEPCON;
Time0_Init();
I2C_Init(30000);
UART0_Init();
for(i=0; i<8; i++) disp_buf[i] = 0x1f; //清屏
ZLG7290_SendBuf(disp_buf,8);
IRcvStr(CAT24WC02, 0x00, rcv_buf,12);
Modify_Time();
Disp_Time();
while(1)
{
if(rcv_flag == 1) //定时中断后显示数据刷新
{
rcv_flag = 0;
Refresh_Time();
}
if(rcv_flag == 2) //串口接收中断后时间修改与显示数据刷新
{
rcv_flag = 0;
SendBuf();
ISendStr(CAT24WC02, 0x00, rcv_buf,12);
Modify_Time();
Refresh_Time();
}
Del_Key();
DelayNS(2);
}
return(0);
}
/****************************************************************************
* 名称:IRQ_TIME0()
* 功能:定时器0中断。
****************************************************************************/
void __irq IRQ_TIME0(void)
{
if(++Sec ==60)
{
Sec = 0;
if(++Min == 60)
{
Min = 0;
if(++Hour == 24)
{
Hour = 0;
++Day;
if(((Year % 4) == 0) && (Month == 2))
{
if(Day > 29) Day =1;
}
else if(Day > Array_Mon[Month]) Day = 1;
if(Day == 1)
{
if(++Month == 13)
{
Month = 1;
if(++ Year == 100) Year = 0;
}
}
}
}
}
rcv_flag = 1;
T0IR = 0x01;
VICVectAddr = 0x00;
}
/****************************************************************************
* 名称:IRQ_UART0()
* 功能:串口UART0接收中断。
****************************************************************************/
void __irq IRQ_UART0(void)
{
uint8 i = 0;
switch(U0IIR&0x0f)
{ //发生RDA中断,读U0RBR中断复位
case 0x04:
for(i=0; i<8; i++)
rcv_buf[num++] = U0RBR;
rcv_flag = 2;
break;
//发生CTI中断,读U0RBR中断复位
case 0x0c:
while((U0LSR&0x01)==1)
{
rcv_buf[num++] = U0RBR;
}
rcv_flag = 2;
break;
default:
break;
}
VICVectAddr = 0x00;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -