野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 20534|回复: 4

做数字钟的时候遇到了问题

[复制链接]
发表于 2019-7-16 11:35:24 | 显示全部楼层 |阅读模式
本帖最后由 Garfield 于 2019-7-16 11:35 编辑

7月1刚跟着学校老师学了下32  然后布置了一个数字钟的任务。然后做着做着发现了些问题。可能代码有点长,还是希望有大佬救救我这个小萌新。先放原本代码   问题在代码之后。
=======================================main函数中================================================================================================

#include "stm32f10x.h"
#include "gpio.h"
#include "exti.h"
#include "tim.h"
#include "usart.h"
#include "bsp_ili9341_lcd.h"
#include <stdio.h>
#include <string.h>
#define PI 3.141592
#include <math.h>

void RCC_Config(void);
void SysTick_Delay_ms(uint16_t ms);
void Delay ( __IO uint32_t nCount );

uint32_t time=0;
uint32_t num=0;
uint32_t s=58;
uint32_t min=59;
uint32_t hour=23;
uint32_t year=2019;
uint32_t mon=7;
uint32_t day=15;

////////////////////////////////////////////////////////年月日时分秒==============================================================
uint32_t s1=0;
uint32_t min1=0;
uint32_t hour1=0;
========================闹钟的时分秒==========================================
char dispBuff[100];
char ALMCLK[220];
char ALMCLK2[220];
//                char dispBuff[100];
int main(void)
{
        void NVIC2_Config(void);
        void EXTI2_Config(void);
        char SETTING[220];
        GPIO_Config();
        ILI9341_Init();
        ILI9341_GramScan(6);
        ILI9341_Clear ( 0, 0, 240, 320 );
============================屏幕上第一二行显示年月日时分秒    第三行显示闹钟时分秒设定   第四行原本打算显示 设置时间请选择K1
        LCD_SetBackColor(WHITE);
        sprintf(ALMCLK,"alarm clock:%d:%d:%d     KEY1",hour1,min1,s1);
        sprintf(SETTING,"TIME SETTING          KEY2");
        ILI9341_DispStringLine_EN(LINE(3),ALMCLK);
        ILI9341_DispStringLine_EN(LINE(4),SETTING);
=========================定时器二装配模拟秒针滴答的函数================================================================================================
                NVICTIM2_Config();
                TIM2_Config();
        while(1)
        {
                        void DayTick(void);
                        DayTick();        

                        if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0))
                        {
                                LCD_ClearLine(LINE(2));
                                LCD_ClearLine(LINE(3));
                                LCD_ClearLine(LINE(4));
                                LCD_SetTextColor(BLACK);
                                sprintf(ALMCLK,"alarm clock:%d:%d:%d     ",hour1,min1,s1);
                                ILI9341_DispStringLine_EN(LINE(3),ALMCLK);
                                sprintf(ALMCLK2,"  UP KEY2      CONFIRM KEY1");
                                ILI9341_DispStringLine_EN(LINE(4),ALMCLK2);
                        }
=============================妄图以此方法通过K2来更改时间闹钟时间设定=============================================
                        while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13))
                {
                        s1++;
                        LCD_SetTextColor(BLACK);
                        sprintf(ALMCLK,"alarm clock:%d:%d:%d     ",hour1,min1,s1);
                        ILI9341_DispStringLine_EN(LINE(3),ALMCLK);
                        if(s1>=60)
                        {
                                min1++;
                                s1=0;
                        }
                        if(min1>=60)
                        {
                                hour1++;
                                min1=0;
                        }
                        if(hour1>=24)hour1=0;
                }
        }
}

