作业1,秒表,定时器的实现

主要任务为

1,oled显示秒表时间,当前模式

2,秒表模式可以记录几个时间

3,秒表模式下10ms发送串口数据,当前时间和模式

4,通过按键更改,转换成定时器模式

5,定时器模式下可以自行设置初始时间,并倒计时

6,倒计时情况下灯逐渐熄灭


秒表部分


if (!flag){OLED_Clear();OLED_ShowNum(0,0,0,1,1);OLED_ShowString(70,0,"mode:1",1);//清屏,初始化


  while(1){ks0 = HAL_GPIO_ReadPin(k0_GPIO_Port,k0_Pin);

if(ks0!=GPIO_PIN_SET){HAL_Delay(200);ks0 = HAL_GPIO_ReadPin(k0_GPIO_Port,k0_Pin);
    if(ks0!=GPIO_PIN_SET)break;}}//ks0作为开始按钮,点击后启动程序
  unsigned ti=0;//用于记录当前存储了多少数据
HAL_TIM_Base_Start_IT(&htim2);//启动定时器二

while (1) { ks2 = HAL_GPIO_ReadPin(k2_GPIO_Port,k2_Pin);//ks2判断是否更改模式

if(ks2!=GPIO_PIN_SET){flag=!flag;HAL_TIM_Base_Stop_IT(&htim2);break;}
 i++;//i为i*100ms
if(i<10){OLED_ShowNum(0,0,0,1,1);OLED_ShowChar(10,0,',',1);OLED_ShowNum(20,0,i,1,1);}//由于个位特殊性,单独判断
else { unsigned j=i,cnt=0,num[100]; while(1) { num[++cnt]=j%10; j/=10; if(!j)break; }
for(j=cnt;j>=2;j--)OLED_ShowNum((cnt-j)*10,0,num[j],1,1); OLED_ShowChar((cnt-1)*10,0,',',1);OLED_ShowNum(cnt*10,0,num[1],1,1); }
ks0 = HAL_GPIO_ReadPin(k0_GPIO_Port,k0_Pin);//按钮判断区域 if(ks0!=GPIO_PIN_SET){HAL_Delay(200);ks0 = HAL_GPIO_ReadPin(k0_GPIO_Port,k0_Pin); if(ks0!=GPIO_PIN_SET){ while(1) { HAL_Delay(200);ks1=HAL_GPIO_ReadPin(k1_GPIO_Port,k1_Pin); ks0 = HAL_GPIO_ReadPin(k0_GPIO_Port,k0_Pin); if(ks0!=GPIO_PIN_SET){OLED_Clear();i=0;break;}//重置 if(ks1!=GPIO_PIN_SET){break;}//继续 ks4=HAL_GPIO_ReadPin(k4_GPIO_Port,k4_Pin);//记录数据 if(ks4!=GPIO_PIN_SET){HAL_Delay(200);if(ks4!=GPIO_PIN_SET){ ++ti;if(ti==4)ti=0; if(i<10){OLED_ShowNum(0,ti*2,0,1,1);OLED_ShowChar(10,ti*2,',',1);OLED_ShowNum(20,ti*2,i,1,1);} else { unsigned j=i,cnt=0,num[100]; while(1) { num[++cnt]=j%10; j/=10; if(!j)break; } for(j=cnt;j>=2;j--)OLED_ShowNum((cnt-j)*10,ti*2,num[j],1,1); OLED_ShowChar((cnt-1)*10,ti*2,',',1);OLED_ShowNum(cnt*10,ti*2,num[1],1,1); } }} }} }

while(1)
{
if(kb1>=10)break;
}

}

定时器部分

//初始化,k这里是作为k*1000ms,因为设置时是1s为精度,开启时将k乘十作为k*100ms即可
if(flag)
  {OLED_Clear();OLED_ShowString(70,0,"mode:2",1);
      OLED_ShowNum(0,0,0,1,1);
      k=0;//初始化,k*1000ms,后续乘十作为k*100ms

      while(1)
      {
              ks2 = HAL_GPIO_ReadPin(k2_GPIO_Port,k2_Pin);
              if(ks2!=GPIO_PIN_SET){flag=!flag;break;}
          ks0 = HAL_GPIO_ReadPin(k0_GPIO_Port,k0_Pin);
          ks1 = HAL_GPIO_ReadPin(k1_GPIO_Port,k1_Pin);
          ks3 = HAL_GPIO_ReadPin(k3_GPIO_Port,k3_Pin);
          if(ks0!=GPIO_PIN_SET){//增
              HAL_Delay(200);ks0 = HAL_GPIO_ReadPin(k0_GPIO_Port,k0_Pin);
              if(ks0!=GPIO_PIN_SET){k++;
              unsigned j=k,cnt=0,num[100];
                    while(1)
                    {
                        num[++cnt]=j%10;
                        j/=10;
                        if(!j)break;
                    }
                    for(j=cnt;j>=1;j--)OLED_ShowNum((cnt-j)*10,0,num[j],1,1);
          }}
          if(ks1!=GPIO_PIN_SET){//减
          HAL_Delay(200);ks0 = HAL_GPIO_ReadPin(k0_GPIO_Port,k0_Pin);
          if(ks1!=GPIO_PIN_SET){k--;
              unsigned j=k,cnt=0,num[100];
                              while(1)
                              {
                                  num[++cnt]=j%10;
                                  j/=10;
                                  if(!j)break;
                              }
                              for(j=cnt;j>=1;j--)OLED_ShowNum((cnt-j)*10,0,num[j],1,1);
                    }}
          if(ks3!=GPIO_PIN_SET)
          {//启动
              k*=10;
              unsigned int maxx=k;
              uint16_t dutyCycle = 0;//调控led的pwm波占空比
              HAL_TIM_Base_Start_IT(&htim5);//启动计时器
              while (1)
              {
                  if(k==0){OLED_Clear();OLED_ShowString(70,0,"mode:2",1);
                  OLED_ShowNum(0,0,0,1,1);__HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_1,0);break;}//pwm设为初始低电平
                if(k<10){OLED_ShowNum(0,0,0,1,1);OLED_ShowChar(10,0,',',1);OLED_ShowNum(20,0,k,1,1);}
                else {
                    unsigned j=k,cnt=0,num[100];
                    while(1)
                    {
                        num[++cnt]=j%10;
                        j/=10;
                        if(!j)break;
                    }
                for(j=cnt;j>=2;j--)OLED_ShowNum((cnt-j)*10,0,num[j],1,1);
                OLED_ShowChar((cnt-1)*10,0,',',1);OLED_ShowNum(cnt*10,0,num[1],1,1);
                }
                dutyCycle=k*1000/maxx;//将当前k与总时间的关系转化成占空比,达到逐渐熄灭的效果
                __HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_1, 1000-dutyCycle);

              }
              HAL_TIM_Base_Stop_IT(&htim5);
          }
      }

    }

定时器中断程序


void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

{

    if (htim->Instance == htim2.Instance)

    {
        printf("mode1
");
          printf("%d,%d",i/10,i%10);
              kb1++;

   }
    if (htim->Instance == htim5.Instance)
            k--;
}

最后是一些初始化变量和头文件

#include "main.h"
#include "i2c.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
#include "oled.h"

GPIO_PinState ks0,ks1,ks2,ks3,ks4 ;
unsigned int di=1,kb1,i=0,k=0,flag=0;

 MX_GPIO_Init();
  MX_I2C1_Init();
  MX_USART1_UART_Init();
  MX_TIM3_Init();
  MX_TIM8_Init();
  MX_TIM2_Init();
  MX_TIM5_Init();
  OLED_Init();

  HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_1);//打开pwm

printf函数

#include "stdio.h"

#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
    HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
    return ch;
}

over

 
原文地址:https://www.cnblogs.com/SFWR-YOU/p/14038809.html