⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 canlendar.c

📁 一个日历程序
💻 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 + -