博主上午比赛完下午就开源
开源时间---2024年4月13日下午
前言:本人有一定的嵌入式基础做过不少的项目,拿过十几个省级奖项和一个国一
蓝桥杯嵌入式比赛是一个专业性较强的赛事,它主要考察参赛者在STM32微控制器编程和电子学科基础知识方面的能力。以下是对蓝桥杯嵌入式比赛的一些具体分析:
- 竞赛内容:蓝桥杯嵌入式组比赛采用STM32G431RBT6 (ARM Cortex M4)作为指定芯片。比赛内容包括客观题和基于硬件平台的程序设计与调试,其中客观题占比15%,程序设计与调试占比85%。
- 竞赛要求:参赛者需要具备扎实的C语言编程能力、模拟/数字电子技术基础、熟悉ARM Cortex M4硬件资源以及软件编程与调试知识。此外,熟悉相关软硬件环境和工具也是必不可少的。
- 备赛建议:对于准备参加比赛的学生来说,C语言是学习的基础,尤其是位运算和指针等重要概念需要熟练掌握。建议可以从51单片机入手,使用C语言编写代码,实现基本的灯光控制、串口通信等功能,这有助于培养对单片机编程的兴趣和实践能力。
- 难度与挑战:由于蓝桥杯嵌入式比赛涉及的内容较为专业和深入,因此对于大一或初学者来说可能存在一定的难度。但通过系统的学习和实践,可以逐步提升自己在嵌入式领域的技能。
- 赛事影响:蓝桥杯作为国内知名的IT类竞赛之一,其嵌入式组比赛对于参赛者的专业成长和就业有一定的积极影响。通过参加比赛,学生不仅能够检验自己的学习成果,还有机会获得奖项,增加个人履历的亮点。
蓝桥杯嵌入式比赛是一个对参赛者专业技能有较高要求的赛事,适合有一定基础的学生参加。通过比赛,学生可以提升自己的实际操作能力和解决实际问题的能力,为未来的学习和工作打下坚实的基础。
真题
视频环节
蓝桥杯十五届
省赛LCD菜单模块
主要业务代码:
LCD扫描代码
/*
这段代码是一个名为LCD_Scan的函数,用于在LCD屏幕上显示不同的信息。根据不同的条件,它会显示不同的数据和参数。
1. 如果Data_LCD为真,表示需要显示数据:
- 显示"DATA"在第一行;
- 如果A_1KHZ_flag为1,显示"A=%.2fKHz"在第三行,其中A_FLOAT是A的频率值;
- 如果A_1KHZ_flag为0且freq_A_Out_flag为0,显示"A=%dHz"在第三行,其中A是A的频率值;
- 如果B_1KHZ_flag为1,显示"B=%.2fKHz"在第四行,其中B_FLOAT是B的频率值;
- 如果B_1KHZ_flag为0且freq_B_Out_flag为0,显示"B=%dHz"在第四行,其中B是B的频率值;
- 如果freq_A_Out_flag为1,显示"A=NULL"在第三行;
- 如果freq_B_Out_flag为1,显示"B=NULL"在第四行。
2. 如果Data_LCD_T为真,表示需要显示时间数据:
- 显示"DATA"在第一行;
- 如果A_T_ms_flag为1,显示"A=%.2fmS"在第三行,其中A_T_FLOAT是A的时间值;
- 如果A_T_ms_flag为0且freq_B_Out_flag为0,显示"A=%.0fuS"在第三行,其中A_T是A的时间值;
- 如果B_T_ms_flag为1,显示"B=%.2fmS"在第四行,其中B_T_FLOAT是B的时间值;
- 如果B_T_ms_flag为0且freq_B_Out_flag为0,显示"B=%.0fuS"在第四行,其中B_T是B的时间值;
- 如果freq_A_Out_flag为1,显示"A=NULL"在第三行;
- 如果freq_B_Out_flag为1,显示"B=NULL"在第四行。
3. 如果argument_LCD为真,表示需要显示参数:
- 显示"PARA"在第一行;
- 显示"PD=%d"在第三行,其中P_D是参数D的值;
- 显示"PH=%d"在第四行,其中P_H是参数H的值;
- 显示"PX=%d"在第五行,其中P_X是参数X的值。
4. 如果Statistics_LCD为真,表示需要显示统计信息:
- 显示"RECD"在第一行;
- 显示"NHA=%d"在第五行,其中NHA是统计信息A的值;
- 显示"NHB=%d"在第六行,其中NHB是统计信息B的值;
- 如果NDA大于0,显示"NDA=%d"在第三行,其中NDA是统计信息C的值减1;
- 如果NDB大于0,显示"NDB=%d"在第四行,其中NDB是统计信息D的值减1;
- 如果NDA等于0,显示"NDA=%d"在第三行,其中NDA是统计信息C的值;
- 如果NDB等于0,显示"NDB=%d"在第四行,其中NDB是统计信息D的值。
*/
void LCD_Scan(void)
{
char str[50];
if(Data_LCD)
{
sprintf(str," DATA");
LCD_DisplayStringLine_char(Line1,str);
if(A_1KHZ_flag==1)
{
sprintf(str," A=%.2fKHz ",A_FLOAT);
LCD_DisplayStringLine_char(Line3,str);
}
else if(A_1KHZ_flag==0 && freq_A_Out_flag==0)
{
sprintf(str," A=%dHz ",A);
LCD_DisplayStringLine_char(Line3,str);
}
if(B_1KHZ_flag==1)
{
sprintf(str," B=%.2fKHz ",B_FLOAT);
LCD_DisplayStringLine_char(Line4,str);;
}
else if(B_1KHZ_flag==0 && freq_B_Out_flag==0)
{
sprintf(str," B=%dHz ",B);
LCD_DisplayStringLine_char(Line4,str);
}
if(freq_A_Out_flag==1)
{
sprintf(str," A=NULL ");
LCD_DisplayStringLine_char(Line3,str);
}
if(freq_B_Out_flag==1)
{
sprintf(str," B=NULL ");
LCD_DisplayStringLine_char(Line4,str);
}
}
else if(Data_LCD_T)
{
sprintf(str," DATA");
LCD_DisplayStringLine_char(Line1,str);
if(A_T_ms_flag==1)
{
sprintf(str," A=%.2fmS ",A_T_FLOAT);
LCD_DisplayStringLine_char(Line3,str);
}
else if(A_T_ms_flag==0 && freq_B_Out_flag==0)
{
sprintf(str," A=%.0fuS ",A_T);
LCD_DisplayStringLine_char(Line3,str);
}
if(B_T_ms_flag==1)
{
sprintf(str," B=%.2fmS ",B_T_FLOAT);
LCD_DisplayStringLine_char(Line4,str);
}
else if(B_T_ms_flag==0 && freq_B_Out_flag==0)
{
sprintf(str," B=%.0fuS ",B_T);
LCD_DisplayStringLine_char(Line4,str);
}
if(freq_A_Out_flag==1)
{
sprintf(str," A=NULL ");
LCD_DisplayStringLine_char(Line3,str);
}
if(freq_B_Out_flag==1)
{
sprintf(str," B=NULL ");
LCD_DisplayStringLine_char(Line4,str);
}
}
else if(argument_LCD)
{
sprintf(str," PARA");
LCD_DisplayStringLine_char(Line1,str);
sprintf(str," PD=%d ",P_D);
LCD_DisplayStringLine_char(Line3,str);
sprintf(str," PH=%d ",P_H);
LCD_DisplayStringLine_char(Line4,str);
sprintf(str," PX=%d ",P_X);
LCD_DisplayStringLine_char(Line5,str);
}
else if(Statistics_LCD)
{
sprintf(str," RECD");
LCD_DisplayStringLine_char(Line1,str);
sprintf(str," NHA=%d ",NHA);
LCD_DisplayStringLine_char(Line5,str);
sprintf(str," NHB=%d ",NHB);
LCD_DisplayStringLine_char(Line6,str);
if(NDA>0)
{
sprintf(str," NDA=%d ",NDA-1);
LCD_DisplayStringLine_char(Line3,str);
}
if(NDB>0)
{
sprintf(str," NDB=%d ",NDB-1);
LCD_DisplayStringLine_char(Line4,str);
}
if(NDA==0)
{
sprintf(str," NDA=%d ",NDA);
LCD_DisplayStringLine_char(Line3,str);
}
if(NDB==0)
{
sprintf(str," NDB=%d ",NDB);
LCD_DisplayStringLine_char(Line4,str);
}
}
}
频率测量以及参数合法性判断代码
void Capture_Init(void)
{
HAL_TIM_IC_Start(&htim3, TIM_CHANNEL_2);//开启输入捕获
HAL_TIM_IC_Start(&htim3, TIM_CHANNEL_1);//开启输入捕获
// HAL_TIM_IC_Start_IT(&htim16, TIM_CHANNEL_1);//开启输入捕获
HAL_TIM_IC_Start_IT(&htim8, TIM_CHANNEL_1);//开启输入捕获
}
//定时器2,3,8 主从触发模式输入捕获测量频率函数
float TIM_IC_Capture_GetFreq(TIM_HandleTypeDef *htim,uint32_t channel)
{
uint32_t capture_value=0;
float fre;
capture_value = HAL_TIM_ReadCapturedValue(htim, channel); //在捕获到上升沿时,会将CNT赋值给CCR
fre = 1000000/(capture_value+1);
return fre;
}
//定时器2,3,8 主从触发模式输入捕获测量占空比函数
float TIM_IC_Capture_GetDuty(TIM_HandleTypeDef *htim,uint32_t chan1,uint32_t chan2,TIM_HandleTypeDef *htim1)
{
float Duty;
uint16_t Autoreload=0;
Autoreload=htim1->Instance->ARR+1;
Duty=(HAL_TIM_ReadCapturedValue(htim, chan2)+1) * Autoreload / (HAL_TIM_ReadCapturedValue(htim,chan1) + 1);
return Duty;
}
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
uint32_t capture_value=0;
if(htim->Instance == TIM16)
{
//capture_value = TIM17->CCR1;
capture_value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); //在捕获到上升沿时,会将CNT赋值给CCR
TIM16->CNT = 0;
fre = 1000000/(capture_value+1);
}
}
void Capture_GetFreq(void)
{
// 获取定时器8通道1的输入捕获频率,并存储到变量A中
A = TIM_IC_Capture_GetFreq(&htim8, TIM_CHANNEL_1);
// 获取定时器3通道1的输入捕获频率,并存储到变量B中
B = TIM_IC_Capture_GetFreq(&htim3, TIM_CHANNEL_1);
// 计算输出频率A和B,分别加上P_X
freq_A_Out = A + P_X;
freq_B_Out = B + P_X;
// 将输出频率A和B转换为浮点数,并除以1000
A_FLOAT = (float)freq_A_Out / 1000;
B_FLOAT = (float)freq_B_Out / 1000;
// 计算时间间隔A和B,分别为1/输出频率A和B乘以1000000
A_T = (float)1 / freq_A_Out * 1000000;
B_T = (float)1 / freq_B_Out * 1000000;
// 将时间间隔A和B转换为毫秒,并除以1000
A_T_FLOAT = (float)1 / freq_A_Out * 1000;
B_T_FLOAT = (float)1 / freq_B_Out * 1000;
// 根据NHA_flag的值,判断是否需要更新NHA的值
if (NHA_flag == 0)
{
if (freq_A_Out > P_H)
{
NHA_flag = 1;
NHA++;
}
}
else
{
if ( freq_A_Out < P_H)
{
NHA_flag = 0;
}
}
// 根据NHB_flag的值,判断是否需要更新NHB的值
if (NHB_flag == 0)
{
if (freq_B_Out > P_H)
{
NHB_flag = 1;
NHB++;
}
}
else
{
if (freq_B_Out < P_H)
{
NHB_flag = 0;
}
}
// 根据输出频率A和B的大小,设置相应的标志位
if (freq_A_Out > 1000)
{
A_1KHZ_flag = 1;
}
else
{
if (freq_A_Out < 0)
{
freq_A_Out_flag = 1;
A_1KHZ_flag = 0;
}
else
{
freq_A_Out_flag = 0;
A_1KHZ_flag = 0;
}
}
if (freq_B_Out > 1000)
{
B_1KHZ_flag = 1;
}
else
{
if (freq_B_Out < 0)
{
freq_B_Out_flag = 1;
B_1KHZ_flag = 0;
}
else
{
freq_B_Out_flag = 0;
B_1KHZ_flag = 0;
}
}
// 根据时间间隔A和B的大小,设置相应的标志位
if (A_T > 1000)
{
A_T_ms_flag = 1;
}
else
A_T_ms_flag = 0;
if (B_T > 1000)
{
B_T_ms_flag = 1;
}
else
B_T_ms_flag = 0;
// 根据P_D、P_H和P_X的值,进行范围限制
if (P_D < 100 || P_D > 1000)
{
if (P_D < 100)
{
P_D = 100;
}
if (P_D > 1000)
{
P_D = 1000;
}
}
if (P_H < 1000 || P_H > 10000)
{
if (P_H < 1000)
{
P_H = 1000;
}
if (P_H > 10000)
{
P_H = 10000;
}
}
if (P_X < -1000 || P_X > 1000)
{
if (P_X < -1000)
{
P_X = -1000;
}
if (P_X > 1000)
{
P_X = 1000;
}
}
}
LED扫描代码
#define LED_ALL_MODE_ON HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET)
#define LED_ALL_MODE_OFF HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET)
#define LED1_ON HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_RESET)
#define LED1_OFF HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_SET)
#define LED2_ON HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,GPIO_PIN_RESET)
#define LED2_OFF HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,GPIO_PIN_SET)
#define LED3_ON HAL_GPIO_WritePin(GPIOC,GPIO_PIN_10,GPIO_PIN_RESET)
#define LED3_OFF HAL_GPIO_WritePin(GPIOC,GPIO_PIN_10,GPIO_PIN_SET)
#define LED4_ON HAL_GPIO_WritePin(GPIOC,GPIO_PIN_11,GPIO_PIN_RESET)
#define LED4_OFF HAL_GPIO_WritePin(GPIOC,GPIO_PIN_11,GPIO_PIN_SET)
#define LED5_ON HAL_GPIO_WritePin(GPIOC,GPIO_PIN_12,GPIO_PIN_RESET)
#define LED5_OFF HAL_GPIO_WritePin(GPIOC,GPIO_PIN_12,GPIO_PIN_SET)
#define LED6_ON HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET)
#define LED6_OFF HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET)
#define LED7_ON HAL_GPIO_WritePin(GPIOC,GPIO_PIN_14,GPIO_PIN_RESET)
#define LED7_OFF HAL_GPIO_WritePin(GPIOC,GPIO_PIN_14,GPIO_PIN_SET)
#define LED8_ON HAL_GPIO_WritePin(GPIOC,GPIO_PIN_15,GPIO_PIN_RESET)
#define LED8_OFF HAL_GPIO_WritePin(GPIOC,GPIO_PIN_15,GPIO_PIN_SET)
void Close_LED(void)
{
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);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}
void Close_LED_UESER(void)
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_11 |
GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}
void Open_LED(void)
{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}
void LED_Scan(void)
{
// 如果Data_LCD或Data_LCD_T为真,则关闭LED用户模式,打开LED1,然后打开LED
if(Data_LCD||Data_LCD_T)
{
Close_LED_UESER();
LED1_ON;
Open_LED();
}
// 否则,关闭LED1,打开LED,然后关闭LED用户模式
else
{
LED1_OFF;
Open_LED();
Close_LED_UESER();
}
// 如果freq_A_Out大于P_H,则关闭LED用户模式,打开LED2,然后打开LED
if(freq_A_Out>P_H)
{
Close_LED_UESER();
LED2_ON;
Open_LED();
}
// 否则,关闭LED用户模式,关闭LED2,然后打开LED
else
{
Close_LED_UESER();
LED2_OFF;
Open_LED();
}
// 如果freq_B_Out大于P_H,则关闭LED用户模式,打开LED3,然后打开LED
if(freq_B_Out>P_H)
{
Close_LED_UESER();
LED3_ON;
Open_LED();
}
// 否则,关闭LED用户模式,关闭LED3,然后打开LED
else
{
Close_LED_UESER();
LED3_OFF;
Open_LED();
}
// 如果flag_A_3或flag_B_3为真,则关闭LED用户模式,打开LED8,然后打开LED
if(flag_A_3==1||flag_B_3==1)
{
Close_LED_UESER();
LED8_ON;
Open_LED();
}
}
按键扫描代码
typedef enum
{
KEY_Check, //按键检测
KEY_Press, //按键按下
KEY_Release, //按键释放
Key_Over,
}KEY_State;
uint16_t Num=0;
uint8_t KEY_Value=0;
KEY_State KeyState=KEY_Check; //定义结构体
uint8_t KEY_Flag = 0;
uint32_t KEY_Press_TIME=20;
/*
uint8_t Key_GetNum(void)
{
uint8_t KeyNum = 0;
if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == 0)
{
HAL_Delay(20);
while (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == 0);
HAL_Delay(20);
KeyNum = 1;
}
if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == 0)
{
HAL_Delay(20);
while (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == 0);
HAL_Delay(20);
KeyNum = 2;
}
return KeyNum;
}
*/
void KeyScan(void)
{
switch(KeyState)
{
case KEY_Check:
{
if((B1==GPIO_PIN_RESET)||(B2==GPIO_PIN_RESET)||(B3==GPIO_PIN_RESET)||(B4==GPIO_PIN_RESET))KeyState=KEY_Press;
}
break;
case KEY_Press:
{
if(B1==GPIO_PIN_RESET)KEY_Value=1;
else if(B2==GPIO_PIN_RESET)KEY_Value=2;
else if(B3==GPIO_PIN_RESET)KEY_Value=3;
else if(B4==GPIO_PIN_RESET)KEY_Value=4;
KeyState=KEY_Release;
}
break;
case KEY_Release:
{
if((B1==GPIO_PIN_RESET)||(B2==GPIO_PIN_RESET)||(B3==GPIO_PIN_RESET)||(B4==GPIO_PIN_RESET))
{
KEY_Press_TIME=KEY_Press_TIME+10;
}
else
{
KeyState=KEY_Check;
KEY_Flag=1;
}
}
break;
default:break;
}
}
/**
* @brief This function handles System tick timer.
*/
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
static uint8_t Key_Start_Time=0;
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */
if(++Key_Start_Time==10)
{
Key_Start_Time=0;
KeyScan();
}
/* USER CODE END SysTick_IRQn 1 */
}
```c
if(KEY_Flag==1) //按键 滴答定时器扫描按锿
{
KEY_Flag=0;
// 根据按键值进行相应操作
if(KEY_Value==1){
// 如果argument_LCD_flag为0,P_D增加100
if(argument_LCD_flag==0)
{
P_D+=100;
}
// 如果argument_LCD_flag为1,P_H增加100
else if(argument_LCD_flag==1)
{
P_H+=100;
}
// 如果argument_LCD_flag为2,P_X增加100
else if(argument_LCD_flag==2)
{
P_X+=100;
}
}
else if(KEY_Value==2){
// 如果argument_LCD_flag为0,P_D减少100
if(argument_LCD_flag==0)
{
P_D-=100;
}
// 如果argument_LCD_flag为1,P_H减少100
else if(argument_LCD_flag==1)
{
P_H-=100;
}
// 如果argument_LCD_flag为2,P_X减少100
else if(argument_LCD_flag==2)
{
P_X-=100;
}
}
else if(KEY_Value==3 && KEY_Press_TIME<=1000){
// 如果Data_LCD为真,清屏并设置背景色、文本颜色等
if(Data_LCD)
{
LCD_Clear(Black);
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
Data_LCD_T=1;Data_LCD=0,argument_LCD=0,Statistics_LCD=0;
}
// 如果Data_LCD_T为真,清屏并设置背景色、文本颜色等
else if(Data_LCD_T)
{
LCD_Clear(Black);
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
Data_LCD_T=0;Data_LCD=1,argument_LCD=0,Statistics_LCD=0;
}
// 如果argument_LCD为真,argument_LCD_flag加1,如果超过2则重置为0
else if(argument_LCD)
{
argument_LCD_flag++;
if(argument_LCD_flag==3)
{
argument_LCD_flag=0;
}
}
}
else if(KEY_Value==3 && KEY_Press_TIME>1000){
// 如果Statistics_LCD为真,重置NDA、NDB、NHA、NHB、flag_A_3、flag_B_3的值
if(Statistics_LCD)
{
NDA=0;
NDB=0;
NHA=0;
NHB=0;
flag_A_3=0;
flag_B_3=0;
}
}
else if(KEY_Value==4){
// 如果Data_LCD为真,清屏并设置背景色、文本颜色等
if(Data_LCD)
{
LCD_Clear(Black);
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
Data_LCD=0,argument_LCD=1,Statistics_LCD=0,Data_LCD_T=0;;
}
// 如果Data_LCD_T为真,清屏并设置背景色、文本颜色等
else if(Data_LCD_T)
{
LCD_Clear(Black);
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
Data_LCD=0,argument_LCD=1,Statistics_LCD=0,Data_LCD_T=0;;
}
// 如果argument_LCD为真,清屏并设置背景色、文本颜色等,将argument_LCD_flag设置为0,将Data_LCD、argument_LCD、Statistics_LCD设置为相应的值
else if(argument_LCD)
{
LCD_Clear(Black);
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
argument_LCD_flag=0;
Data_LCD=0,argument_LCD=0,Statistics_LCD=1,Data_LCD_T=0;;
}
// 如果Statistics_LCD为真,清屏并设置背景色、文本颜色等,将Data_LCD、argument_LCD、Statistics_LCD设置为相应的值
else if(Statistics_LCD)
{
LCD_Clear(Black);
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
Data_LCD=1,argument_LCD=0,Statistics_LCD=0,Data_LCD_T=0;;
}
}
// 将KEY_Press_TIME设置为20
KEY_Press_TIME=20;
}
```
初始化代码
uint32_t ADC_Value[2]; // [0]为R37的模拟忿,[1]为R38的模拟忿
extern Uart_Tpye_t Uart1; // 外部定义的UART类型变量Uart1
uint32_t fre_PWM, fre_555, Duty; // PWM频率、555定时器频率和占空比
uint32_t P_H = 5000, P_D = 1000; // 设置P_H和P_D的初始值
int P_X = 0; // 初始化P_X变量
int freq_A_Out, freq_B_Out; // 定义频率输出变量A和B
uint8_t Data_LCD = 1, argument_LCD = 0, Statistics_LCD = 0, Data_LCD_T = 0; // LCD显示数据和参数变量
extern uint32_t A, B, NDA, NDB, NHA, NHB; // 外部定义的A、B、NDA、NDB、NHA、NHB变量
extern float A_FLOAT, B_FLOAT, A_T, B_T; // 外部定义的浮点型A、B、A_T、B_T变量
extern uint8_t flag_A_3, flag_B_3; // 外部定义的标志位变量flag_A_3和flag_B_3
uint8_t A_1KHZ_flag, B_1KHZ_flag, A_T_ms_flag, B_T_ms_flag, freq_A_Out_flag, freq_B_Out_flag, NHA_flag, NHB_flag, argument_LCD_flag, NDA_flag, NDB_flag; // 各种标志位变量
Capture_Init(); //输入捕获初始匿
TIM_init(); //定时器初始化
LCD_Clear(Black);
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
// LCD_Test();
HAL_ADC_Start_DMA(&hadc2,&ADC_Value[0],1); //以DMA的方式开启ADC2转换
HAL_ADC_Start_DMA(&hadc1,&ADC_Value[1],1); //以DMA的方式开启ADC1转换
__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);//打开串口空闲中断
HAL_UART_Receive_DMA(&huart1, Uart1.RxBuf, RX_MAXLEN); //串口DMA接收数据
定时器扫描频率代码,3秒一个周期
uint8_t flag_A_3,flag_B_3; // 定义标志位变量
uint32_t count; // 定义计数变量
uint32_t max_A,min_A=100000,max_B,min_B=100000,m_A_OUT,m_B_OUT; // 定义最大值、最小值和差值变量
extern uint32_t A,B,NDA,NDB,NHA,NHB; // 声明外部变量
extern int freq_A_Out,freq_B_Out; // 声明外部变量
extern uint32_t P_H,P_D; // 声明外部变量
extern int P_X; // 声明外部变量
extern uint8_t A_1KHZ_flag,B_1KHZ_flag,A_T_ms_flag,B_T_ms_flag,freq_A_Out_flag,freq_B_Out_flag,NHA_flag,NHB_flag,NDA_flag,NDB_flag; // 声明外部变量
void TIM_init(void) // 定时器初始化函数
{
HAL_TIM_Base_Start_IT(&htim6); // 启动定时器中断
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) // 定时器中断回调函数
{
if(htim->Instance==TIM6) // 判断是否为TIM6定时器
{
if(NDA==4||NDB==4) // 如果NDA或NDB等于4
{
flag_A_3=1; // 设置标志位A_3为1
flag_B_3=1; // 设置标志位B_3为1
}
count++; // 计数加1
if(freq_A_Out>max_A) // 如果freq_A_Out大于max_A
max_A=freq_A_Out; // 更新max_A的值
if(freq_A_Out<min_A) // 如果freq_A_Out小于min_A
min_A=freq_A_Out; // 更新min_A的值
if(freq_B_Out>max_B) // 如果freq_B_Out大于max_B
max_B=freq_B_Out; // 更新max_B的值
if(freq_A_Out<min_B) // 如果freq_A_Out小于min_B
min_B=freq_A_Out; // 更新min_B的值
if(count>=300) // 如果计数大于等于300
{
count=0; // 重置计数
m_A_OUT=max_A-min_A; // 计算差值A
m_B_OUT=max_B-min_B; // 计算差值B
if(m_A_OUT>P_D) // 如果差值A大于P_D
{
NDA++; // NDA加1
}
if(m_B_OUT>P_D) // 如果差值B大于P_D
{
NDB++; // NDB加1
}
max_A=0;min_A=100000; // 重置最大值和最小值A
max_B=0;min_B=100000; // 重置最大值和最小值B
m_A_OUT=0; // 重置差值A
m_B_OUT=0; // 重置差值B
}
}
}