代码开源,Gitee自取
代码开源,Gitee自取
代码开源,Gitee自取
目录
0 前言
1 展示
1.1 源码
1.2 演示视频
1.3 题目展示
2 工程配置
3 资源配置&代码实现
3.1 定时器
3.2 液位检测
3.3 液位阈值设定
3.4 液位阈值设定
3.5 串口通信
3.6 LCD显示
3.7 LED显示
3.8 逻辑处理
3.9 main函数
原版
修改
4 电路设计
5 总结
0 前言
- 开发板:CT117E-M4(STM32G431RBT6)
- 软件环境:CubeMX + Keil5
- 涉及题目:第十三届蓝桥杯嵌入式省赛第二场真题
1 展示
1.1 源码
Gitee链接:
CSDN下载链接:https://download.csdn.net/download/weixin_63135906/89250289?spm=1001.2014.3001.5501
有需要的同学可以下载源码,对照本文说明使用!
1.2 演示视频
B站链接:
1.3 题目展示
考察内容:
LED、LCD、按键、ADC、RTC、E2PROM
需要用到的外设比较多,但是逻辑非常简单
2 工程配置
下载
使能HSE
失能LSE,LSE不需要配置,如果配置了,那么PC14、PC15就不能配置了,这两个引脚还要控制LED,这里有冲突,所以不能配置LSE!!!
GPIO
时钟设置
24M晶振,80M主频
24M晶振一定要设置好,不然会卡在初始化里一直过不去!!!
3 资源配置&代码实现
3.1 定时器
我这里先配置定时器,分析题目
找一个定时器专门用作按键扫描,再用一个定时器处理各种标志位~
定时器3配置
定时器4配置
我的工程里时钟都是配置了80M,这里预分频系数给80-1,计数值给10000-1
计算一下
80M / 80 / 10000 = 100Hz = 10ms
10ms进入一次中断
我用了定时器4中断做按键的扫描,定时器3中断做各种标志位的处理~
定时器中断回调函数
//定时器中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{static unsigned char tim4_count;static unsigned char adc_cnt; //1S内检测ADC的标志位static unsigned char led1_cnt, led2_cnt, led3_cnt;//每次进入中断回调函数都会判断是哪个中断if (htim->Instance == TIM3) //如果是定时器3的中断 - ADC - LED{adc_cnt ++ ;if (adc_cnt >= 65) //650ms{flag.adc_readtime_ok = 1;adc_cnt = 0;}// 处理LED状态指示// 这里时间也没有自加,笨比……if (++ led1_cnt >= 100) //1S{flag.LED1_State = ! flag.LED1_State;led1_cnt = 0; //记得这里一定要软件复位啊,又忘记了,大聪明蛋!}if (++ led2_cnt >= 20) //0.2S{flag.LED2_State = ! flag.LED2_State;if (flag.YW_IS_Change_forLED == 1) //如果液位变化{if (++ flag.LED2_ON_Cnt >= 10) //闪烁5次以上{flag.YW_IS_Change_forLED = 0;flag.LED2_ON_Cnt = 0;}}led2_cnt = 0;}if (++ led3_cnt >= 20) //0.2S{flag.LED3_State = ! flag.LED3_State;if (flag.IS_Receive == 1) //收到查询指令了{if ( ++ flag.LED3_ON_Cnt >= 10) //闪烁5次以上{flag.IS_Receive = 0; //先清零接收标志位flag.LED3_ON_Cnt = 0; //再清零闪烁次数,方便下一次闪烁指示}}led3_cnt = 0;}}if (htim->Instance == TIM4) //如果是定时器4的中断 - 按键{tim4_count++;if (tim4_count >= 50) //500ms{//led指示灯} /* 按键 */key[0].Key_sta = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0); //按键1 PB0key[1].Key_sta = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1); //按键2 PB1key[2].Key_sta = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2); //按键3 PB2key[3].Key_sta = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0); //按键4 PA0//轮询按键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; //状态置1key[i].key_time = 0; //按键按下的时间,初次按下先清零}}break;case 1: //按键消抖{if (key[i].Key_sta == 0) //如果状态保持按下{key[i].judge_sta = 2; //跳转到状态2}elsekey[i].judge_sta = 0; //否则按键按下}break;case 2:{if (key[i].Key_sta == 1) //如果按键松手{key[i].judge_sta = 0; //循环回到最开始if (key[i].key_time < 70) //短按键{key[i].single_flag = 1; //短按标志位置0,松手确认按键按下key[i].long_flag = 0; //长按标志位置0key[i].key_time = 0;}}else {key[i].key_time++; //按下的时候,一直10ms计时++if (key[i].key_time >= 70){ key[i].long_flag = 1; //长按标志位置1key[i].single_flag = 0; //短按标志位置0}}}break;}}}
}
定时器4用作按键扫描,这里的代码是我学习B站up主01stdio的~可以实现长按和短按
定时器3的操作后面慢慢讲
在定时器中断回调函数里要注意计时变量加加,时间到了也要清零,很久不写代码就会忘记这些基本操作
3.2 液位检测
通过电位器R37模拟液位传感器输出电压信号,设备以 1 秒为间隔采集 R37 输出电压, 并与用户设定的液位阈值进行比较。假定液位高度与 R37 输出电压之间具有正比例关系: H = VR37*K,当 VR37=3.3V 时,对应液位高度为 100cm。通过液晶显示当前的液位高度、 传感器(R37)输出状态和液位等级,液位检测显示界面如图 1 所示:
注意题目描述的关键词:
- 1S为间隔采集R37电压
- 液位高度与 R37 输出电压之间具有正比例关系: H = VR37*K
- 当 VR37=3.3V 时,对应液位高度为 100cm
在定时器3的中断里,每隔650ms读取一次
每相隔650ms,将flag.adc_readtime_ok标志位置1
adc_cnt ++ ;
if (adc_cnt >= 65) //650ms
{flag.adc_readtime_ok = 1;adc_cnt = 0;
}
if (flag.adc_readtime_ok == 1){Vol_1S = getADC(&hadc2); //ADC采集一次height = (uint16_t)(Vol_1S / 3.3f * 100);flag.adc_readtime_ok = 0;}
ADC读取函数
配置ADC引脚 PB15、PB12
新建关于ADC的.c.h 保存在BSP中,名称不要为adc,稍微修改一下
避免和HAL库自带的adc.c重复 - 报错
使用方法:定时读取调用ADC读取,刷新不用太快,这里我给了800ms
double getADC(ADC_HandleTypeDef *pin)
{uint adc; //声明变量,ADC读取出来的原始值HAL_ADC_Start(pin); //开启ADCadc = HAL_ADC_GetValue(pin); //read adcreturn adc*3.355/4096; //12位的ADC电压采集
}
这里有必要说明一下,返回值应该是return adc*3.3/4096;
虽然理论上的ADC电压是3.3V,但是事实上并不会真正的测到3.3V(实测滑动变阻器的拉满采集的最大电压值一直都是3.25V,经过我实际测试了几块蓝桥杯官方的开发板,都是3.25V)那么如果照着正常公式计算的话,最后转换的高度最大将会是98而不会到达100,因为就会面临着向下取整的问题,所以也无法满足保持高电平的要求,这点如果使用机器阅卷的话,不知道会怎么判。
所以我这里修改代码补偿一下硬件问题。虽然……但是……我现在就这样干了
电压显示,没有写题目给的中文
// 显示ADC
sprintf(LCD_Show_text, " ADC: %.2fV ", Vol_1S);
LCD_DisplayStringLine(Line5, (uint8_t *)LCD_Show_text);
3.3 液位阈值设定
设备可设定三个液位阈值,对应四个液位等级,阈值由用户通过按键输入,设备保存阈值,并根据此阈值判断液位等级,假定用户输入的三个液位阈值为 10cm、20cm 和 30cm, 液位高度与液位等级的对应关系如下:
- 液位高度≤10cm 时,液位等级为 0;
- 10cm<液位高度≤20cm 时,液位等级为 1;
- 20cm<液位高度≤30cm 时,液位等级为 2;
- 液位高度>30cm 时,液位等级为 3。
设备初始液位阈值分别为 30cm、50cm 和 70cm,用户修改阈值后,设备应将此参数保存在 E2PROM 中,当设备重新上电时,可从 E2PROM 中获取。
注意这里埋了个大坑:当设备重新上电时,可从 E2PROM 中获取。解决方法就是用E2PROM识别是否是第一次上电,后面讲这个~
3.4 液位阈值设定
- B1 按键:“设置”按键,按下后进入阈值设定界面(如图 2 所示),再次按下 B1 按键时 退出设置界面,保存用户设定的结果到 E2PROM,并返回图 1 所示的液位检测界面。
- B2 按键:切换选择 3 个待修改的阈值,被选中的阈值应突出显示。
- B3 按键:“加”按键,按下后,被选择的阈值增加 5cm,增加到 95cm 为止。
- B4 按键:“减”按键,按下后,被选择的阈值减少 5cm,减少到 5cm 为止。
按键处理函数 void key_proc(void)
void key_proc(void)
{if(key[0].single_flag == 1) //如果按键1按下 短按{key[0].single_flag = 0; //按键清零lcd_view ++;if (lcd_view == 2) lcd_view = 0;//界面切换.两个界面LCD_Clear(White);//清LCD屏}if(key[1].single_flag == 1) //如果按键PB2按下 短按{key[1].single_flag = 0; //按键清零if (lcd_view == 1) //如果是阈值设置界面{//切换选择 3 个待修改的阈值,被选中的阈值应突出显示select_param_set ++; //选择参数设置 ++if (select_param_set == 3) select_param_set = 0;//参数设置切换.3个参数,一个保存写入}}if(key[2].single_flag == 1) //如果按键PB3按下 短按{key[2].single_flag = 0; //按键清零if (select_param_set == 0) //设置第一个参数{Threshold_1 += 5;if (Threshold_1 >= 95)Threshold_1 = 95;}else if (select_param_set == 1) //设置第二个参数{Threshold_2 += 5; if (Threshold_2 >= 95)Threshold_2 = 95;}else if (select_param_set == 2) //设置第三个参数{Threshold_3 += 5; if (Threshold_3 >= 95)Threshold_3 = 95;}} if(key[3].single_flag == 1) //如果按键PB4按下 短按{key[3].single_flag = 0; //按键清零 if (select_param_set == 0) //设置第一个参数{Threshold_1 -= 5; if (Threshold_1 <= 5)Threshold_1 = 5;}else if (select_param_set == 1) //设置第二个参数{Threshold_2 -= 5; if (Threshold_2 <= 5)Threshold_2 = 5;}else if (select_param_set == 2) //设置第三个参数{Threshold_3 -= 5; if (Threshold_3 <= 5)Threshold_3 = 5;}}
}
按键部分比较简单,注意越界判断,注意界面切换要清LCD屏
LCD高亮,这部分是我自己研究的,没有copy别人的代码,写的有些简陋了些
3.5 串口通信
每次接收一个字节
串口接收部分,没什么好讲的,看注释
这里需要使用sprintf函数,可以去菜鸟教程学一下
//串口的接收 回调函数
char rxdata[50];
uint8_t RX_Str_Data;
unsigned char rx_pointer; //自己定义的指针,判断接收到哪了void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{if (huart->Instance == USART1) // 如果是USART1{//数据处理部分if(RX_Str_Data == 'C') //只接收了一个字符,用这个变量判断即可{flag.IS_Receive = 1; //收到查询指令了sprintf(USART_tx_string, "C:H%d+L%d\r\n", height, yewei_level);HAL_UART_Transmit(&huart1, (uint8_t *)USART_tx_string, strlen(USART_tx_string), 50);}else if (RX_Str_Data == 'S'){flag.IS_Receive = 1; //收到查询指令了sprintf(USART_tx_string, "S:TL%d+TM%d+TH%d\r\n", Threshold_1, Threshold_2, Threshold_3);HAL_UART_Transmit(&huart1, (uint8_t *)USART_tx_string, strlen(USART_tx_string), 50);}rxdata[rx_pointer++] = RX_Str_Data; //接收到的字符串存放在这里HAL_UART_Receive_IT(&huart1, &RX_Str_Data, 1); //最后这个参数只能写1}
}
3.6 LCD显示
void disp_proc(void)
{if (lcd_view == 0){sprintf(LCD_Show_text, " Liquid Level ");LCD_DisplayStringLine(Line1, (uint8_t *)LCD_Show_text);sprintf(LCD_Show_text, " Height: %dcm ", height);LCD_DisplayStringLine(Line3, (uint8_t *)LCD_Show_text);// 显示ADCsprintf(LCD_Show_text, " ADC: %.2fV ", Vol_1S);LCD_DisplayStringLine(Line5, (uint8_t *)LCD_Show_text);sprintf(LCD_Show_text, " Level: %d ", yewei_level);LCD_DisplayStringLine(Line7, (uint8_t *)LCD_Show_text);//测试用例,查看数据的,写完用不到了
// sprintf(LCD_Show_text, " LED:%d %d Rx:%c ", flag.LED3_State,flag.LED3_ON_Cnt, RX_Str_Data);
// LCD_DisplayStringLine(Line8, (uint8_t *)LCD_Show_text);}//阈值设定界面if (lcd_view == 1){if (select_param_set == 0) //第一个参数{sprintf(LCD_Show_text, " Parameter Setup ");LCD_DisplayStringLine(Line1, (uint8_t *)LCD_Show_text);LCD_SetTextColor(Red); // 设置字体颜色sprintf(LCD_Show_text, " Threshold 1: %dcm ", Threshold_1);LCD_DisplayStringLine(Line4, (uint8_t *)LCD_Show_text);LCD_SetTextColor(Blue); // 设置字体颜色 sprintf(LCD_Show_text, " Threshold 2: %dcm ", Threshold_2);LCD_DisplayStringLine(Line6, (uint8_t *)LCD_Show_text);sprintf(LCD_Show_text, " Threshold 3: %dcm ", Threshold_3);LCD_DisplayStringLine(Line8, (uint8_t *)LCD_Show_text);}else if (select_param_set == 1) //第二个参数{sprintf(LCD_Show_text, " Parameter Setup ");LCD_DisplayStringLine(Line1, (uint8_t *)LCD_Show_text);LCD_SetTextColor(Blue); // 设置字体颜色sprintf(LCD_Show_text, " Threshold 1: %dcm ", Threshold_1);LCD_DisplayStringLine(Line4, (uint8_t *)LCD_Show_text);LCD_SetTextColor(Red); // 设置字体颜色sprintf(LCD_Show_text, " Threshold 2: %dcm ", Threshold_2);LCD_DisplayStringLine(Line6, (uint8_t *)LCD_Show_text);LCD_SetTextColor(Blue); // 设置字体颜色sprintf(LCD_Show_text, " Threshold 3: %dcm ", Threshold_3);LCD_DisplayStringLine(Line8, (uint8_t *)LCD_Show_text);}else if (select_param_set == 2) //第三个参数{sprintf(LCD_Show_text, " Parameter Setup ");LCD_DisplayStringLine(Line1, (uint8_t *)LCD_Show_text);LCD_SetTextColor(Blue); // 设置字体颜色sprintf(LCD_Show_text, " Threshold 1: %dcm ", Threshold_1);LCD_DisplayStringLine(Line4, (uint8_t *)LCD_Show_text);LCD_SetTextColor(Blue); // 设置字体颜色sprintf(LCD_Show_text, " Threshold 2: %dcm ", Threshold_2);LCD_DisplayStringLine(Line6, (uint8_t *)LCD_Show_text);LCD_SetTextColor(Red); // 设置字体颜色sprintf(LCD_Show_text, " Threshold 3: %dcm ", Threshold_3);LCD_DisplayStringLine(Line8, (uint8_t *)LCD_Show_text);LCD_SetTextColor(Blue); // 设置字体颜色}}
}
在不同的界面下显示不同的内容,用到一个标志位即可实现
3.7 LED显示
配置PC8~PC15、PD2
该板子是低电平点亮,8个led灯使用的是高8位所以需要左移8位,led等于几就是将高8位中第几位设置成低电平即点亮,由于led与lcd复用引脚最后打开锁存器让值被写入之后,立刻关闭锁存器防止影响LCD
void LED_proc(void)
{// LED1 数据if (flag.LED1_State == 0){flag.LED1_Data = 0x00; //0000 0000}else if (flag.LED1_State == 1){flag.LED1_Data = 0x01; //0000 0001}// LED2 数据if (flag.YeWei_IS_change == 1) //如果液位变化flag.YW_IS_Change_forLED = 1; //液位变化,LED的标志位置1if (flag.LED2_State == 0){flag.LED2_Data = 0x00; //0000 0000}else if (flag.LED2_State == 1){if (flag.YW_IS_Change_forLED == 1) //如果液位变化{flag.LED2_Data = 0x02; //0000 0010}}// LED3 数据if (flag.LED3_State == 0){flag.LED3_Data = 0x00; //0000 0000}else if (flag.LED3_State == 1){if (flag.IS_Receive == 1) //收到查询指令了{flag.LED3_Data = 0x04; //0000 0100} }// if (flag.IS_Receive == 1) //收到查询指令了
// {
// if (flag.LED3_State == 0) //
// {
// flag.LED3_Data = 0x00; //0000 0000
// }
// else if (flag.LED3_State == 1)
// {
// flag.LED3_Data = 0x04; //0000 0100
// ++ flag.LED3_ON_Cnt;
// if (flag.LED3_ON_Cnt > 5) //闪烁5次以上
// {
// flag.IS_Receive = 0; //先清零接收标志位
// flag.LED3_ON_Cnt = 0; //再清零闪烁次数,方便下一次闪烁指示
// }
// }
// } LED_Disp(flag.LED1_Data | flag.LED2_Data | flag.LED3_Data);
}
分析:
- LED1以1S为间隔亮灭闪烁:亮1S、灭1S、亮1S、灭1S……
- LED2以0.2S为间隔闪烁5次:0.2S亮灭一次,一秒内亮灭5次
- LED3以0.2S为间隔闪烁5次:0.2S亮灭一次,一秒内亮灭5次
用几个标志位控制LED的闪烁频率和次数,都是51单片机的基础操作,这里我就不多讲了,具体可以看代码~
这里用三个标志位,分别控制三个灯,最后调用LED显示函数,这样操作LED,他们之间互不影响
3.8 逻辑处理
void control_fun(void)
{if (flag.adc_readtime_ok == 1){Vol_1S = getADC(&hadc2); //ADC采集一次height = (uint16_t)(Vol_1S / 3.3f * 100);flag.adc_readtime_ok = 0;}//液位等级判断if (height <= Threshold_1)yewei_level = 0;else if (height > Threshold_1 && height <= Threshold_2)yewei_level = 1;else if (height > Threshold_2 && height <= Threshold_3)yewei_level = 2;else if (height > Threshold_3)yewei_level = 3;//液位等级变化 判断,串口发送数据if (yewei_level - flag.last_YW_state == 0) //液位等级没有变化{flag.YeWei_IS_change = 0; //液位是否变化标志位置0}else if (yewei_level - flag.last_YW_state > 0) //液位 上升{flag.YeWei_IS_change = 1; //液位是否变化标志位置1flag.YeWei_change_Dir = 1; //上升趋势}else if (yewei_level - flag.last_YW_state < 0) //液位 下降{flag.YeWei_IS_change = 1; //液位是否变化标志位置1flag.YeWei_change_Dir = 2; //下降趋势}flag.last_YW_state = yewei_level;if (flag.YeWei_IS_change == 1) //如果液位变化{
// flag.YW_IS_Change_forLED = 1; //液位变化,LED的标志位置1,放到后面的函数写了if (flag.YeWei_change_Dir == 1) //上升趋势{sprintf(USART_tx_string, "A:H%d+L%d+U\r\n", height, yewei_level);HAL_UART_Transmit(&huart1, (uint8_t *)USART_tx_string, strlen(USART_tx_string), 50);}else if (flag.YeWei_change_Dir == 2) //下降趋势{sprintf(USART_tx_string, "A:H%d+L%d+D\r\n", height, yewei_level);HAL_UART_Transmit(&huart1, (uint8_t *)USART_tx_string, strlen(USART_tx_string), 50);}}//EEPROM读写if (lcd_view == 0){if (flag.E2PROM_Write == 1){ //E2PROM 写入EEPROM_WriteByte(1, Threshold_1); //写入阈值1HAL_Delay(10); //延时10msEEPROM_WriteByte(2, Threshold_2); //写入阈值2HAL_Delay(10); //延时10msEEPROM_WriteByte(3, Threshold_3); //写入阈值3HAL_Delay(10); //延时10msflag.E2PROM_Write = 0; //复位,写一次即可,放在后面,写完flag.E2PROM_read = 1;}}else if (lcd_view == 1){flag.E2PROM_Write = 1; //调到阈值设定界面 置1,到第一个界面时候,才存储阈值参数if (flag.E2PROM_read == 1){//读出来的三个阈值都是95 怀疑有问题,把阈值上下限限制的判断,挪到按键里了,发现读出来的数据都变成255了//突然想到这里我没有初始化I2C引脚,被自己蠢笑了~~~哈哈哈,初始化PB6、PB7,按键也忘记初始化过...以后先找CubeMX~~~Threshold_1 = EEPROM_ReadByte(1);Threshold_2 = EEPROM_ReadByte(2);Threshold_3 = EEPROM_ReadByte(3);flag.E2PROM_read = 0;}}
}
3.9 main函数
原版
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_TIM4_Init();MX_ADC2_Init();MX_TIM3_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */LED_Disp(0x00); //LED初始化,全部熄灭LCD_Init(); //LCD初始化//定时器初始化HAL_TIM_Base_Start_IT(&htim3);HAL_TIM_Base_Start_IT(&htim4);LCD_Clear(White);//清LCD屏LCD_SetBackColor(White);LCD_SetTextColor(Blue);//上电先读取一遍Threshold_1 = EEPROM_ReadByte(1);Threshold_2 = EEPROM_ReadByte(2);Threshold_3 = EEPROM_ReadByte(3);HAL_UART_Receive_IT(&huart1, &RX_Str_Data, 1); //打开串口接收的初始化/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){key_proc();disp_proc();control_fun();LED_proc();/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}
初始化这里有点小Bug存在,我第一次写的时候没有解决这个问题,就是用E2PROM检测是否单片机为第一次上电
如果是第一次上电,那就初始化阈值参数,如果不是第一次上电,那就读取E2PROM里的数据作为阈值数据
修改
具体修改过的代码如下,我实际测试过,这样的写法可以实现我们预期效果,比较完美
直接放码过来~
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_TIM4_Init();MX_ADC2_Init();MX_TIM3_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */LED_Disp(0x00); //LED初始化,全部熄灭LCD_Init(); //LCD初始化//定时器初始化HAL_TIM_Base_Start_IT(&htim3);HAL_TIM_Base_Start_IT(&htim4);LCD_Clear(White);//清LCD屏LCD_SetBackColor(White);LCD_SetTextColor(Blue);//上电先读取一遍if (EEPROM_ReadByte(123) != 0xA5){Threshold_1 =30;Threshold_2 =50;Threshold_3 =70;EEPROM_WriteByte(123, 0xA5);}else{Threshold_1 = EEPROM_ReadByte(1);Threshold_2 = EEPROM_ReadByte(2);Threshold_3 = EEPROM_ReadByte(3);}HAL_UART_Receive_IT(&huart1, &RX_Str_Data, 1); //打开串口接收的初始化/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){key_proc();disp_proc();control_fun();LED_proc();/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}
4 电路设计
不会