一、题目

解析:这届题目用到的是LCD、LED、按键、ADC、PWM输出和脉冲捕获,其中按键还包括了短按键和长按键,首先让我们来进行CubeMX的配置。

二、CubeMX配置

基础配置

1、RCC配置:

2、时钟树的配置:

3、SYS配置:

模块配置

1、GPIO配置:

2、定时器配置:

3、ADC配置:

当全部配置完成后就是这样

三、题目分析

先把整个题目看一遍,了解大概要用到什么知识,特别是硬件框图,直接确定了本题所用到的模块,当大致了解以后就可以去配置CubeMX。一些模块的初始状态很重要,编写代码时要根据题目要求来确定模块的初始状态,然后再根据题目要求一点一点的去实现题目的要求。

1、LCD

分三个不同界面,分别是数据界面、参数界面、统计界面,不同界面实现不同功能,可以设置三个不同的条件来决定进入哪个界面。同时LCD初始状态也要配置正确。

2、按键

B1按键用来切换界面,在数据界面时,B2按键用于切换输出模式,B4按键长按,锁定输出信号占空比,短按解锁。在参数界面时,B2按键用于选择参数R和K,B3按键定义为“加”,B4按键定义为“减”。

3、LED

在数据界面下,LED灯1一直亮起,当B2按键按下,LED灯2闪烁,闪烁五秒后熄灭,输出模式切换。当B4长按时,锁定输出信号占空比,LED灯3亮起,B4短按后解锁,LED灯3熄灭

四、代码实现

1、主函数基础设置

int view=0,n=0,lock=0;    //界面,模式切换次数,状态 int R=1,K=1;        //参数 int plv_pa1=200;    //频率 int flag_view1;        //选择标志位 uchar PA1_duty;        //占空比 float Vs,Vmax_H,Vmax_L;    //实时速度,最大速度,最小速度

    LED_Disp(0x01);//设置LED初始状态     LCD_Init ();//LCD初始化          LCD_Clear(Black  );     LCD_SetBackColor(Black );     LCD_SetTextColor(White);        //设置LCD背景          HAL_TIM_Base_Start_IT (&htim3 );    //开启定时器3     HAL_TIM_Base_Start_IT (&htim4 );    //开启定时器4

    HAL_TIM_PWM_Start (&htim2 ,TIM_CHANNEL_2 );//PWM输出打开          HAL_TIM_IC_Start_IT(&htim17,TIM_CHANNEL_1 );//脉冲捕获定时器开启

2、LCD显示部分

void disp_proc(void )    //LCD模块 {       Vs = (frq*2*3.14*R)/(100*K);        //实时速度V          if(getADC (&hadc2 )<1 && lock==0)        //如果电压小于1V且位于解锁状态     {         PA1_duty =10;     }     else if(getADC (&hadc2 )>3 && lock==0)        //如果电压大于3V且位于解锁状态     {         PA1_duty =85;     }     else if(lock ==0)                            //位于1V~3V之间     PA1_duty =37.5*getADC (&hadc2 )-27.5;    //实时占空比P              if(plv_pa1 >=200)        //高频模式下最大速度     {         if(Vs>Vmax_H)         {             Vmax_H=Vs;         }     }     else if(plv_pa1 <105)        //低频模式下最大速度     {         if(Vs>Vmax_L)         {             Vmax_L=Vs;         }     }          if(view ==0)        //数据界面     {                      char text[30];         sprintf (text ,"         DATA                ");         LCD_DisplayStringLine(Line2, (uint8_t *)text );         if(plv_pa1==200)         {             sprintf (text ,"    M=L                      ");             LCD_DisplayStringLine(Line4, (uint8_t *)text );         }         else if(plv_pa1==100)         {             sprintf (text ,"    M=H                     ");             LCD_DisplayStringLine(Line4, (uint8_t *)text );         }         sprintf (text ,"    P=%d%%               ",PA1_duty );         LCD_DisplayStringLine(Line5, (uint8_t *)text );         sprintf (text ,"    V=%.1f              ",Vs);         LCD_DisplayStringLine(Line6, (uint8_t *)text );     }     else if(view ==1)        //参数界面     {       char text[30];       sprintf (text ,"         PARA                ");       LCD_DisplayStringLine(Line2, (uint8_t *)text );       sprintf (text ,"    R=%d                       ",R);       LCD_DisplayStringLine(Line4, (uint8_t *)text );       sprintf (text ,"    K=%d                       ",K);       LCD_DisplayStringLine(Line5, (uint8_t *)text );

    }     else if(view==2)            //    统计界面     {             char text[30];         sprintf (text ,"         RECD               ");       LCD_DisplayStringLine(Line2, (uint8_t *)text );       sprintf (text ,"    N=%d                  ",n);       LCD_DisplayStringLine(Line4, (uint8_t *)text );       sprintf (text ,"    MH=%.1f          ",Vmax_H);       LCD_DisplayStringLine(Line5, (uint8_t *)text );       sprintf (text ,"    ML=%.1f          ",Vmax_L);       LCD_DisplayStringLine(Line6, (uint8_t *)text );     } }

3、按键实现

