作业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\r\n"); 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