stm32实现秒表及万年历

秒表
/普通按键初始化函数****

  • 通用定时器中断初始化

  • 这里时钟选择为APB1的2倍,而APB1为36M

  • arr:自动重装值。

  • psc:时钟预分频数

  • 这里使用的是定时器3!
    ******************************************************/
    void TimerxInit(u16 arr, u16 psc)
    {
    RCC->APB1ENR |= 1<<1; //TIM3时钟使能
    TIM3->ARR = arr; //设定计数器自动重装值,10为1ms
    TIM3->PSC = psc; //预分频器7200,得到10KHZ的计数时钟

    TIM3->DIER |= 1<<0; //允许更新中断
    TIM3->CR1 |= 0x01; //使能定时器3

    MY_NVIC_Init(1, 3, TIM3_IRQChannel, 2); //抢占1,子优先级3,组2

    RCC->APB2ENR|=1<<4; //使能PORTC时钟
    GPIOC->CRL&=0XFFFFF000;//PC0-2设置成输入
    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);//抢占2,子优先级2,组2
    MY_NVIC_Init(2,2,EXTI2_IRQChannel,2);//抢占2,子优先级1,组2
    }

void EXTI2_IRQHandler(void){
delay_ms(10);//消抖
if(key10){ //按键1
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++; // 记录时间个数+1
actCount = count-1; //actCount表示实际记录的时间个数
EXTI->PR=1<<1; //清除LINE1上的中断标志位
}
}
}
EXTI->PR=1<<2; //清除LINE2上的中断标志位
}

void EXTI0_IRQHandler(void){
delay_ms(10);//消抖
if(key30){ //按键3
while(1){
DisplayDigitalClock(hour, minute, second); //计时停在当前计时时间
t=KeyScan();
if(t
2){ //先翻看前一个记录时间
while(1){
DisplayDigitalClock(timeRec[0][count], timeRec[1][count], timeRec[2][count]);
if(t2){
if(count>0){ //判断记录下限
–count;
}
EXTI->PR=1<<1;//清除LINE1上的中断标志位
}
if(t
3){
if(count ++count;
}
EXTI->PR=1<<0;//清除LINE0上的中断标志位
}
t=KeyScan();
}
}
}
}
EXTI->PR=1<<0; //清除LINE0上的中断标志位
}

万年历
/// 注释部分为功能2【万年历】部分的代码
// 判断是否为闰年
int IsLeapYear(int year){
if((year%4 == 0 && year%100 != 0) || year %400 == 0){
return 1;
}
return 0;
}

// 对day++的合法性做判断
void JudgeDay(){
int i;
for(i=0; i<12; i++){
if(i0||i2||i4||i6||i7||i9||i11){ //31天的月份
if((day>31)&&(curMonth
i)){
day=1;
curMonth++;
if(curMonth13){
curMonth=1;
year++;
}
}
}else if(i
1){
if(day>28&&(curMonth==2)){ //2月
if(IsLeapYear(year)0){ //且不是闰年
day=1;
curMonth=3;
}
}
}else { // 30的月份
if((day>30)&&(curMonth
i+1)){
day=1;
curMonth++;
}
}
}
}

// 对day–的合法性的操作
void JudgeDay2(){
int i;
if(day0){
for(i=0; i<12; i++){
if(i
0||i2||i4||i6||i7||i9||i11){
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); //清除中断标志位
}

// 处理按键3切换时间和日期的终端函数
void EXTI0_IRQHandler(void){
u8 t , cnt = 0;
delay_ms(10);//消抖
if(key30){ //按键3
while(1){
t = KeyScan();
if(t
3){
cnt++;
if(cnt7) break;
}
if(cnt>3) DisplayDigitalClock2();
else DisplayCalendar(year, curMonth, day);
if(t
2){// 加操作
if(cnt1) year++;
else if(cnt
2){
curMonth++;
if(curMonth13){
curMonth=1; year++;
}
}else if(cnt
3){
day++; JudgeDay();
}else if(cnt>3){
if(cnt4){
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(cnt6){
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(cnt1) year–;
else if(cnt
2) {
curMonth–;
if(curMonth0) {curMonth=12;year–;}
}else if(cnt
3){
day–;JudgeDay2();
}else if(cnt>3){
if(cnt4){
if( hour
0 ){hour=23; }
else { hour–;}
}else if(cnt5){
if( minute
0 )minute=59;
else minute–;
}else if(cnt6){
if(second
0){ second=59;}
else { second–; }
}
}
}
}
}
EXTI->PR=1<<0; //清除LINE0上的中断标志位
}

你可能感兴趣的:(stm32)