一、如何用STM32F103内部RTC实现可调时钟万年历?
通常我们都是利用单片机驱动外设来实现可调时钟万年历的,但是如果手里没有相应的外设又想做一个可调时钟万年历怎么办,先不要着急,找一个STM32单片机我们利用其内部RTC就可以实现,是不是方便了好多呀。
int main(void)
{
u8 t=0;
u8 keynum;
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
LED_Init(); //LED端口初始化
LCD_Init();
BEEP_Init(); //初始化蜂鸣器IO
EXTIX_Init();
// usmart_dev.init(SystemCoreClock/1000000); //初始化USMART
// alarmclock.hour =17;
// alarmclock.min =43 ;
// alarmclock.sec =00;
RTC_Init(); //RTC初始化
POINT_COLOR=RED;//设置字体为红色
//LCD_ShowString(60,50,200,16,16,"Elite 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,"2021/2/14");
//显示时间
POINT_COLOR=BLUE;//设置字体为蓝色
LCD_ShowString(60,130,200,16,16," - - ");
LCD_ShowString(60,162,200,16,16," : : ");
while(1)
{
POINT_COLOR=BLUE;
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;
keynum = KEY_Scan(0);
if(keynum==1)//设置
{
BEEP=0;
main_Set();//时钟万年历调时函数
}
else if(keynum==3)//设置
{
BEEP=0;
alarm_Set();//调闹钟
}
else if(keynum==2) //关声音
{
BEEP=0;
}
}
delay_ms(10);
};
}
void main_Set()//时钟万年历调时函数
{
u8 keynum ,state=1;
LCD_ShowString(16,112,200,16,16,"Calendar Set:");//显示字符Calendar Set:可进行相应的时钟设置
LCD_ShowNum(108,162,calendar.sec,2,16);//定格到当前所在秒
while(1)
{
keynum = KEY_Scan(0);
if(keynum==1)
{
if(state>=6)
state=0;
else
state++;
switch(state)
{
case 0:
case 1: POINT_COLOR=RED;
LCD_ShowNum(108,162,calendar.sec,2,16);
break;//秒
case 2: POINT_COLOR=RED;
LCD_ShowNum(84,162,calendar.min,2,16);
break;//分
case 3: POINT_COLOR=RED;
LCD_ShowNum(60,162,calendar.hour,2,16);
break;//时
case 4: POINT_COLOR=RED;
LCD_ShowNum(124,130,calendar.w_date,2,16);
break;//日
case 5: POINT_COLOR=RED;
LCD_ShowNum(100,130,calendar.w_month,2,16);
break;//月
case 6: POINT_COLOR=RED;
LCD_ShowNum(60,130,calendar.w_year,4,16);
break;//年
default:break;
}
}
else if(keynum>1)
{
if(keynum==4)
{
}
if(state==1)//设置秒,我这里秒不作为可设置开放所以注释掉了
{
// if(keynum==3)
// calendar.sec++;
// else if(keynum==2)
// calendar.sec--;
// if(calendar.sec>=60)
// calendar.sec=0;
// else if(calendar.sec<0)
// calendar.sec=59;
// POINT_COLOR=BLUE;
// LCD_ShowNum(108,216,calendar.sec,2,16);
}
else if(state==2)//设置分
{
if(keynum==3)
calendar.min++;
else if(keynum==2)
calendar.min--;
if(calendar.min>=60)
calendar.min=0;
else if(calendar.min<=0)
calendar.min=59;
POINT_COLOR=BLUE;
LCD_ShowNum(84,162,calendar.min,2,16);
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
RTC_Set(calendar.w_year,calendar.w_month ,calendar.w_date ,calendar.hour ,calendar.min ,calendar.sec ); //设置时间
RTC_ExitConfigMode(); //退出配置模式
}
else if(state==3)//设置时
{
if(keynum==3)
calendar.hour++;
else if(keynum==2)
calendar.hour--;
if(calendar.hour>=24)
calendar.hour=0;
else if(calendar.hour<=0)
calendar.hour=23;
POINT_COLOR=BLUE;
LCD_ShowNum(60,162,calendar.hour,2,16);
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
RTC_Set(calendar.w_year,calendar.w_month ,calendar.w_date ,calendar.hour ,calendar.min ,calendar.sec ); //设置时间
RTC_ExitConfigMode(); //退出配置模式
}
// else if(state==4)//设置周,我这里周不作为可设置开放所以注释掉了
// {
// if(keynum==3)
// calendar.week++;
// else if(keynum==2)
// calendar.week--;
// if(calendar.week>=7)
// calendar.week=1;
// else if(calendar.week<=1)
// calendar.week=7;
// POINT_COLOR=BLUE;
// LCD_ShowNum(84,216,calendar.week,2,16);
// RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
// RTC_Set(calendar.w_year,calendar.w_month ,calendar.w_date ,calendar.hour ,calendar.min ,calendar.sec ); //设置时间
// RTC_ExitConfigMode(); //退出配置模式
// }
else if(state==4)//设置日
{
if(keynum==3)
calendar.w_date++;
else if(keynum==2)
calendar.w_date--;
if(calendar.w_date>=32)
calendar.w_date=1;
else if(calendar.w_date<=1)
calendar.w_date=31;
POINT_COLOR=BLUE;
LCD_ShowNum(124,130,calendar.w_date,2,16);
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
RTC_Set(calendar.w_year,calendar.w_month ,calendar.w_date ,calendar.hour ,calendar.min ,calendar.sec ); //设置时间
RTC_ExitConfigMode(); //退出配置模式
}
else if(state==5)//设置月
{
if(keynum==3)
calendar.w_month++;
else if(keynum==2)
calendar.w_month--;
if(calendar.w_month>12)
calendar.w_month=1;
else if(calendar.w_month<1)
calendar.w_month=12;
POINT_COLOR=BLUE;
LCD_ShowNum(100,130,calendar.w_month,2,16);
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
RTC_Set(calendar.w_year,calendar.w_month ,calendar.w_date ,calendar.hour ,calendar.min ,calendar.sec ); //设置时间
RTC_ExitConfigMode(); //退出配置模式
}
else if(state==6)//设置年,这里年只开放2000-2025年的设置
{
if(keynum==3)
calendar.w_year++;
else if(keynum==2)
calendar.w_year--;
if(calendar.w_year>2025)
calendar.w_year=2000;
else if(calendar.w_year<=2000)
calendar.w_year=2025;
POINT_COLOR=BLUE;
LCD_ShowNum(60,130,calendar.w_year,4,16);
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
RTC_Set(calendar.w_year,calendar.w_month ,calendar.w_date ,calendar.hour ,calendar.min ,calendar.sec ); //设置时间
RTC_ExitConfigMode(); //退出配置模式
}
else
{
break;//退出循环
}
}
if(state==0)
{
LCD_Clear(WHITE);//清屏
POINT_COLOR=BLUE;//字体变蓝
LCD_ShowString(60,130,200,16,16," - - ");
LCD_ShowString(60,162,200,16,16," : : ");
break;
}
}
}
void alarm_Set()//调闹铃函数
{
int Keynum,State=1;
LCD_ShowString(16,180,200,16,16,"AlarmClock:");
LCD_ShowString(60,198,200,16,16," - - ");
LCD_ShowString(60,216,200,16,16," : : ");
LCD_ShowNum(60,216,alarmclock.hour,2,16);
LCD_ShowNum(84,216,alarmclock.min,2,16);
LCD_ShowNum(108,216,alarmclock.sec,2,16);
LCD_ShowNum(60,198,alarmclock.w_year ,4,16);
LCD_ShowNum(100,198,alarmclock.w_month,2,16);
LCD_ShowNum(124,198,alarmclock.w_date,2,16);
POINT_COLOR=RED;
LCD_ShowNum(108,216,alarmclock.sec,2,16);
while(1)
{
Keynum = KEY_Scan(0);
if(Keynum==1)//设置
{
if(State>=6)
State=0;
else
State++;
switch(State)
{
case 0:
case 1: POINT_COLOR=RED;LCD_ShowNum(108,216,alarmclock.sec,2,16);break;//秒
case 2: POINT_COLOR=RED;LCD_ShowNum(84,216,alarmclock.min,2,16); break;//分
case 3: POINT_COLOR=RED;LCD_ShowNum(60,216,alarmclock.hour,2,16); break;//时
//case 4:
case 4: POINT_COLOR=RED;LCD_ShowNum(124,198,alarmclock.w_date,2,16); break;//日
case 5: POINT_COLOR=RED;LCD_ShowNum(100,198,alarmclock.w_month,2,16);break;//月
case 6: POINT_COLOR=RED;LCD_ShowNum(60,198,alarmclock.w_year,4,16); break;//年
default:break;
}
}
else if(Keynum>1)
{
if(Keynum==4)
{
}
if(State==1)//设置秒
{
if(Keynum==3)
alarmclock.sec++;
else if(Keynum==2)
alarmclock.sec--;
if(alarmclock.sec>=60)
alarmclock.sec=0;
else if(alarmclock.sec<0)
alarmclock.sec=59;
POINT_COLOR=BLUE;
LCD_ShowNum(108,216,alarmclock.sec,2,16);
RTC_Alarm_Set(alarmclock.w_year,alarmclock.w_month ,alarmclock.w_date ,alarmclock.hour ,alarmclock.min ,alarmclock.sec );
}
else if(State==2)//设置分
{
if(Keynum==3)
alarmclock.min++;
else if(Keynum==2)
alarmclock.min--;
if(alarmclock.min>=60)
alarmclock.min=0;
else if(alarmclock.min<=0)
alarmclock.min=59;
POINT_COLOR=BLUE;
LCD_ShowNum(84,216,alarmclock.min,2,16);
RTC_Alarm_Set(alarmclock.w_year,alarmclock.w_month ,alarmclock.w_date ,alarmclock.hour ,alarmclock.min ,alarmclock.sec ); //设置时间
}
else if(State==3)//设置时
{
if(Keynum==3)
alarmclock.hour++;
else if(Keynum==2)
alarmclock.hour--;
if(alarmclock.hour>=24)
alarmclock.hour=0;
else if(alarmclock.hour<=0)
alarmclock.hour=23;
POINT_COLOR=BLUE;
LCD_ShowNum(60,216,alarmclock.hour,2,16);
RTC_Alarm_Set(alarmclock.w_year,alarmclock.w_month ,alarmclock.w_date ,alarmclock.hour ,alarmclock.min ,alarmclock.sec );
}
// else if(state==4)//设置周
// {
// if(keynum==3)
// calendar.week++;
// else if(keynum==2)
// calendar.week--;
// if(calendar.week>=8)
// calendar.week=1;
// else if(calendar.week<=1)
// calendar.hour=7;
// POINT_COLOR=BLUE;
// LCD_ShowNum(84,216,calendar.week,2,16);
// RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
// RTC_Set(calendar.w_year,calendar.w_month ,calendar.w_date ,calendar.hour ,calendar.min ,calendar.sec ); //设置时间
// RTC_ExitConfigMode(); //退出配置模式
// }
else if(State==4)//设置日
{
if(Keynum==3)
alarmclock.w_date++;
else if(Keynum==2)
alarmclock.w_date--;
if(alarmclock.w_date>=32)
alarmclock.w_date=1;
else if(alarmclock.w_date<=1)
alarmclock.w_date=31;
POINT_COLOR=BLUE;
LCD_ShowNum(124,198,alarmclock.w_date,2,16);
RTC_Alarm_Set(alarmclock.w_year,alarmclock.w_month ,alarmclock.w_date ,alarmclock.hour ,alarmclock.min ,alarmclock.sec );
}
else if(State==5)//设置月
{
if(Keynum==3)
alarmclock.w_month++;
else if(Keynum==2)
alarmclock.w_month--;
if(calendar.w_month>=13)
alarmclock.w_month=1;
else if(calendar.w_month<1)
alarmclock.w_month=12;
POINT_COLOR=BLUE;
LCD_ShowNum(100,198,alarmclock.w_month,2,16);
RTC_Alarm_Set(alarmclock.w_year,alarmclock.w_month ,alarmclock.w_date ,alarmclock.hour ,alarmclock.min ,alarmclock.sec );
}
else if(State==6)//设置年
{
if(Keynum==3)
alarmclock.w_year++;
else if(Keynum==2)
alarmclock.w_year--;
if(alarmclock.w_year>2025)
alarmclock.w_year=2000;
else if(alarmclock.w_year<=2000)
alarmclock.w_year=2025;
POINT_COLOR=BLUE;
LCD_ShowNum(60,198,alarmclock.w_year,4,16);
RTC_Alarm_Set(alarmclock.w_year,alarmclock.w_month ,alarmclock.w_date ,alarmclock.hour ,alarmclock.min ,alarmclock.sec );
}
else
{
break;//退出循环
}
}
if(State==0)
{
LCD_Clear(WHITE);//清屏
POINT_COLOR=BLUE;//字体变蓝
LCD_ShowString(60,130,200,16,16," - - ");
LCD_ShowString(60,162,200,16,16," : : ");
break;
}
}
}
以上就是今天分享的内容,本文仅仅简单介绍了STM32如何实现可调万年历的方法及主要程序的思想,由于时间的原因,日后再行完善哈哈哈。