源码地址:GitHub源码
前言
实验基于STM32F103开发板,Keil4。这里仅作为记录实验过程,代码上传至GitHub,尽量优化代码,本人小白,有不当之处请指教
实验目标
1.实现秒表功能: 分、秒和毫秒计时 按K1键开始计时 按K2键计录一个时间,再按继续记录下一时间,共可记录五个时间 按K3键停止计时 停止后,K2,K3可以前后翻看五个时间
2.实现万能历功能 能显示年、月、日 或 时、分、秒,通过按键切换显示内容 按键可以调整和设置日期和时间
功能分析
1、先进行系统时钟、延时函数、LED的初始化,然后配置按键外部中断,通过两个按键外部中断实现计时及终止计时功能。 时间的记录则用一个二维数组分别记录时、分、秒,根据题目要求显示。 2、万年历功能主要是通过三个按键KEY3控制切换,KEY2和KEY1分别对年、月、日、时、分、秒或加或减操作,需要对闰年进行判断。减操作仅影响当前操作的数,不影响其他的。如 day–,当month==0,执行month=12。【这里尚未对当前操作位做特殊操作,比如年份闪烁表示正在对其进行操作,之后补充】
关键代码
秒表
void TimerxInit(u16 arr
, u16 psc
)
{
RCC
->APB1ENR
|= 1<<1;
TIM3
->ARR
= arr
;
TIM3
->PSC
= psc
;
TIM3
->DIER
|= 1<<0;
TIM3
->CR1
|= 0x01;
MY_NVIC_Init(1, 3, TIM3_IRQChannel
, 2);
RCC
->APB2ENR
|=1<<4;
GPIOC
->CRL
&=0XFFFFF000;
GPIOC
->CRL
|=0X00000888;
Ex_NVIC_Config(GPIO_C
,0,FTIR
);
Ex_NVIC_Config(GPIO_C
,1,FTIR
);
Ex_NVIC_Config(GPIO_C
,2,FTIR
);
MY_NVIC_Init(0,2,EXTI0_IRQChannel
,2);
MY_NVIC_Init(2,2,EXTI2_IRQChannel
,2);
}
void EXTI2_IRQHandler(void){
delay_ms(10);
if(key1
==0){
key1
=1;
second
= 0;
minute
= 0;
hour
= 0;
while(1){
DisplayDigitalClock(hour
, minute
, second
);
delay_ms(10);
t
=KeyScan();
if(t
==2){
timeRec
[0][count
] = hour
;
timeRec
[1][count
] = minute
;
timeRec
[2][count
] = second
;
count
++;
actCount
= count
-1;
EXTI
->PR
=1<<1;
}
}
}
EXTI
->PR
=1<<2;
}
void EXTI0_IRQHandler(void){
delay_ms(10);
if(key3
==0){
while(1){
DisplayDigitalClock(hour
, minute
, second
);
t
=KeyScan();
if(t
==2){
while(1){
DisplayDigitalClock(timeRec
[0][count
], timeRec
[1][count
], timeRec
[2][count
]);
if(t
==2){
if(count
>0){
--count
;
}
EXTI
->PR
=1<<1;
}
if(t
==3){
if(count
<actCount
){
++count
;
}
EXTI
->PR
=1<<0;
}
t
=KeyScan();
}
}
}
}
EXTI
->PR
=1<<0;
}
万年历
int IsLeapYear(int year
){
if((year
%4 == 0 && year
%100 != 0) || year
%400 == 0){
return 1;
}
return 0;
}
void JudgeDay(){
int i
;
for(i
=0; i
<12; i
++){
if(i
==0||i
==2||i
==4||i
==6||i
==7||i
==9||i
==11){
if((day
>31)&&(curMonth
==i
)){
day
=1;
curMonth
++;
if(curMonth
==13){
curMonth
=1;
year
++;
}
}
}else if(i
==1){
if(day
>28&&(curMonth
==2)){
if(IsLeapYear(year
)==0){
day
=1;
curMonth
=3;
}
}
}else {
if((day
>30)&&(curMonth
==i
+1)){
day
=1;
curMonth
++;
}
}
}
}
void JudgeDay2(){
int i
;
if(day
==0){
for(i
=0; i
<12; i
++){
if(i
==0||i
==2||i
==4||i
==6||i
==7||i
==9||i
==11){
day
=31;
}else if(i
==1){
if(IsLeapYear(year
)==1){
day
=29;
}else {
day
=28;
}
}else {
day
=30;
}
}
}
}
void TIM3_IRQHandler( void )
{
if( TIM3
->SR
& 0x0001)
{
second
++;
if( second
>59 )
{
second
= 0;
minute
++;
if( minute
>59 )
{
minute
= 0;
hour
++;
if( hour
>23 )
{
hour
= 0;
day
++;
JudgeDay();
}
}
}
}
TIM3
->SR
&= ~(1<<0);
}
void EXTI0_IRQHandler(void){
u8 t
, cnt
= 0;
delay_ms(10);
if(key3
==0){
while(1){
t
= KeyScan();
if(t
==3){
cnt
++;
if(cnt
==7) break;
}
if(cnt
>3) DisplayDigitalClock2();
else DisplayCalendar(year
, curMonth
, day
);
if(t
==2){
if(cnt
==1) year
++;
else if(cnt
==2){
curMonth
++;
if(curMonth
==13){
curMonth
=1; year
++;
}
}else if(cnt
==3){
day
++; JudgeDay();
}else if(cnt
>3){
if(cnt
==4){
hour
++;
if( hour
>23 ){
hour
= 0;
day
++;
JudgeDay();
}
}else if(cnt
==5){
minute
++;
if( minute
>59 ){
minute
= 0;
hour
++;
if( hour
>23 ){
hour
= 0;
day
++;
JudgeDay();
}
}
}else if(cnt
==6){
second
++;
if( second
>59 ){
second
= 0; minute
++;
if( minute
>59 ) {
minute
= 0; hour
++;
if( hour
>23 ){
hour
= 0;
day
++;
JudgeDay();
}
}
}
}
}
}else if(t
==1){
if(cnt
==1) year
--;
else if(cnt
==2) {
curMonth
--;
if(curMonth
==0) {curMonth
=12;year
--;}
}else if(cnt
==3){
day
--;JudgeDay2();
}else if(cnt
>3){
if(cnt
==4){
if( hour
==0 ){hour
=23; }
else { hour
--;}
}else if(cnt
==5){
if( minute
==0 )minute
=59;
else minute
--;
}else if(cnt
==6){
if(second
==0){ second
=59;}
else { second
--; }
}
}
}
}
}
EXTI
->PR
=1<<0;
}