蓝桥杯嵌入式(G431)备赛笔记——第十一届第二场真题

关键代码:、

user.c:

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:

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显示状态:

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:

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占空比
    }
}

完整工程:

https://download.csdn.net/download/WYW35416/89114759?spm=1001.2014.3001.5501&ydreferer=aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1dZVzM1NDE2P3NwbT0xMDExLjI0MTguMzAwMS41MzQz

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 蓝桥杯是全国性的计算机大赛,旨在提高大学生的计算机技术水平和创新能力。嵌入式STM32G431是一款嵌入式芯片,具有高性能和低功耗的特点。第十二届第一场省赛停车计费系统是蓝桥杯的一道工程题目,要求参赛选手设计一个停车场计费系统。 停车计费系统是指通过嵌入式技术实现对车辆进入和离开停车场的自动检测、计时和计费的系统。对于这个题目,参赛选手可以根据题目要求,使用STM32G431芯片设计一个具有以下功能的系统: 1. 车辆进入检测:使用车辆传感器检测车辆的进入,触发计时。 2. 车辆离开检测:使用车辆传感器检测车辆的离开,停止计时。 3. 计时功能:使用内部时钟模块获取进入和离开的时间,并计算停车时间。 4. 计费功能:根据停车时间,按照一定的计费规则进行计费。 5. 显示功能:使用液晶显示屏显示当前的停车信息,如车牌号、停车时间、费用等。 6. 数据存储功能:使用闪存等储存介质将停车数据进行存储,以便后续的数据分析和查询。 设计一个停车计费系统涉及到硬件设计和软件编程两个方面。硬件方面,参赛选手需要选择合适的传感器、显示屏、存储介质等,以及设计电路和接口进行连接。软件方面,需要使用C语言或者汇编语言编写程序,对芯片进行编程,实现各项功能。 通过此次比赛,选手们可以锻炼嵌入式系统的设计能力和编程能力,了解实际应用中嵌入式系统的工作原理和应用场景。同时,也能提升对STM32G431芯片的理解和运用能力。这对于培养嵌入式技术人才,推动物联网技术的发展都具有积极意义。 ### 回答2: 蓝桥杯是面向计算机爱好者的智力竞赛,而嵌入式STM32G431是一款嵌入式系统开发板。第十二届第一场省赛的停车计费系统真题工程,则是要求参赛选手设计并实现一个能够进行停车计费的系统。 停车计费系统是一种用于自动计费和管理停车场的系统。这个系统可以通过识别车辆的进出以及停车的时间,自动计算并收费。在这个工程中,选手需要使用嵌入式STM32G431开发板以及相关的硬件和软件,来设计一个能够实现停车计费功能的系统。 首先,选手需要使用传感器或摄像头来实现车辆进出的检测。当车辆进入或离开停车场时,传感器会发出信号并通过STM32G431进行检测。接着,选手需要编程实现识别车辆的算法,以便能够识别不同的车辆。当车辆停放时,系统会通过计时器记录停车的时间。 然后,选手需要编写计费算法,根据停车的时间来计算费用。这个算法可以根据停车场的规则来确定费用的计算方式,例如按小时计费或按照不同的时间段采用不同的费率。 最后,选手还需要设计一个界面,使得系统能够与用户进行交互。用户可以通过该界面查询停车费用,并进行付款。同时,选手还需要保证系统的稳定性和安全性,确保数据的准确性和保密性。 总而言之,蓝桥杯嵌入式STM32G431第十二届第一场省赛停车计费系统真题工程要求选手使用硬件和软件开发能力,设计并实现一个完整的停车计费系统。这需要选手具备嵌入式系统开发、传感器技术、算法设计和界面设计等多方面的知识和技能。 ### 回答3: 蓝桥杯嵌入式stm32g431——第十二届第一场省赛停车计费系统真题工程是一个基于STM32G431开发板的停车计费系统设计题目。该系统的主要功能是实现停车场的车辆进入、出场的计费管理。 首先,该系统需要实现一个车辆进入检测的功能。当车辆进入停车场时,系统会通过传感器检测到车辆的到达,并记录下进入的时间。 然后,系统需要实现一个车辆出场的功能。当车辆准备离开停车场时,系统会通过传感器检测到车辆的离开,并记录下离开的时间。 接下来,系统需要计算车辆停留的时间。通过进入时间和离开时间的差值计算得出车辆停留的时长。 最后,系统需要计算停车费用。根据停车场的计费规则,根据车辆停留的时长计算出停车费用,并将费用显示在屏幕上。 在实现上述功能的过程中,需要运用STM32G431开发板的各种功能和模块,包括GPIO口、定时器、中断、串口通信等。通过编写相应的代码,实现按钮的控制、传感器检测、时间的计算以及屏幕的显示等功能。 该项目的设计需要考虑多种情况,比如车辆重复进入出场、车辆进入出场顺序错乱等,要充分考虑这些异常情况并进行相应的处理。在代码编写过程中,还需注意代码的优化和资源的合理利用,以提高系统的性能和效率。 通过完成这个项目的设计与实现,可以加深对STM32G431嵌入式系统的了解和应用,并提升嵌入式系统开发的能力。同时,也能锻炼自己的逻辑思维、问题解决能力和团队合作精神。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玄奕子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值