原题展示 :

代码实现:
数据定义:
uint8_t display = 0;
uint8_t mode = 0;
int frea,freb,pera,perb,frea_m,freb_m;//频率0~1000 周期0~1000
float freA,freB,perA,perB;//频率 > 1000 周期 > 1000
int PD=1000,PH=5000,PX=0,NDA,NDB,NHA,NHB;
uint8_t select=0;
uint32_t count = 0;//计时
uint8_t count100ms_lcd,count100ms_flag,capture_flag;
float freqa_m,freqb_m;
LED相关:
void led_show(uint8_t led,uint8_t led_mode)
{
if(led_mode)
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8 << (led -1),GPIO_PIN_RESET);
else
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8 << (led -1),GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
void led_offall()
{
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|
GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15,GPIO_PIN_SET);
}
void led_fun(void)//LED灯显示
{
if(display == 0)
led_show(1,1);
else
led_show(1,0);
if(frea > PH)
led_show(2,1);
else
led_show(2,0);
if(freb > PH)
led_show(3,1);
else
led_show(3,0);
if(NDA >= 3 || NDB >= 3)
led_show(8,1);
else
led_show(8,0);
}
LCD相关:
char text[20];
void lcd_show()
{
if(count100ms_lcd == 1)//100ms刷新LCD
{
switch(display)
{
case 0://数据界面
{
if(mode == 0)//频率显示模式
{
sprintf(text, " DATA ");
LCD_DisplayStringLine(Line1,(uint8_t*)text);
//第二行
if(frea < 0)
sprintf(text, " A=NULL ");
else if(frea > 1000)
{
freA = (float)frea / 1000;
sprintf(text, " A=%.2fKHz ",freA);
}
else
sprintf(text, " A=%dHz ",frea);
LCD_DisplayStringLine(Line3,(uint8_t*)text);
//第三行
if(freb < 0)
sprintf(text, " B=NULL ");
else if(freb > 1000)
{
freB = (float)freb / 1000;
sprintf(text, " B=%.2fKHz ",freB);
}
else
sprintf(text, " B=%dHz ",freb);
LCD_DisplayStringLine(Line4,(uint8_t*)text);
}
else if(mode == 1)//周期显示模式
{
sprintf(text, " DATA ");
LCD_DisplayStringLine(Line1,(uint8_t*)text);
//第二行
if(pera < 0)
sprintf(text, " A=NULL ");
else if(pera > 1000)
{
perA = (float)pera / 1000;
sprintf(text, " A=%.2fmS ",perA);
}
else
sprintf(text, " A=%duS ",pera);
LCD_DisplayStringLine(Line3,(uint8_t*)text);
//第三行
if(perb < 0)
sprintf(text, " B=NULL ");
else if(perb > 1000)
{
perB = (float)perb / 1000;
sprintf(text, " B=%.2fmS ",perB);
}
else
sprintf(text, " B=%duS ",perb);
LCD_DisplayStringLine(Line4,(uint8_t*)text);
}
sprintf(text, " ");
LCD_DisplayStringLine(Line5,(uint8_t*)text);
sprintf(text, " ");
LCD_DisplayStringLine(Line6,(uint8_t*)text);
break;
}
case 1://参数界面
{
sprintf(text, " PARA ");
LCD_DisplayStringLine(Line1,(uint8_t*)text);
sprintf(text, " PD=%dHz ",PD);
LCD_DisplayStringLine(Line3,(uint8_t*)text);
sprintf(text, " PH=%dHz ",PH);
LCD_DisplayStringLine(Line4,(uint8_t*)text);
sprintf(text, " PX=%dHz ",PX);
LCD_DisplayStringLine(Line5,(uint8_t*)text);
sprintf(text, " ");
LCD_DisplayStringLine(Line6,(uint8_t*)text);
break;
}
case 2://统计界面
{
sprintf(text, " RECD ");
LCD_DisplayStringLine(Line1,(uint8_t*)text);
sprintf(text, " NDA=%d ",NDA);
LCD_DisplayStringLine(Line3,(uint8_t*)text);
sprintf(text, " NDB=%d ",NDB);
LCD_DisplayStringLine(Line4,(uint8_t*)text);
sprintf(text, " NHA=%d ",NHA);
LCD_DisplayStringLine(Line5,(uint8_t*)text);
sprintf(text, " NHB=%d ",NHB);
LCD_DisplayStringLine(Line6,(uint8_t*)text);
break;
}
}
}
}
按键相关:
uint8_t B1_state;
uint8_t B1_last_state;
uint8_t B2_state;
uint8_t B2_last_state;
uint8_t B3_state;
uint8_t B3_last_state;
uint8_t B4_state;
uint8_t B4_last_state;
void key_scan()
{
B1_state = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
B2_state = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
B3_state = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
B4_state = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
if(B1_state == 0 && B1_last_state == 1)//B1按下 加
{
if(select == 0)//PD
{
PD += 100;
if(PD > 1000) PD = 100;
}
if(select == 1)//PH
{
PH += 100;
if(PH > 10000) PH = 1000;
}
if(select == 2)//PX
{
PX += 100;
if(PX > 1000) PX = -1000;
}
}
if(B2_state == 0 && B2_last_state == 1)//B2按下 减
{
if(select == 0)//PD
{
PD -= 100;
if(PD < 0) PD = 1000;
}
if(select == 1)//PH
{
PH -= 100;
if(PH < 1000) PH = 10000;
}
if(select == 2)//PX
{
PX -= 100;
if(PX < -1000) PX = 1000;
}
}
if(B3_state == 0 && B3_last_state == 1)//B3按下
{
if(display == 1)//参数界面 选择参数
{
select++;
select %= 3;
}
else if(display == 0)//数据界面 模式切换
{
mode++;
mode %= 2;
}
else if(display == 2)//记录界面
{
TIM4->CNT = 0;//按键长按计时
}
}
else if(B3_state == 0 && B3_last_state == 0)//B3长按 清0
{
if(display == 2)
{
if(TIM4->CNT >= 10000)//1s
{
NDA = 0;
NDB = 0;
NHA = 0;
NHB = 0;
}
}
}
if(B4_state == 0 && B4_last_state == 1)//B4按下 界面切换
{
display++;
display %= 3;
if(display == 2)//记录界面
{
select = 0;
mode = 0;
}
}
B1_last_state = B1_state;
B2_last_state = B2_state;
B3_last_state = B3_state;
B4_last_state = B4_state;
}
频率捕获:
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//脉冲捕获中断
{
if(htim->Instance == TIM2)
{
uint32_t capture_valuea;
capture_valuea = TIM2->CCR1;
TIM2->CNT = 0;
frea_m = 80000000/(80*capture_valuea);//通道A频率
}
if(htim->Instance == TIM3)
{
uint32_t capture_valueb;
capture_valueb = TIM3->CCR1;
TIM3->CNT = 0;
freb_m = 80000000/(80*capture_valueb);//通道B频率
}
}
频率数据处理:
int max_a=0,min_a=20000,max_b=0,min_b=20000;
int frea_old=0,freb_old=0,PH_old=5000;
void freq_proc()//频率处理
{
if(count100ms_flag)//每100ms进行更新频率数据
{
count100ms_flag=0;
frea = frea_m+PX;//频率校准
freb = freb_m+PX;
pera = 1000000/(float)frea;// 1/fre = (s) => 1000000/fre = (us) 周期初始单位为us
perb = 1000000/(float)freb;
}
//频率超限
if(frea_old != frea)//频率A改变
{
if(frea_old<PH && frea>PH)
{
NHA++;
}
frea_old = frea;
}
if(freb_old != freb)//频率B改变
{
if(freb_old<PH && freb>PH)
{
NHB++;
}
freb_old = freb;
}
if(PH_old!=PH)//参数PH改变
{
if(frea<PH_old && frea>PH)
{
NHA++;
}
if(freb<PH_old && freb>PH)
{
NHB++;
}
PH_old = PH;
}
//频率突变
if(capture_flag) //3s计时
{//static 3s内持续更新最大值,最小值
if(frea>=0)
{
if(frea>max_a)
{
max_a=frea;
}
else if(frea<min_a)
{
min_a=frea;
}
}
if(freb>=0)
{
if(freb>max_b)
{
max_b=freb;
}
else if(freb<min_b)
{
min_b=freb;
}
}
}
else//统计完3s内的最大最小值
{
capture_flag=1;
if(max_a-min_a>PD && frea>=0)
{
NDA++;
}
if(max_b-min_b>PD && freb>=0)
{
NDB++;
}
//恢复初始化,以便在下一个3s 重新统计更新最大值,最小值
max_a=0;
min_a=20000;
max_b=0;
min_b=20000;
}
}
定时器:
uint32_t count3s,count100ms;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//100ms
{
if(htim->Instance == TIM17)
{
count100ms++;
if(count100ms>=10)//100ms
{
count100ms=0;
count100ms_lcd=1;
count100ms_flag=1;
}
if(capture_flag)
{
count3s++;
if(count3s>=300)//5s
{
count3s=0;
capture_flag=0;
}
}
}
}
主函数:
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM2_Init();
MX_TIM3_Init();
MX_TIM4_Init();
MX_TIM17_Init();
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
LCD_Init();
LCD_Clear(Black);
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
HAL_TIM_Base_Start(&htim4);
HAL_TIM_Base_Start_IT(&htim17);
HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);
HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);
while (1)
{
key_scan();
lcd_show();
freq_proc();
led_fun();
}
}