#include "led.h"
#include "delay.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"
#include "rtc.h"
int main(void)
{
u8 t=0;
delay_init();
NVIC_Configuration();
位抢占优先级,2 位响应优先级
uart_init(9600);
LED_Init();
LCD_Init();
BEEP_Init();
//延时函数初始化
//设置 NVIC 中断分组 2:2
//串口初始化为 9600
//LED 端口初始化
//初始化蜂鸣器端口
//RTC 初始化
//设置字体为红色
//设置字体为蓝色
RTC_Init();
POINT_COLOR=GREEN;
LCD_ShowString(70,50,200,16,16,"^_^ andy ^_^");
POINT_COLOR=BLUE;
LCD_ShowString(60,130,200,16,16," - - ");
LCD_ShowString(60,162,200,16,16," : : ");
while(1)
{
if(t!=calendar.sec)
{
t=calendar.sec;
LCD_ShowNum(60,130,calendar.w_year,4,16);
LCD_ShowNum(100,130,calendar.w_month,2,16);
LCD_ShowNum(124,130,calendar.w_date,2,16);
switch(calendar.week)
{
case 0:
LCD_ShowString(60,148,200,16,16,"Sunday ");
break;
case 1:
LCD_ShowString(60,148,200,16,16,"Monday ");
break;
case 2:
LCD_ShowString(60,148,200,16,16,"Tuesday ");
break;
case 3:
LCD_ShowString(60,148,200,16,16,"Wednesday");
break;
case 4:
LCD_ShowString(60,148,200,16,16,"Thursday ");
break;
case 5:
LCD_ShowString(60,148,200,16,16,"Friday ");
break;
case 6:
LCD_ShowString(60,148,200,16,16,"Saturday ");
break;
}
LCD_ShowNum(60,162,calendar.hour,2,16);
LCD_ShowNum(84,162,calendar.min,2,16);
LCD_ShowNum(108,162,calendar.sec,2,16);
LED0=!LED0;
}
delay_ms(10);
}
}
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "rtc.h"
_calendar_obj calendar;//时钟结构体
static void RTC_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级 1 位,从优先
//RTC 全局中断
级 3 位
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//先占优先级 0 位,从优先级 4 位
//使能该通道中断
//根据 NVIC_InitStruct 中指定的参数初始化外
设 NVIC 寄存器
}
u8 RTC_Init(void)
{
//检查是不是第一次配置时钟
u8 temp=0;
u32 flag=0;
if (BKP_ReadBackupRegister(BKP_DR1) != 0x5050)
数据:读出了与写入的指定数据不相乎
{
//从指定的后备寄存器中读出
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR
| RCC_APB1Periph_BKP,
ENABLE);
//使能 PWR 和 BKP 外设时钟
PWR_BackupAccessCmd(ENABLE);
BKP_DeInit();//复位备份区域
RCC_LSEConfig(RCC_LSE_ON);
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
//使能后备寄存器访问
//设置外部低速晶振(LSE),使用外设低速晶振
// 检 查 指 定 的
RCC 标志位设置与否,等待低速晶振就绪
{
temp++;
delay_ms(10);
}
if(temp>=250)return 1;
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
//初始化时钟失败,晶振有问题
//设置 RTC 时钟(RTCCLK),
选择 LSE 作为 RTC 时钟
RCC_RTCCLKCmd(ENABLE);
RTC_WaitForLastTask();
的写操作完成
RTC_WaitForSynchro();
RTC_ITConfig(RTC_IT_SEC, ENABLE);
RTC_ITConfig(RTC_IT_ALR, ENABLE);
RTC_WaitForLastTask();
的写操作完成
RTC_EnterConfigMode();
RTC_SetPrescaler(32767);
RTC_WaitForLastTask();
的写操作完成
//使能 RTC 时钟
//等待最近一次对 RTC 寄存器
//等待 RTC 寄存器同步
//使能 RTC 秒中断
//等待最近一次对 RTC 寄存器
/// 允许配置
//设置 RTC 预分频的值
//等待最近一次对 RTC 寄存器
RTC_Set(2014,12,2,10,0,55);
RTC_ExitConfigMode();
flag=RTC_GetCounter();
RTC_WaitForLastTask();
RTC_SetAlarm(flag+1);
BKP_WriteBackupRegister(BKP_DR1, 0X5050);
//设置时间
//退出配置模式
//每秒钟闹一次
//向指定的后备寄存器中写入
用户程序数据
}
else
{
//系统继续计时
RTC_WaitForSynchro();
//等待最近一次对 RTC 寄存器的写
操作完成
RTC_ITConfig(RTC_IT_SEC, ENABLE);
RTC_ITConfig(RTC_IT_ALR, ENABLE);
RTC_WaitForLastTask();
//使能 RTC 秒中断
//等待最近一次对 RTC 寄存器
的写操作完成
}
RTC_NVIC_Config();
RTC_Get();
return 0;
}
void RTC_IRQHandler(void)
{
//RCT 中断分组设置
//更新时间
//ok
u32 flag=0;
if (RTC_GetITStatus(RTC_IT_SEC) != RESET)
{
RTC_Get();
}
if(RTC_GetITStatus(RTC_IT_ALR)!= RESET)
{
RTC_ClearITPendingBit(RTC_IT_ALR);
LED1=!LED1;
flag=RTC_GetCounter();
RTC_WaitForLastTask();
RTC_SetAlarm(flag+1);
//秒钟中断
//更新时间
//闹钟中断
//清闹钟中断
//绿色的 led 灯闪烁
//每秒钟闹一次
}
RTC_ClearITPendingBit(RTC_IT_SEC|RTC_IT_OW);
RTC_WaitForLastTask();
}
//判断是否是闰年函数
//月份 1 2 3 4 5 6 7 8 9 10 11 12
//闰年 31 29 31 30 31 30 31 31 30 31 30 31
//非闰年 31 28 31 30 31 30 31 31 30 31 30 31
//输入:年份
//输出:该年份是不是闰年.1,是.0,不是
u8 Is_Leap_Year(u16 year)
{
if(year%4==0)
{
if(year%100==0)
{
//清闹钟中断
//必须能被 4 整除
if(year%400==0)return 1;
//如果以 00 结尾,还要能被 400 整除
else return 0;
}else return 1;
}else return 0;
}
//设置时钟
//把输入的时钟转换为秒钟
//以 1970 年 1 月 1 日为基准
//1970~2099 年为合法年份
//返回值:0,成功;其他:错误代码.
//月份数据表
u8 const table_week[12]={0,3,3,6,1,4,6,2,5,0,3,5}; //月修正数据表
//平年的月份日期表
const u8 mon_table[12]={31,28,31,30,31,30,31,31,30,31,30,31};
u8 RTC_Set(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec)
{
u16 t;
u32 seccount=0;
if(syear<1970||syear>2099)return 1;
for(t=1970;t
u8 RTC_Get(void)
{
static u16 daycnt=0;
u32 timecount=0;
u32 temp=0;
u16 temp1=0;
timecount=RTC_GetCounter();
temp=timecount/86400;
if(daycnt!=temp)
{
daycnt=temp;
temp1=1970;
while(temp>=365)
{
//得到天数(秒钟数对应的)
//超过一天了
//从 1970 年开始
if(Is_Leap_Year(temp1))//是闰年
{
if(temp>=366)temp-=366;//闰年的秒钟数
else {temp1++;break;}
}
else temp-=365;
temp1++;
//平年
}
calendar.w_year=temp1;//得到年份
temp1=0;
while(temp>=28)//超过了一个月
{
if(Is_Leap_Year(calendar.w_year)&&temp1==1)//当年是不是闰年/2 月份
{
if(temp>=29)temp-=29;//闰年的秒钟数
else break;
}
else
{
if(temp>=mon_table[temp1])temp-=mon_table[temp1];//平年
else break;
}
temp1++;
}
calendar.w_month=temp1+1; //得到月份
//得到日期
calendar.w_date=temp+1;
}
temp=timecount%86400;
calendar.hour=temp/3600;
calendar.min=(temp%3600)/60;
//得到秒钟数
//小时
//分钟
calendar.sec=(temp%3600)%60;
calendar.week=RTC_Get_Week(calendar.w_year,calendar.w_month,calendar.w_date);// 获 取
//秒钟
星期
return 0;
}
//获得现在是星期几
//功能描述:输入公历日期得到星期(只允许 1901-2099 年)
//输入参数:公历年月日
//返回值:星期号
u8 RTC_Get_Week(u16 year,u8 month,u8 day)
{
u16 temp2;
u8 yearH,yearL;
yearL=year%100;
yearH=year/100;
// 如果为 21 世纪,年份数加 100
if (yearH>19)yearL+=100;
// 所过闰年数只算 1900 年之后的
temp2=yearL+yearL/4;
temp2=temp2%7;
temp2=temp2+day+table_week[month-1];
if (yearL%4==0&&month<3)temp2--;
return(temp2%7);
}
#include "led.h"
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE,
ENABLE);
//使能 PB,PE 端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIOB.5
GPIO_SetBits(GPIOB,GPIO_Pin_5);
//LED0-->PB.5 端口配置
//推挽输出
//IO 口速度为 50MHz
// 根 据 设 定 参 数 初 始 化
//PB.5 输出高
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
//LED1-->PE.5 端口 配置 , 推
挽输出
GPIO_Init(GPIOE, &GPIO_InitStructure);
50MHz
GPIO_SetBits(GPIOE,GPIO_Pin_5);
}
// 推 挽 输 出 , IO 口 速 度 为
//PE.5 输出高