最近想用RTC实现一个类似电子表的功能,就是让显示在液晶上面的时间可以自动走动,并且能通过按键修改日期,不知道哪里出现问题了,改了半天也没有成功,已实现部分通过按键来修改时间的功能,把内部RTC得到时间赋值给我新建的结构体time里面时,按键功能就实现不了,而且这个时间不知道为什么走不了,还有就是他一按复位键,时间的秒就会加一,这是为什么?这下面是RTC的配置与秒中断函数;和主函数。u8 RTC_Init(void)
{
//检查是不是第一次配置时钟
u8 temp=0;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); //使能PWR和BKP外设时钟
PWR_BackupAccessCmd(ENABLE); //使能后备寄存器访问; 默认情况下是禁止访问后备区域,避免误操作
if (BKP_ReadBackupRegister(BKP_DR1) != 0x5050) //从指定的后备寄存器中读出数据:读出了与写入的指定数据不相乎
{
BKP_DeInit(); //复位备份区域
RCC_LSEConfig(RCC_LSE_ON); //设置外部低速晶振(LSE),使用外设低速晶振
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) //检查指定的RCC标志位设置与否,等待低速晶振就绪
{
temp++;
delay_ms(10);//使能外部低速振荡器,一般要先判断 RCC_BDCR 的 LSERDY位来确定低速振荡器已经就绪了
}//如果2.5s还没有准备就绪,则说明时钟初始化失败
if(temp>=250)
return 1; //初始化时钟失败,晶振有问题
//如果时钟初始化是没有问题的则执行以下代码
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);//设置RTC时钟(RTCCLK),选择LSE作为RTC时钟
RCC_RTCCLKCmd(ENABLE); //使能RTC时钟
//以上执行完之后则表示时钟已准备就绪
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
RTC_WaitForSynchro(); //等待RTC寄存器同步
RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能RTC秒中断
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
RTC_EnterConfigMode(); //允许配置
RTC_SetPrescaler(32767); //设置RTC预分频的值 32.768KHZ/(32767+1)=1HZ 也就是1s一个周期, 在这个RTC_SetPrescaler()函数里面其实已经有设置进入配置模式和退出配置模式 此时再次写是为了以防万一
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
RTC_Set(2017,5,29,20,35,55); //设置时间 当前时间 配置RTC_CNT寄存器
RTC_ExitConfigMode(); //退出配置模式
BKP_WriteBackupRegister(BKP_DR1, 0X5050);//向指定的后备寄存器中写入用户程序数据
}
else//系统继续计时
{
RTC_WaitForSynchro(); //等待最近一次对RTC寄存器的写操作完成
RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能RTC秒中断 使用过RTC寄存器
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
}
RTC_NVIC_Config();//RCT中断分组设置
RTC_Get(); //更新时间
return 0; //ok
}
//RTC时钟中断
//每秒触发一次
//extern u16 tcnt;
void RTC_IRQHandler(void)
{
if(RTC_GetITStatus(RTC_IT_SEC) != RESET)//秒钟中断
{
RTC_Get(); //更新时间
}
if(RTC_GetITStatus(RTC_IT_ALR)!= RESET) //闹钟中断
{
RTC_ClearITPendingBit(RTC_IT_ALR); //清闹钟中断
}
RTC_ClearITPendingBit(RTC_IT_SEC|RTC_IT_OW);//清闹钟中断
RTC_WaitForLastTask();
}
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "lcd.h"
#include "usmart.h"
#include "rtc.h"
#include "key.h"
_calendar_obj time;
int main(void)
{
u8 t;
u8 key;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
delay_init(); //延时函数初始化
uart_init(9600); //串口初始化为9600
LED_Init(); //初始化与LED连接的硬件接口
LCD_Init(); //初始化LCD
KEY_Init();
usmart_dev.init(72); //初始化USMART
POINT_COLOR=RED; //设置字体为红 {MOD}
LCD_ShowString(60,50,200,16,16,"Mini STM32");
LCD_ShowString(60,70,200,16,16,"RTC TEST");
LCD_ShowString(60,90,200,16,16,"ATOM@ALIENTEK");
LCD_ShowString(60,110,200,16,16,"2014/3/8");
while(RTC_Init()) //RTC初始化 ,一定要初始化成功
{
LCD_ShowString(60,130,200,16,16,"RTC ERROR! ");
delay_ms(800);
LCD_ShowString(60,130,200,16,16,"RTC Trying...");
}
//显示时间
POINT_COLOR=BLUE;//设置字体为蓝 {MOD}
LCD_ShowString(60,130,200,16,16," - - ");
LCD_ShowString(60,170,200,16,16," : : ");
time.w_year = 2013;
time.w_month = 12;
time.w_date = 24;
time.week = 2;
time.hour = 12;
time.min = 0;
time.sec = 0;
while(1)
{
time=calendar;
RTC_Set(time.w_year,time.w_month,time.w_date,time.hour,time.min,time.sec);
if(t!=calendar.sec)
{
t=calendar.sec;
LCD_ShowNum(60,130,time.w_year,4,16);
LCD_ShowNum(100,130,time.w_month,2,16);
LCD_ShowNum(124,130,time.w_date,2,16);
switch(calendar.week)
{
case 0:
LCD_ShowString(60,150,200,16,16,"Sunday ");
break;
case 1:
LCD_ShowString(60,150,200,16,16,"Monday ");
break;
case 2:
LCD_ShowString(60,150,200,16,16,"Tuesday ");
break;
case 3:
LCD_ShowString(60,150,200,16,16,"Wednesday");
break;
case 4:
LCD_ShowString(60,150,200,16,16,"Thursday ");
break;
case 5:
LCD_ShowString(60,150,200,16,16,"Friday ");
break;
case 6:
LCD_ShowString(60,150,200,16,16,"Saturday ");
break;
}
LCD_ShowNum(60,170,time.hour,2,16);
LCD_ShowNum(84,170,time.min,2,16);
LCD_ShowNum(108,170,time.sec,2,16);
delay_ms(10);
}
key=KEY_Scan(0);
switch(key)
{
case 1:
if(time.sec==0) time.sec=59;
else time.sec--;
RTC_Set(time.w_year,time.w_month,time.w_date,time.hour,time.min,time.sec);
LCD_ShowNum(108,170,time.sec,2,16);
break;
case 2:
if(time.min==0) time.min=59;
else time.min--;
RTC_Set(time.w_year,time.w_month,time.w_date,time.hour,time.min,time.sec);
LCD_ShowNum(84,170,time.min,2,16);
break;
case 3:
if(time.hour==0) time.hour=23;
else time.hour--;
RTC_Set(time.w_year,time.w_month,time.w_date,time.hour,time.min,time.sec);
LCD_ShowNum(60,170,time.hour,2,16);
break;
default:delay_ms(10);
}
}
}
一周热门 更多>