标题:
通过矩阵键盘修改STM32F103的RTC时间
[打印本页]
作者:
yw秃头了
时间:
2020-4-16 20:33
标题:
通过矩阵键盘修改STM32F103的RTC时间
思路:我想通过矩阵键盘修改RTC时间,通过矩阵键盘输入一串字符串到数组里面,然后通过数组的值对RTC进行修改,但是数组里面有数据RTC却无法修改时间为什么?
void set_time() //设置时间
{
unsigned char n=0;
int m;
for(;;)
{
OLED_Clear(0);
OLED_Display_Flont(0+16*2,0,flont_shijian[0]);
OLED_Display_Flont(0+16*3,0,flont_shijian[1]);
OLED_Display_Flont(0+16*4,0,flont_shijian[2]);
OLED_Display_Flont(0+16*5,0,flont_shijian[3]);
OLED_Display_Flont(0+16*1,2,flont_shijian[4]);
OLED_Display_Flont(0+16*2,2,flont_shijian[5]);
OLED_Display_Flont(0+16*3,2,flont_shijian[6]);
OLED_Display_Flont(0+16*4,2,flont_shijian[7]);
OLED_Display_Flont(0+16*5,2,flont_shijian[8]);
OLED_Display_Flont(0+16*6,2,flont_shijian[9]);
for(;;)
{
key=Key_Scan();//检测按键
if(key>=0&&key<=9)
{
sjxg_time[n]=key;
printf("%d\n",sjxg_time[n]);
OLED_DisplayString(0+8*n,48,16,&sjxg_time[n]);
OLED_Refresh_GRAM();
OLED_Clear_GRAM();
n++;
}
if(key=='*')
{
yuanshi();
break;
}
if(key=='#')
{
rtc_time.year=(sjxg_time[0]-'0')*1000 +(sjxg_time[1]-'0')*100+(sjxg_time[2]-'0')*10+(sjxg_time[3]-'0');
rtc_time.mon=(sjxg_time[4]-'0')*10+(sjxg_time[5]-'0');
rtc_time.day=(sjxg_time[6]-'0')*10+(sjxg_time[6]-'0');
rtc_time.hour=(sjxg_time[8]-'0')*10+(sjxg_time[9]-'0');
rtc_time.min=(sjxg_time[10]-'0')*10+(sjxg_time[11]-'0');
rtc_time.sec=(sjxg_time[12]-'0')*10+(sjxg_time[13]-'0');
SET_RTC_TIME(rtc_time.year,rtc_time.mon,rtc_time.day,rtc_time.hour,rtc_time.min,rtc_time.sec);
memset(sjxg_time,0,sizeof(sjxg_time));
break;
}
}
break;
}
}
void RTC_IRQHandler(void)
{
u32 time;
if(RTC->CRL & 1<<0)//秒中断标志
{
time=RTC->CNTL; //获取低位
time|=RTC->CNTH<<16; //获取高位
GET_RTC_TIME(time);
// printf("%d-%d-%d %d:%d:%d\r\n",rtc_time.year,rtc_time.mon,rtc_time.day,rtc_time.hour,rtc_time.min,rtc_time.sec);
yuanshi();
}
if(RTC->CRL & 1<<1)//闹钟中断标志
{
printf("闹钟到达\r\n");
}
RTC->CRL&=~(0X3<<0);//清除中断标志位
RTC_WaitForLastTask();
}
void yuanshi(void)
{
char str[50];
sprintf(str,"%d-%d-%d %d:%d:%d",rtc_time.year,rtc_time.mon,rtc_time.day,rtc_time.hour,rtc_time.min,rtc_time.sec);
OLED_DisplayString(0,48,16,(u8*)str);
OLED_Refresh_GRAM();
OLED_Clear_GRAM();
OLED_Display_Flont(0+16*0,0,flont_chu1[0]); //您好
OLED_Display_Flont(0+16*1,0,flont_chu1[1]);
OLED_Display_Flont(0+16*3,2,flont_chu2[0]); //请打卡!
OLED_Display_Flont(0+16*4,2,flont_chu2[1]);
OLED_Display_Flont(0+16*5,2,flont_chu2[2]);
OLED_Display_Flont(0+16*6,2,flont_chu2[3]);
}
//返回值 0代表平年 1代表闰年
u8 GET_TIME_STATE(u32 year)
{
if((year % 4 ==0 && year % 100!=0) || year %400 ==0 )return 1;
else return 0;
}
u8 mon_r[12]={31,29,31,30,31,30,31,31,30,31,30,31};
u8 mon_p[12]={31,28,31,30,31,30,31,31,30,31,30,31};
//年月日转秒
void SET_RTC_TIME(u32 year ,u32 mon,u32 day,u32 hour,u32 min,u32 sec)
{
u32 i;
u32 rtc_sec=0;
for(i=2020;i<year;i++)
{
if(GET_TIME_STATE(i))
{
rtc_sec+=366*24*60*60;
}
else
{
rtc_sec+=365*24*60*60;
}
}
for(i=0;i<mon-1;i++)
{
if(GET_TIME_STATE(year))
{
rtc_sec+=mon_r[i]*24*60*60;
}
else
{
rtc_sec+=mon_p[i]*24*60*60;
}
}
rtc_sec+=(day-1)*24*60*60;
rtc_sec+=hour*60*60;
rtc_sec+=min*60;
rtc_sec+=sec;
RCC->APB1ENR|=1<<28;//电源接口时钟使能
RCC->APB1ENR|=1<<27;//备份域接口时钟使能
PWR->CR|=1<<8;//允许对备份域和RTC的写入
while(!(RTC->CRL& 1<<5)){}//等待RTC操作完成
RTC->CRL|=1<<4;//进入配置模式
RTC->CNTH=rtc_sec>>16;
RTC->CNTL=rtc_sec&0xFFFF;//计数值清0
RTC->CRL&=~(1<<4);//退出配置模式
while(!(RTC->CRL& 1<<5)){}//等待RTC操作完成
}
//秒转年月日
void GET_RTC_TIME(u32 sec)
{
u32 i=0;
rtc_time.year=2020;
rtc_time.mon=1;
rtc_time.day=1;
rtc_time.hour=0;
rtc_time.min=0;
rtc_time.sec=0;
while(1)
{
if(GET_TIME_STATE(rtc_time.year))
{
if(sec>=366*24*60*60)
{
sec-=366*24*60*60;
rtc_time.year++;
}
else break;
}
else
{
if(sec>=365*24*60*60)
{
sec-=365*24*60*60;
rtc_time.year++;
}
else break;
}
}
for(i=0;i<12;i++)
{
if(GET_TIME_STATE(rtc_time.year))
{
if(sec>=mon_r[i]*24*60*60)
{
sec-=mon_r[i]*24*60*60;
rtc_time.mon++;
}
else break;
}
else
{
if(sec>=mon_p[i]*24*60*60)
{
sec-=mon_p[i]*24*60*60;
rtc_time.mon++;
}
else break;
}
}
while(1)
{
if(sec>=24*60*60)
{
sec-=24*60*60;
rtc_time.day++;
}
else break;
}
while(1)
{
if(sec>=60*60)
{
sec-=60*60;
rtc_time.hour++;
}
else break;
}
while(1)
{
if(sec>=60)
{
sec-=60;
rtc_time.min++;
}
else break;
}
rtc_time.sec=sec;
}
复制代码
作者:
我未曾来过
时间:
2020-4-16 23:12
你的代码没什么注释就看的很吃力,我觉得有可能是你中断处理的问题,进入中断服务函数后先关中断,然后才执行操作,不然有可能让中断重复触发导致具体操作没能达到预期(当然也可能不是这个问题),我只是给楼主一个可能的方向
作者:
yw秃头了
时间:
2020-4-17 10:13
我未曾来过 发表于 2020-4-16 23:12
你的代码没什么注释就看的很吃力,我觉得有可能是你中断处理的问题,进入中断服务函数后先关中断,然后才执 ...
我也在思考这个问题,因为我是通过OLED屏幕进行时间显示的,在RTC中断中一直刷新时间在屏幕上进行显示,但是我一按按键就出现一下时间修改界面(时间差不多5s左右),然后就又跳到时间中断里面一直刷新时间了,按键修改就没用,一直想不明白为什么
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1