蓝桥杯嵌入式总的模板笔记

发布时间:2026/5/20 7:07:36

蓝桥杯嵌入式总的模板笔记 LED模板void LED_Conter(u8 led_conter) { HAL_GPIO_WritePin(GPIOC,0xff00,GPIO_PIN_SET);//熄灭PIN8~15 HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);//寄存器进行锁存 HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOC,led_conter8,GPIO_PIN_RESET);//通过移位操作控制指定引脚 HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);//寄存器进行锁存 HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET); }开/关led_num|0x01;//LED1开 led_num~0x01;//LED1关不影响其他灯定时闪烁u32 ledTick; void led_process() { if(uwTick-ledTick1000) return ; //return执行则下面的程序都不会执行 ledTickuwTick; led_ctrl ^ 0x01; //第0位取反其他位不变 led_ctrl~led_ctrl效果也是一样的 led_control(led_ctrl); //这个是已经打包好了的自定义函数 } /*由led_ctrl ^ 0x01可以推广到led_ctrl ^ 0x02就是第二位取反其他不变 led_ctrl ^ 0x03就是一二位取反其他位不变*/不定时闪烁u32 ledTick; u8 led_cnt;//这是用来表示秒的一个变量 void led_process() { if(uwTick-ledTick1000) return ; ledTickuwTick; led_cnt; if(led_cnt5)//这句是关键的一句实现循环的不定时亮灭 led_cnt0; if(led_cnt3) //小于3秒亮 led_ctrl | 0x01; if(led_cnt2) //大于2秒灭 led_ctrl ~0x01; led_control(led_ctrl); }Systicku8 num void SysTick_Handler(void)//复制的main.c文件中后记得删除原来的 { HAL_IncTick(); num; if(num%1000)//0.1s { //执行相应程序 } }按键模板/*放自己创的key.c里面*/ #define KB1 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0) #define KB2 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) #define KB3 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2) #define KB4 HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) #define KEYPORT KB1|(KB21)|(KB32)|(KB43)|0xf0 u8 Trg; //按键状态 u8 Cont; //长按 void key_Read(void) { u8 ReadData (KEYPORT) ^ 0xff; TrgReadData (ReadData^Cont); ContReadData; } /*放main.c文件里面*/ u32 KeyTick0; void Key_Process() { if(uwTick-KeyTick20)return;//按键的消抖 KeyTickuwTick; Key_Read(); //这里是调用上面的函数目的是读取Trg的值 if(Trg0x01)//按键1被按下 { //执行相应的程序 } if(Trg0x02)//按键2被按下 { //执行相应的程序 } if(Trg0x04)//按键3被按下 { //执行相应的程序 } if(Trg0x08)//按键4被按下 { //执行相应的程序 } }长按if(Cont0x01) { count; } if(Cont 0x00 Trg 0x00) { if(count20)//这里20是指1s { //功能 //清0 } else //清零 }这个20代表1s是根据你按键消抖所设的数x2就是指1s如果我按键消抖设20那么我的count40才算1sif(uwTick-keyTick10)return;双击u32 double_tick0; u8 key_num0; if(Trg0x01key_num0) { key_num1; double_tickuwTick; } else if(key_num1) { if(Trg0x01uwTick-double_tick300)//双击 { key_num0; LED_flag11; } else if(uwTick-double_tick300)//单击 { key_num0; LED_flag21; } }ADC模板u16 adc_num; u16 adc_val; void ADC_Process() { HAL_ADC_Start(hadc2); //具体的句柄看自己配置的 adc_numHAL_ADC_GetValue(hadc2); adc_valadc_num/4096.0f*3.3f; }LCD模板void LCD_Process() { u8 display_buf[20]; if(display_modedisplay_data) { LCD_DisplayStringLine(Line3,(u8*) DATA ); sprintf((char*)display_buf, VR37:%5.2fV ,vr37_val); LCD_DisplayStringLine(Line4,display_buf); } if(display_modedisplay_para) { LCD_DisplayStringLine(Line3,(u8*) PARA ); sprintf((char*)display_buf, VP1:%3.1fV ,vp1_val/10.0f); LCD_DisplayStringLine(Line4,display_buf); } }高亮LCD_SetBackColor(Green);//背景色改为绿色 sprintf((char*)buf, Max Volt:%3.1fV ,max_volt/10.0f); LCD_DisplayStringLine(Line3,buf); LCD_SetBackColor(White);//背景色改为白色EEPROM模板//写在i2c.c文件中 //写入 void EEPROM_Write(u8 add,u8 dat) { I2CStart(); I2CSendByte(0xa0); //0x01是设备地址 I2CWaitAck(); I2CSendByte(add); //EEPROM内部的地址用于指定数据要写入的具体位置 I2CWaitAck(); I2CSendByte(dat); I2CWaitAck(); I2CStop(); HAL_Delay(50); } ----------------------------------------------------------------------------------------- //读取 u8 EEPROM_Read(u8 add) { u8 dat; I2CStart(); I2CSendByte(0xa0); I2CWaitAck(); I2CSendByte(add); I2CWaitAck(); I2CStart(); I2CSendByte(0xa1); //0xa1是指表示读 I2CWaitAck(); datI2CReceiveByte(); I2CSendNotAck(); I2CStop(); return(dat); }//EEPROM void EEPROM_Init_Read() { //判断是不是第一次开机 if(EEPROM_Read(0xf0)!0xaa)//第一次开机 { EEPROM_Write(0xf0,0xaa);//标记下初始化完成 EEPROM_Write(0x00,rep_x); EEPROM_Write(0x01,rep_y); EEPROM_Write(0x02,price_x); EEPROM_Write(0x00,price_y); } rep_xEEPROM_Read(0x00); rep_yEEPROM_Read(0x01); price_xEEPROM_Read(0x02); price_yEEPROM_Read(0x03); }EEPROM_Read()如果前面没有数据写入那么它会返回一个默认值就是255为什么是255因为我们给他定义的是u8 void EEPROM_Read(u8 add)。例如你在按键1按下会执行相应的保存数据功能但如果不按下而你重新上电时你取出的值变成255明明没有存入却有值产生这不符合功能要求。RTCUSART固定长度模板u8 uart_buf[2]; u8 rx_buf[10]; u8 rx_cnt0; u32 uartTick0; int fputc(int ch,FILE*f)//printf重定向 { HAL_UART_Transmit(huart1,(u8*)ch,1,50);//发送一个字符ch到huart1串口50是超时时间 return ch; } void RxIdle_Process()//延时接收函数 { if(uwTick-uartTick50)return; uartTickuwTick; rx_cnt0; memset(rx_buf,\0,sizeof(rx_buf)); } ----------------------------------------------------------------------------------------- _Bool Check_String(u8*str)//格式检查 { if(str[1]!.||str[3]!,||str[5]!.) return 0; if(str[0]0||str[0]9) return 0; if(str[2]0||str[2]9) return 0; if(str[4]0||str[4]9) return 0; if(str[6]0||str[6]9) return 0; return 1; } ----------------------------------------------------------------------------------------- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//串口回调函数 { uartTickuwTick; rx_buf[rx_cnt]uart_buf[0]; if(rx_cnt7)//固定7位可以自己定几位 { rx_cnt0; //功能 } else { rx_cnt0; //功能 } HAL_UART_Receive_IT(huart1,uaret_buf,1);//启动中断接收每次接收1个字节 } //接收完成后回调函数HAL_UART_RxCpltCallback会被调用在初始化处不要忘记开启串口接收函数HAL_UART_Receive_IT(huart1,uaret_buf,1);//启动中断接收每次接收1个字节串口软件的使用注意这个一定要选对如果出现下载了且代码正确的前提下显示屏白屏可能是魔术棒里面有东西没勾不固定长度PWM捕获单路捕获u32 tim_cnt0 u32 f400 void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { tim_cnt__HAL_TIM_GetCounter(htim2); __HAL_TIM_SetCounter(htim2,0); f401000000/tim_cnt; HAL_TIM_IC_Start_IT(htim2,TIM_CHANNEL_1); }双路捕获void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { if(htimhtim2) { if(tim2_state0) { __HAL_TIM_SetCounter(htim2,0); TIM2-CCER|0X02; tim2_state1; } else if(tim2_state1) { tim2_cnt1__HAL_TIM_GetCounter(htim2); TIM2-CCER~0x02; tim2_state2; } else if(tim2_state2) { tim2_cnt2__HAL_TIM_GetCounter(htim2); freq_pa71000000/tim2_cnt2; duty_pa7tim2_cnt1*100.0f/tim2_cnt2; tim2_state0; } HAL_TIM_IC_Start_IT(htim2,TIM_CHANNEL_1); } //--------------------------------------------------------- if(htimhtim3) { if(tim3_state0) { __HAL_TIM_SetCounter(htim3,0); TIM3-CCER|0X02; tim3_state1; } else if(tim3_state1) { tim3_cnt1__HAL_TIM_GetCounter(htim3); TIM3-CCER~0x02; tim3_state2; } else if(tim3_state2) { tim3_cnt2__HAL_TIM_GetCounter(htim3); freq_pa61000000/tim3_cnt2; duty_pa6tim3_cnt1*100.0f/tim3_cnt2; tim3_state0; } HAL_TIM_IC_Start_IT(htim3,TIM_CHANNEL_1); }注意这个还要放到初始化的位置如果是双通道两个都要HAL_TIM_IC_Start_IT(htim2,TIM_CHANNEL_1);PWM输出void PWM_Process() { TIMx-CCRy...;//这个影响的是占空比 TIMx-ARR...;//这个影响的是频率 }在初始化的位置要开启pwm输出HAL_TIM_PWM_Start(htim17,TIM_CHANNEL_1);逻辑类题型14届高频、低频输出模式下的最大速度分开统计,保持时间不足 2 秒的速度值不纳入统计//定义 float v_prev0; u32 mlTick0; _Bool ml_flag0; if(mode0)//在低频模式下 { if(fabs(v_prev-v)2.0f) { if(vML) { if(ml_flag0)//是否可开始计时 { mlTickuwTick;//开始计时 ml_flag1; } if((uwTick-mlTick)2000ml_flag1)//到了2秒 { MLv; ml_flag0; } } else ml_flag0;//当前速度低于ml } else ml_flag0;//速度变化太快 }14届在数据界面下长按 B4 按键超过 2 秒后松开长按键可以“锁定” 占空比调整功能此时输出信号占空比保持不变不受 R37 电位器输出电压控制处于“锁定”状态后再次按下 B4 按键短按键实现“解锁” 功能恢复 R37 电位器对输出信号占空比的控制if(Cnt0x08)//B4一直按下 { if(display_modedisplay_data)//在数据界面下 time_b4; } if(Trg0x00Cnt0x00) { if(time_b4100)//超过2秒 { time_b40; lock1;//超过2秒锁定 } else if(time_b4!0)//b4按下过但是没有超过2秒,则为短按 { lock0;//超过2秒解锁 time_b40; } }

相关新闻