void key_proc(void )        //按键模块 {

    if(key[0].single_flag ==1)             //当按键B1按下     {         LCD_Clear(Black );         view++;            //界面切换         if(view ==3)    {view=0;}                  if(view==0)        //如果在view0界面下         {             LED_Disp(0x01);        //led灯1亮         }         else LED_Disp(0x00);        //否则全熄灭                  if(view==1)                 {             flag_view1=0;//每次进入view1界面,默认可调整参数为R         }

        key[0].single_flag=0;     }              if(key[1].single_flag ==1)    //当按键B2按下     {         if(view==0)        //view0界面下         {             n++;        //高低频率模式切换次数                         flag_5s =1;//跳转到中断函数         }                     if(view ==1)        //view1界面下         {             flag_view1++;        //R,K参数选择             if(flag_view1==2)             {                 flag_view1=0;             }                  }         key[1].single_flag =0;     }          if(key[2].single_flag ==1)        //按键B3按下     {         if(view ==1)        //view1界面下         {             if(flag_view1==0)        //处于R参数位置下             {                 R++;                 if(R==11)                 {                     R=1;                 }             }             else            //处于K位置下             {                 K++;                 if(K==11)                 {                     K=1;                 }             }                 }             key[2].single_flag =0;     }          if(key[3].single_flag==1)        //按键B4按下     {                  if(view==0)         {             lock =0;             LED_Disp(0x01);         }                        //用于解锁                  if(view==1)        //位于view1界面下         {             if(flag_view1==0)        //处于R位置             {                 R--;                 if(R==0)                 {                     R=10;                 }             }             if(flag_view1==1)        //处于K位置             {                 K--;                 if(K==0)                 {                     K=10;                 }             }         }         key[3].single_flag=0;     }              if(key[3].long_flag==1)        //当按键B4长按         {                 lock=1;             LED_Disp(0x05);        //led灯1和led灯3亮起             key[3].long_flag=0;         }

}

4、中断函数interrupt.c

#include "interrupt.h" #include "led.h"

extern int plv_pa1; int deng,flag_5s,Num=0; bool led_flag; struct keys key[4]={0,0,0};

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { 定时器3控制按键//     if(htim ->Instance ==TIM3 )     {         key[0].key_sta =HAL_GPIO_ReadPin (GPIOB ,GPIO_PIN_0 );         key[1].key_sta =HAL_GPIO_ReadPin (GPIOB ,GPIO_PIN_1 );         key[2].key_sta =HAL_GPIO_ReadPin (GPIOB ,GPIO_PIN_2 );         key[3].key_sta =HAL_GPIO_ReadPin (GPIOA ,GPIO_PIN_0 );                  for(int i=0;i<4;i++)         {             switch (key[i].judge_sta )             {                 case 0:                 {                     if(key[i].key_sta ==0)                     {                         key[i].judge_sta =1;                         key[i].key_time =0;                     }                 }                 break ;                 case 1:                 {                     if(key[i].key_sta ==0)                     {                         key[i].judge_sta =2;                     }                     else                         key[i].judge_sta =0;                 }                 break ;                 case 2:                 {                     if(key[i].key_sta ==1)                     {                         key[i].judge_sta =0;

                        if(key[i].key_time <200)                         {                             key[i].single_flag =1;                         }                     }                     else                     {                         key[i].key_time ++;                         if(key[i].key_time >200)                             key[i].long_flag =1;                     }                 }                 break;             }         }         } 定时器控制LED灯///     if(htim ->Instance== TIM4)     {             if(flag_5s==1)         {             led_flag =!led_flag ;             if(led_flag )             {                 LED_Disp (0x03);             }             else             {                 LED_Disp (0x01);

            }             Num++;             if(Num>=100)        //闪烁100次             {                 flag_5s =0;                 Num=0;                 if(plv_pa1 ==200)//如果处于低频模式                 {                     plv_pa1 =100;//高频模式                 }                 else if(plv_pa1 ==100)//如果处于高频模式                 {                     plv_pa1 =200;//低频模式                 }             }         }     }      } //脉冲捕获模块 uint  ccr1_val=0,frq=0; void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {         if(htim ->Channel ==HAL_TIM_ACTIVE_CHANNEL_1 )         {             ccr1_val=HAL_TIM_ReadCapturedValue (htim,TIM_CHANNEL_1 );//获取计数器1的值             __HAL_TIM_SetCounter (htim ,0);//计数器归0             frq=(80000000/80)/ccr1_val;//计算频率frq             HAL_TIM_IC_Start (htim ,TIM_CHANNEL_1 );//开启定时器         }                  if(plv_pa1 ==200)        //如果处于低频模式         {             __HAL_TIM_SetAutoreload (&htim2,1000);// 80 000 000\(20*1000)         }         else if(plv_pa1 ==100)        //如果处于高频模式         {             __HAL_TIM_SetAutoreload (&htim2,500);//80 000 000\(20*500)         } }

5、led设置

#include "led.h"

void LED_Disp(uchar dsLED) {     HAL_GPIO_WritePin (GPIOC ,GPIO_PIN_All ,GPIO_PIN_SET );//所有led置高电平,led熄灭     HAL_GPIO_WritePin (GPIOC ,dsLED <<8,GPIO_PIN_RESET );//led置低电平,led亮起     HAL_GPIO_WritePin (GPIOD ,GPIO_PIN_2 ,GPIO_PIN_SET );//打开锁存器     HAL_GPIO_WritePin (GPIOD ,GPIO_PIN_2 ,GPIO_PIN_RESET ); }

6、AD模块

#include "badc.h"

double getADC(ADC_HandleTypeDef *pin) {     uint adc;     HAL_ADC_Start (pin);     adc=HAL_ADC_GetValue (pin);     return adc*3.3/4096; }

相关文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: