【蓝桥杯嵌入式】14届程序题刷题记录及反思

• led
• 按键（长按/短按）
• PWM输出（PA1）
• 脉冲捕获（PA7）

二、按键部分

//放在定时器中断函数

    if(htim->Instance == TIM6)          //0.01s进入一次
{
for(uint8_t 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;    //按键时间清零
}else{
key[i].judge_sta = 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 < Short_time){
key[i].single_flag = 1;      //短按键
key[i].key_time = 0;
}
}else{                              //按键没松开
key[i].key_time++;              //继续计时
if(key[i].key_time > Long_time){
key[i].long_flag = 1;
key[i].key_time = 0;
}
}
}break;

}
}
}
struct keys{
uint8_t judge_sta;                        //按键状态判断
uint8_t key_sta;                          //按键状态
uint8_t single_flag;                      //按键单击成功1
uint8_t long_flag;                        //按键长按成功1
uint16_t key_time;                       //按键按下时长记录
};
/*define-----------------------------------------------------------------------*/
#define B1_PORT GPIOB
#define B2_PORT GPIOB
#define B3_PORT GPIOB
#define B4_PORT GPIOA

#define B1_PIN  GPIO_PIN_0
#define B2_PIN  GPIO_PIN_1
#define B3_PIN  GPIO_PIN_2
#define B4_PIN  GPIO_PIN_0
/*define------------------------------------------------------------------------*/
#define Long_time  200    //200*0.1 = 1s   //2s进入一次
#define Short_time 30     //单击在0.3s以内
/*include-----------------------------------------------------------------------*/
extern struct keys key[4];

三、LED灯部分

#include "led.h"

void led_set(uint8_t led_dis)
{
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC,led_dis<<8,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
void led_toggle(void)
{
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_10,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_11,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_12,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_14,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_15,GPIO_PIN_SET);

HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_9);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}

#include "base_adc.h"

{
return val*3.3/4096;
}

五、输入捕获

PSC 80-1  得到1us 计数值不用改动

/-----------------------------------------------------------------------------------------------------------------------------/

HAL_TIM_ACTIVE_CHANNEL_1是在使用STM32Cube库时的一个宏定义，用于指示TIM的第一个通道是否处于活动状态。这通常用于轮询或中断处理程序中，以确定特定通道是否触发了事件。

//单通道频率测量--双通道占空比测量

uint16_t cnt_rising=0, cnt_falling=0;
uint16_t freq=0;
float IC_duty;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(htim -> Instance == TIM3)
{
if(htim -> Channel == HAL_TIM_ACTIVE_CHANNEL_2)
{
freq = (80000000/80) / cnt_rising;
IC_duty = ((float)cnt_falling/cnt_rising)*100;
}
if(htim -> Channel == HAL_TIM_ACTIVE_CHANNEL_1)
{
}
}
}

六、PWM输出

__HAL_TIM_SET_PRESCALER(&htim2,40-1+bujin_time);

__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,P*0.01*1000 - 1); 

七、定时器部分

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

//定时器和中断记得在while(1)前面开启

    if(htim->Instance == TIM7)  //0.125s进入一次
{
if(bujin_flag == 1){

bujin_time ++;
if(M == L){
if(bujin_time == 40){
bujin_time = 0;
bujin_flag = 0;
__HAL_TIM_SET_PRESCALER(&htim2,80-1);
}else{
__HAL_TIM_SET_PRESCALER(&htim2,40-1+bujin_time);
}
}else if(M == H){
if(bujin_time == 40){
bujin_time = 0;
bujin_flag = 0;
__HAL_TIM_SET_PRESCALER(&htim2,40-1);
}else{
__HAL_TIM_SET_PRESCALER(&htim2,80-1-bujin_time);
}
}
}
}

if(htim->Instance == TIM17)  //0.1s进入一次
{
static uint16_t i = 0;
static uint16_t j = 0;
if(bujin_flag == 1){
led_toggle();
}
if(sel_en_flag == 0)
{
i++;
if(i >= 490){
i = 0;
sel_en_flag = 1;
}
}
V_2s = V;
j++;
if(j>=19){               //2s_V 要求
j=0;
if(V_2s == V){
V_2s_valid = 1;
}else{
V_2s_valid = 0;
}
}else{
V_2s_valid = 0;
}
}      

八、显示页面

void display_init(void)
{
LCD_Clear(Black);
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
}

//阶段2--步进设置100hz -- 40次中断 5s内
//0.125s中断一次

void H_fre_set(void){
__HAL_TIM_SET_PRESCALER(&htim2,40-1);
}
void L_fre_set(void){
__HAL_TIM_SET_PRESCALER(&htim2,80-1);
}

{
uint8_t text[30];
{
sprintf((char *)text,"        DATA    ");
LCD_DisplayStringLine(Line2,text);
if(M == H){
sprintf((char *)text,"     M=H     ");

// H_fre_set();
LCD_DisplayStringLine(Line4,text);
}else if(M == L){
sprintf((char *)text,"     M=L        ");

// L_fre_set();
LCD_DisplayStringLine(Line4,text);
}
P = IC_duty;
sprintf((char *)text,"     P=%d%%    ",P);
LCD_DisplayStringLine(Line5,text);
V = freq*2*3.14*R/(100.0*K);
sprintf((char *)text,"     V=%.1f     ",V);
LCD_DisplayStringLine(Line6,text);

if(M ==H){
if(V_2s_valid){
if(V> MH) {
MH = V;
}
}
}else if(M ==L){
if(V_2s_valid){
ML = V;
}
}

sprintf((char *)text,"        PARA    ");
if(key[1].single_flag == 1){
key[1].single_flag = 0;
}
LCD_DisplayStringLine(Line2,text);
sprintf((char *)text,"     R=%d       ",R);
LCD_DisplayStringLine(Line4,text);
sprintf((char *)text,"     K=%d       ",K);
LCD_DisplayStringLine(Line5,text);
LCD_ClearLine(Line6);

if(M ==H){
if(V_2s_valid){
if(V> MH) {
MH = V;
}
}
}else if(M ==L){
if(V_2s_valid){
ML = V;
}
}
sprintf((char *)text,"        RECD    ");
LCD_DisplayStringLine(Line2,text);
sprintf((char *)text,"     N=%d     ",N);
LCD_DisplayStringLine(Line4,text);
sprintf((char *)text,"     MH=%.1f    ",MH);
LCD_DisplayStringLine(Line5,text);
sprintf((char *)text,"     ML=%.1f   ",ML);
LCD_DisplayStringLine(Line6,text);
V = freq*2*3.14*R/(100.0*K);   //R和K参数在其他页面生效
}
}

九、 总结

后面打算只写一个usr.c usr.h

• 5
点赞
• 19
收藏
觉得还不错? 一键收藏
• 2
评论
06-15 2237
06-10 1658
04-08 1017
03-28 2733
05-07 1596
04-12 1391
03-25 300
11-11 8111
04-08 2万+
03-09 1188
03-25 466
03-05 257

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、付费专栏及课程。