void DayTick(void)
{
        char ymd[100];
        int j=year%4;
        NVICTIM_Config();
        TIM_Config();
        
        LCD_SetFont(&Font8x16);
        LCD_SetTextColor(GREEN);
        sprintf(ymd,"%d/%d/%d",year,mon,day);
        ILI9341_DispStringLine_EN(LINE(1),ymd);
        LCD_SetFont(&Font8x16);
        LCD_SetTextColor(GREEN);
        sprintf(dispBuff,"%d:%d:%d",hour,min,s);
        ILI9341_DispStringLine_EN(LINE(2),dispBuff);
/////////在屏幕中显示时分秒年月日并随时更新////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                if(time>=1000)
                {
                        s++;
                        time=0;
                }
                if(s>=60)
                        {
                                s=0;
                                min++;
                                LCD_ClearLine(LINE(2));        /* &#199;&#229;3yμ¥DD&#206;&#196;×&#214; */
                        }
                if(min>=60)
                        {
                                hour++;
                                min=0;
                        }
                if(hour>=24)
                {
                        hour=0;
                        day++;
                        LCD_ClearLine(LINE(1));
                }
                if( (mon==1||mon==3||mon==5||mon==7||mon==8||mon==10||mon==12)&&(day>31) )
                {
                        day=1;
                        mon++;
                }
          if( (mon==4||mon==6||mon==9||mon==11)&&(day>30))
                        {
                        day=1;
                        mon++;
                  }
                if(j!=0&&mon==2&&day>28)
                {
                        day=1;
                        mon++;
                }
                if(j==0&&mon==2&&day>29)
                {
                        day=1;
                        mon++;
                }
                if(mon>12)
                {
                        mon=1;
                        year++;
                }
///////////////////////////////在屏幕中显示钟表的样子==============================================================
                LCD_SetTextColor(BLACK);
                ILI9341_DrawCircle ( 120,220, 80, 0 );
               
                LCD_SetTextColor(RED);
                ILI9341_DrawLine(120,220,(120+65*cos((3*PI/2)+(2*PI*s/60))),(220+65*sin((3*PI/2)+(2*PI*s/60))));
                 LCD_SetTextColor(WHITE);
                 ILI9341_DrawLine( 120,220, ( 120+65*cos( (3*PI/2)+(2*PI*(s-1)/60) ) ) ,( 220+65*sin( (3*PI/2)+(2*PI*(s-1)/60) ) ) );
                if(s==0)ILI9341_DrawLine( 120,220, ( 120+65*cos( (3*PI/2)+2*PI*59/60 ) ) ,( 220+65*sin( (3*PI/2)+2*PI*59/60 ) ) );
               
                LCD_SetTextColor(RED);
                ILI9341_DrawLine(120,220,(120+50*cos((3*PI/2)+(2*PI*min/60))),(220+50*sin((3*PI/2)+(2*PI*min/60))));
                 LCD_SetTextColor(WHITE);
                 ILI9341_DrawLine(120,220,(120+50*cos((3*PI/2)+(2*PI*(min-1)/60))),(220+50*sin((3*PI/2)+(2*PI*(min-1)/60))));
                if(min==0)ILI9341_DrawLine( 120,220, ( 120+50*cos( (3*PI/2)+2*PI*59/60 ) ) ,( 220+50*sin( (3*PI/2)+2*PI*59/60 ) ) );
                        
                if(hour<=12)
                {
                        LCD_SetTextColor(RED);
                        ILI9341_DrawLine(120,220,(120+35*cos((3*PI/2)+(2*PI*(hour)/12))),(220+35*sin((3*PI/2)+(2*PI*(hour)/12))));
                        LCD_SetTextColor(WHITE);
                        ILI9341_DrawLine(120,220,(120+35*cos((3*PI/2)+(2*PI*(hour-1)/12))),(220+35*sin((3*PI/2)+(2*PI*(hour-1)/12))));
                }
                if(hour>12)
                {
                        LCD_SetTextColor(RED);
                        ILI9341_DrawLine(120,220,(120+35*cos((3*PI/2)+(2*PI*(hour-12)/12))),(220+35*sin((3*PI/2)+(2*PI*(hour-12)/12))));
                        LCD_SetTextColor(WHITE);
                        ILI9341_DrawLine(120,220,(120+35*cos((3*PI/2)+(2*PI*(hour-13)/12))),(220+35*sin((3*PI/2)+(2*PI*(hour-13)/12))));
                }
                if(hour==13)ILI9341_DrawLine( 120,220, ( 120+35*cos( (3*PI/2)+2*PI ) ) ,( 220+35*sin( (3*PI/2)+2*PI ) ) );
                if(hour==0)
                ILI9341_DrawLine( 120,220, ( 120+35*cos( (3*PI/2)+2*PI*11/12 ) ) ,( 220+35*sin( (3*PI/2)+2*PI*11/12 ) ) );
               
}
=============================================================================================================================================
=========================================exti.C文件中===============================================================
#include "stm32f10x.h"
#include "gpio.h"
#include "bsp_ili9341_lcd.h"
#define PI 3.141592
#include <stdio.h>
#include <math.h>

extern uint8_t a;
extern uint32_t num;
uint16_t pwm;
extern uint32_t time;
extern uint32_t s;
extern uint32_t min;
extern uint32_t hour;
extern uint32_t s1;
extern uint32_t min1;
extern uint32_t hour1;
extern uint32_t year;
extern uint32_t mon;
extern uint32_t day;
extern char dispBuff[100];
extern char ALMCLK[220];
extern char ALMCLK2[220];

void TIM_Config(void)
{
                TIM_TimeBaseInitTypeDef TIM_InitS;
                RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
                TIM_InitS.TIM_Prescaler = 71;
                TIM_InitS.TIM_Period = 999;
                TIM_InitS.TIM_CounterMode = TIM_CounterMode_Up;
                TIM_InitS.TIM_ClockDivision = 0;
                TIM_InitS.TIM_RepetitionCounter = 0;
                TIM_TimeBaseInit(TIM1,&TIM_InitS);
        
                TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);
                TIM_Cmd(TIM1,ENABLE);
}
void NVICTIM_Config(void)
{
        NVIC_InitTypeDef NVIC_Inits;
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);
        NVIC_Inits.NVIC_IRQChannel = TIM1_UP_IRQn;
        NVIC_Inits.NVIC_IRQChannelPreemptionPriority = 1;   
        NVIC_Inits.NVIC_IRQChannelSubPriority = 0;   
        NVIC_Inits.NVIC_IRQChannelCmd = ENABLE;      
        NVIC_Init(&NVIC_Inits);                  
}
void TIM1_UP_IRQHandler(void)
{
        if(TIM_GetITStatus(TIM1,TIM_IT_Update)!=RESET)
                {
                        TIM_ClearITPendingBit(TIM1,TIM_IT_Update);
                        time++;
                }
}

