关键代码:、
user.c:
cpp
u32 adc_tick = 0; // 定义一个无符号32位整型变量 adc_tick,用于记录上次ADC处理的时间戳
u32 r37_value = 0; // 定义一个无符号32位整型变量 r37_value,用于存储ADC通道2的采样值
u32 r38_value = 0; // 定义一个无符号32位整型变量 r38_value,用于存储ADC通道1的采样值
float r37_volt = 0; // 定义一个浮点型变量 r37_volt,用于存储ADC通道2的电压值
float r38_volt = 0; // 定义一个浮点型变量 r38_volt,用于存储ADC通道1的电压值
void ADC_proc()
{
if (uwTick - adc_tick < 100) // 如果当前系统时间与上次ADC处理的时间差小于100ms
return; // 退出函数,不执行ADC处理
adc_tick = uwTick; // 更新ADC处理时间为当前系统时间
HAL_ADC_Start(&hadc1); // 启动ADC1的转换
r38_value = HAL_ADC_GetValue(&hadc1); // 获取ADC1的采样值
r38_volt = r38_value * 3.3 / 4096; // 计算ADC1的电压值
HAL_ADC_Start(&hadc2); // 启动ADC2的转换
r37_value = HAL_ADC_GetValue(&hadc2); // 获取ADC2的采样值
r37_volt = r37_value * 3.3 / 4096; // 计算ADC2的电压值
}
u8 ui = 1; // 定义一个无符号8位整型变量 ui,用于控制LCD显示页面,默认值为1(数据页面)
u8 mode = 1; // 定义一个无符号8位整型变量 mode,用于控制工作模式,默认值为1(自动模式)
u8 pa6_duty = 10; // 定义一个无符号8位整型变量 pa6_duty,用于控制PWM输出占空比,默认值为10
u8 pa7_duty = 10; // 定义一个无符号8位整型变量 pa7_duty,用于控制PWM输出占空比,默认值为10
void KEY_proc()
{
// 处理按键操作,包括单击、长按、双击等情况
// 如果按键1单次按下
if (single_key_flag[0] == 1)
{
ui += 1; // 控制 LCD 显示页面切换
if (ui >= 3)
ui = 1; // 循环切换到第一页
LCD_Clear(Black); // 清除LCD屏幕
single_key_flag[0] = 0; // 清除按键1单击标志
}
// 如果按键2单次按下
if (single_key_flag[1] == 1)
{
if (ui == 2 && mode == 2) // 如果当前在参数页面且为手动模式
{
pa6_duty += 10; // 调节 PA6 的占空比,步进值为 10
if (pa6_duty >= 100)
pa6_duty = 10; // 循环设置占空比
__HAL_TIM_SetCompare(&htim16, TIM_CHANNEL_1, pa6_duty); // 设置 TIM16 的通道1的PWM占空比
single_key_flag[1] = 0; // 清除按键2单击标志
}
else
{
single_key_flag[1] = 0; // 清除按键2单击标志
}
}
// 如果按键3单次按下
if (single_key_flag[2] == 1)
{
if (ui == 2 && mode == 2) // 如果当前在参数页面且为手动模式
{
pa7_duty += 10; // 调节 PA7 的占空比,步进值为 10
if (pa7_duty >= 100)
pa7_duty = 10; // 循环设置占空比
__HAL_TIM_SetCompare(&htim17, TIM_CHANNEL_1, pa7_duty); // 设置 TIM17 的通道1的PWM占空比
single_key_flag[2] = 0; // 清除按键3单击标志
}
else
{
single_key_flag[2] = 0; // 清除按键3单击标志
}
}
// 如果按键4单次按下
if (single_key_flag[3] == 1)
{
mode += 1; // 切换工作模式
if (mode >= 3)
mode = 1; // 循环切换工作模式
single_key_flag[3] = 0; // 清除按键4单击标志
}
}
u8 pa6_duty_manu = 0; // 定义一个无符号8位整型变量 pa6_duty_manu,用于手动模式下控制PWM输出占空比
u8 pa7_duty_manu = 0; // 定义一个无符号8位整型变量 pa7_duty_manu,用于手动模式下控制PWM输出占空比
void PWM_AUTO()
{
if (mode == 1) // 如果当前工作模式为自动模式
{
pa6_duty_manu = r37_volt * 1000 / 33; // 根据ADC2的电压值计算PWM输出占空比
pa7_duty_manu = r37_volt * 1000 / 33; // 根据ADC2的电压值计算PWM输出占空比
__HAL_TIM_SetCompare(&htim16, TIM_CHANNEL_1, pa6_duty_manu); // 设置TIM16通道1的PWM占空比
__HAL_TIM_SetCompare(&htim17, TIM_CHANNEL_1, pa7_duty_manu); // 设置TIM17通道1的PWM占空比
}
}
u8 led_num = 0; // 定义一个无符号8位整型变量 led_num,用于控制LED显示
u32 led_tick = 0; // 定义一个无符号32位整型变量 led_tick,用于记录上次LED处理的时间戳
void LED_proc ()
{
if (uwTick - led_tick < 100) // 如果当前系统时间与上次LED处理的时间差小于100ms
return; // 退出函数,不执行LED操作
led_tick = uwTick; // 更新LED处理时间为当前系统时间
if (mode == 1) // 如果当前工作模式为自动模式
led_num |= 0x01; // 设置 led_num 的最低位为1,表示LED1亮;其他位保持不变
else // 如果当前工作模式为手动模式
led_num &= ~0x01; // 设置 led_num 的最低位为0,表示LED1灭;其他位保持不变
if (ui == 1) // 如果当前LCD显示页面为数据页面
led_num |= 0x02; // 设置 led_num 的次低位为1,表示
u32 lcd_tick = 0;
void Disp_proc()
{
// 检查距离上次LCD更新是否已经超过100ms
if (uwTick - lcd_tick < 100)
return; // 如果未超过100ms,则不执行LCD更新操作
lcd_tick = uwTick; // 更新LCD更新计时器
// 根据当前页面选择更新LCD显示内容
if (ui == 1)
{
u8 text[50];
// 在第一行显示日期
sprintf(text, " DATE ");
LCD_DisplayStringLine(Line1, (unsigned char *)text);
// 在第三行显示电压值
sprintf(text, " V:%.2f V ", r37_volt);
LCD_DisplayStringLine(Line3, (unsigned char *)text);
// 根据工作模式在第五行显示模式信息
if (mode == 1)
{
sprintf(text, " Mode:AUTO ");
LCD_DisplayStringLine(Line5, (unsigned char *)text);
}
else if (mode == 2)
{
sprintf(text, " Mode:MANU ");
LCD_DisplayStringLine(Line5, (unsigned char *)text);
}
}
else if (ui == 2)
{
u8 text[50];
// 在第一行显示参数页面标题
sprintf(text, " Para ");
LCD_DisplayStringLine(Line1, (unsigned char *)text);
// 根据工作模式显示对应参数值
if (mode == 1)
{
// 如果为自动模式,则显示自动模式下的参数值
sprintf(text, " PA6:%d ", pa6_duty_manu);
LCD_DisplayStringLine(Line3, (unsigned char *)text);
sprintf(text, " PA7:%d ", pa7_duty_manu);
LCD_DisplayStringLine(Line5, (unsigned char *)text);
}
else if (mode == 2)
{
// 如果为手动模式,则显示手动模式下的参数值
sprintf(text, " PA6:%d ", pa6_duty);
LCD_DisplayStringLine(Line3, (unsigned char *)text);
sprintf(text, " PA7:%d ", pa7_duty);
LCD_DisplayStringLine(Line5, (unsigned char *)text);
}
}
}
main.c:
cpp
int main(void)
{
/* USER CODE BEGIN 1 */
// 用户自定义代码段1
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
// MCU配置
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
// 重置所有外设,初始化Flash接口和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_TIM3_Init();
MX_TIM16_Init();
MX_TIM17_Init();
MX_ADC1_Init();
MX_ADC2_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
// 用户自定义代码段2
LED_disp (0); // LED显示初始化
HAL_TIM_Base_Start_IT(&htim3); // 启动定时器3并使能中断
LCD_Init(); // LCD屏幕初始化
HAL_TIM_PWM_Start(&htim16, TIM_CHANNEL_1); // 启动TIM16通道1的PWM输出
HAL_TIM_PWM_Start(&htim17, TIM_CHANNEL_1); // 启动TIM17通道1的PWM输出
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
// 无限循环
LCD_Clear(Black); // 清屏,背景色为黑色
LCD_SetBackColor(Black); // 设置背景色为黑色
LCD_SetTextColor(White); // 设置字体颜色为白色
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
// 用户自定义循环后代码段
ADC_proc(); // ADC数据处理
PWM_AUTO(); // PWM输出控制
KEY_proc(); // 按键处理
LED_proc (); // LED控制
Disp_proc (); // 显示处理
}
/* USER CODE END 3 */
}
LED显示状态:
cpp
u8 led_num = 0; // 定义一个无符号8位整型变量 led_num,初始化为 0
u32 led_tick = 0; // 定义一个无符号32位整型变量 led_tick,初始化为 0
void LED_proc()
{
if (uwTick - led_tick < 100) // 如果当前系统时间与上次 LED 操作时间的时间差小于 100ms
return; // 退出函数,不执行 LED 操作
led_tick = uwTick; // 更新 LED 操作时间为当前系统时间
if (mode == 1) // 如果 mode 变量的值为 1
led_num |= 0x01; // 将 led_num 的最低位设置为 1,即使 led_num 保持原值的其他位不变
else // 否则(mode 不为 1)
led_num &= ~0x01; // 将 led_num 的最低位设置为 0,其他位保持不变
if (ui == 1) // 如果 ui 变量的值为 1
led_num |= 0x02; // 将 led_num 的次低位设置为 1,其他位保持不变
else // 否则(ui 不为 1)
led_num &= ~0x02; // 将 led_num 的次低位设置为 0,其他位保持不变
LED_disp(led_num); // 调用 LED_disp 函数,根据 led_num 的值控制 LED 的显示
}
|=
是 C 语言中的赋值运算符,表示按位或运算并赋值。具体来说,它将左边的变量与右边的值进行按位或运算,然后将结果赋值给左边的变量。例如,
led_num |= 0x01;
就是将led_num
的当前值与0x01
进行按位或运算,然后将结果赋值给led_num
。这会将led_num
的最低位(即二进制的最右边一位)设置为 1,而其他位保持不变。
"&=" 是一个赋值运算符,它结合了按位与运算符 "&" 和赋值运算符 "="。它的作用是将左操作数和右操作数进行按位与运算,并将结果赋值给左操作数。而 "~" 是按位取反运算符,它将操作数的每一位取反,即将 0 变为 1,将 1 变为 0。因此,
led_num &= ~0x01;
表示将led_num
的值与 0x01(二进制为 0000 0001)进行按位与运算,然后将结果赋值给led_num
。具体地,它会将led_num
的最低位清零,其他位保持不变。
自动模式下的ADC:
cpp
void PWM_AUTO()
{
if (mode == 1) // 如果当前工作模式为自动模式
{
pa6_duty_manu = r37_volt * 1000 / 33; // 根据ADC2的电压值计算PWM输出占空比
pa7_duty_manu = r37_volt * 1000 / 33; // 根据ADC2的电压值计算PWM输出占空比
__HAL_TIM_SetCompare(&htim16, TIM_CHANNEL_1, pa6_duty_manu); // 设置TIM16通道1的PWM占空比
__HAL_TIM_SetCompare(&htim17, TIM_CHANNEL_1, pa7_duty_manu); // 设置TIM17通道1的PWM占空比
}
}