void TIM2_Config(void)
{
                TIM_TimeBaseInitTypeDef TIM2_InitS;
                RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
                TIM2_InitS.TIM_Prescaler = 71;
                TIM2_InitS.TIM_Period = 999;
                TIM2_InitS.TIM_CounterMode = TIM_CounterMode_Up;
                TIM2_InitS.TIM_ClockDivision = 0;
                TIM2_InitS.TIM_RepetitionCounter = 0;
                TIM_TimeBaseInit(TIM2,&TIM2_InitS);
        
                TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
                TIM_Cmd(TIM2,ENABLE);
}
void NVICTIM2_Config(void)
{
        NVIC_InitTypeDef NVIC2_Inits;
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        NVIC2_Inits.NVIC_IRQChannel = TIM2_IRQn;  
        NVIC2_Inits.NVIC_IRQChannelPreemptionPriority = 0;   
        NVIC2_Inits.NVIC_IRQChannelSubPriority = 0;   
        NVIC2_Inits.NVIC_IRQChannelCmd = ENABLE;      
        NVIC_Init(&NVIC2_Inits);                  
}
void TIM2_IRQHandler(void)
{
        GPIO_Config();
        if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET)
                {
                                TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
                num++;
                        if(num>=500)
                {
                                        num=0;
                                        if(a==0)
                                {
                                                a=1;
                                        GPIO_ResetBits(GPIOA,GPIO_Pin_8);
                                }
                                        else
                                {
                                                a=0;
                                        GPIO_SetBits(GPIOA,GPIO_Pin_8);
                                }
                }
                        if(num>=20)GPIO_ResetBits(GPIOA,GPIO_Pin_8);
        }
}
=============================================================================================================================================
===================================GPIO文件中=======================================================================================
#include "stm32f10x.h"

void GPIO_Config(void)
{
        GPIO_InitTypeDef GPIO_InitS;//
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO,ENABLE);//′ò&#191;aíaéèê±&#214;ó
        GPIO_InitS.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitS.GPIO_Pin = GPIO_Pin_8;
        GPIO_InitS.GPIO_Speed = GPIO_Speed_2MHz;
        GPIO_Init(GPIOA,&GPIO_InitS);
        
        //GPIO_SetBits(GPIOB,GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_5);
        
        GPIO_InitS.GPIO_Pin = GPIO_Pin_0;
        GPIO_InitS.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOA,&GPIO_InitS);
        GPIO_InitS.GPIO_Pin = GPIO_Pin_13;
        GPIO_InitS.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOC,&GPIO_InitS);
}

=========================================================================================================================================用此法进行的时候,虽然可以实现目前的基本想法,却突然发现了问题,在main函数的while循环中,设定闹钟的时分秒和主屏幕显示时间相互冲突,会在设定闹钟的时候导致时钟延迟
QQ图片20190716104003.jpg QQ图片20190716103948.jpg QQ图片20190716104009.jpg QQ截图20190716104205.jpg
所以我就把时钟显示的这么长的一串代码(原谅C语言没学好,整天用if else语句判断)全都封装到定时器一中去
QQ截图20190716112723.jpg QQ截图20190716112802.jpg QQ截图20190716112540.jpg QQ截图20190716112640.jpg
然后问题就来了,原先可以实现时钟滴答和显示,和延时的闹钟设定      可如今时钟的滴答声已经由原本的1s一次,变为如今的8s一次,原先可以通过K2来进行闹钟的设定,现在按K2已经完全没有反应
瞬间迷茫,希望大神们帮忙看看问题出在哪顺带上传原PRO 原先还算正常.zip (7 MB, 下载次数: 10) 问题发现的时候.zip (7.05 MB, 下载次数: 9) 万分感谢您们的解答





回复

使用道具 举报

 楼主| 发表于 2019-7-16 11:48:30 | 显示全部楼层
这是作业的 QQ截图20190716114717.jpg 要求
回复 支持 反对

使用道具 举报

发表于 2019-7-16 11:59:06 来自手机 | 显示全部楼层
用RTC不可以吗?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-7-16 15:12:06 | 显示全部楼层

现在比起做出这个实验,我其实更想知道为什么把函数放到定时器里面和放在外面会有差别。定时器在while循环里和while循环外又有什么不同
回复 支持 反对

使用道具 举报

发表于 2019-7-17 01:28:42 来自手机 | 显示全部楼层
轮询系统肯定有这类问题,换成前后台系统。再精简下显示函数,总之就是主循环太乱,步骤太多了,想办法精简。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2025-12-6 10:23 , Processed in 0.049437 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表