赞
踩
- void lcd_proc(void)
- {
- char text[30];
- VR37=getADC(&hadc2);
- if(view)//数据界面
- {
- sprintf(text," DATA ");
- LCD_DisplayStringLine(Line3,(uchar*)text);
- sprintf(text," VR37:%.2lfV ",VR37);
- LCD_DisplayStringLine(Line4,(uchar*)text);
- sprintf(text," PA7:%dHz ",PA7);
- LCD_DisplayStringLine(Line5,(uchar*)text);
- }else//参数设置界面
- {
- sprintf(text," PARA ");
- LCD_DisplayStringLine(Line3,(uchar*)text);
- sprintf(text," VP1:%.1lfV ",VP1);
- LCD_DisplayStringLine(Line4,(uchar*)text);
- }
- }

这个按照题目要求来就是了,没有什么需要注意的地方。
- void key_proc(void)
- {
- if(keys[0].single_flag==1)//按键B1 切换界面
- {
- view=!view;
- LCD_Clear(Black);
- keys[0].single_flag=0;//防止重复
- }else if(keys[1].single_flag==1)//按键B2
- {
- if(view==0)//只在参数界面有效
- {
- VP1+=0.3;
- if(VP1>=3.4) VP1=0.0;
- }
- keys[1].single_flag=0;
- }else if(keys[2].single_flag==1)//按键B3
- {
- if(view==1)//只在数据界面有效
- {
- PA7+=1000;
- if(PA7>=11000) PA7=1000;
- value=1000000/(PA7);
- __HAL_TIM_SetAutoreload(&htim3,value-1);
- __HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,(value+1)*pwm/100);
- }
- keys[2].single_flag=0;
- }
- }

对于每个按键的处理,唯一的难点可能就是在调整频率的时候,同时要调整占空比,因为调整重装载值也会影响到占空比,需要维持占空比的不变。
__HAL_TIM_SetAutoreload(&htim3,value-1);//调整重装载值
__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,(value+1)*pwm/100);//调整占空比
- void led_proc(void)
- {
- if(VR37>VP1)
- {
- if(uwTick-ledTick<100) return ;
- ledTick=uwTick;
- reverse_bit(&led_sta,2);
- }else
- {
- clear_bit(&led_sta,2);
- }
-
- if(view==1)
- set_bit(&led_sta,0);
- else
- clear_bit(&led_sta,0);
- if(view==0)
- set_bit(&led_sta,1);
- else
- clear_bit(&led_sta,1);
- LED_Display(led_sta);
- }

此题目的只有三种亮灯情况:
这里将LED的状态用一个变量 led_sta 保存,通过函数对这个变量里面的各个位数进行修改即可。唯一的重点是LD3的闪烁。应该是可以使用定时器来完成闪烁的,在中断里面实现反转LD3,但是不知道为啥,我用定时器会出错,频率会变,所以就用了另一种方法,SysTick,能够不用开定时器也能起到计时的功能。uwTick 记录板子上电运行的时间,每毫秒加一,通过这个来记录时间变化,在 if 判断下面的语句将每过 100 ms 执行一次,也就实现了LD3的以0.1ms的闪烁。
- void uart_rx(void)
- {
- char text[30];
- if(rx_p>0)
- {
- if(rx_p==1)
- {
- char temp[2];
- sscanf(rxdata,"%s",temp);
- int t=temp[0]-'0';
- if(t>=1&&t<=9)
- {
- pwm=t*10;
- __HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,(value+1)*pwm/100);
- }else
- {
- sprintf(text,"Error\r\n");
- HAL_UART_Transmit(&huart1,(uint8_t*)text,strlen(text),50);
- }
- }
- rx_p=0;
- memset(rxdata,0,30);
- }
- }

串口读到的数据在 rxdata 中,通过 sscanf 将数据读取出来存到一个变量中,判断该变量是否合法,如果合法,则对占空比进行更改,否则通过串口输出一个Error。
-
- //在变量 num 中对 bit_index 位置0
- void clear_bit(unsigned char *num, int bit_index)
- {
- *num = (*num & ~(1 << bit_index));
- }
- //在变量 num 中对 bit_index 位置1
- void set_bit(unsigned char *num, int bit_index)
- {
- *num = (*num & ~(1 << bit_index)) | (1 << bit_index);
- }
- //在变量 num 中对 bit_index 位反转
- void reverse_bit(unsigned char *num, int bit_index) {
- unsigned char reversed = (*num) >> bit_index;
- reversed = reversed ^ (1 << bit_index);
- *num = (*num) ^ reversed;
- }

该文件是官方所给出的,但是在板子上LCD与LED的引脚是相互冲突的,有时候会影响LED的值,需要对以下三个函数进行如下更改:
- /* USER CODE BEGIN Header */
- /**
- ******************************************************************************
- * @file : main.c
- * @brief : Main program body
- ******************************************************************************
- * @attention
- *
- * Copyright (c) 2024 STMicroelectronics.
- * All rights reserved.
- *
- * This software is licensed under terms that can be found in the LICENSE file
- * in the root directory of this software component.
- * If no LICENSE file comes with this software, it is provided AS-IS.
- *
- ******************************************************************************
- */
- /* USER CODE END Header */
- /* Includes ------------------------------------------------------------------*/
- #include "main.h"
- #include "adc.h"
- #include "tim.h"
- #include "usart.h"
- #include "gpio.h"
-
- /* Private includes ----------------------------------------------------------*/
- /* USER CODE BEGIN Includes */
- #include "lcd.h"
- #include "stdio.h"
- #include "interrupt.h"
- #include "myadc.h"
- #include "string.h"
- #include "led.h"
- /* USER CODE END Includes */
-
- /* Private typedef -----------------------------------------------------------*/
- /* USER CODE BEGIN PTD */
- extern struct key keys[4];
- extern char rxdata[30];
- extern uint8_t rxdat;
- extern uchar rx_p;
- extern uint frq;
- extern float duty;
-
- int pwm=10;
- int view=1;
- double VR37=2.35;
- int PA7=1000;
- double VP1=0.3;
- int value=1000-1;
- uchar led_sta=0x00;
- int LD3=0;
-
- __IO uint32_t ledTick=0;
-
- /* USER CODE END PTD */
-
- /* Private define ------------------------------------------------------------*/
- /* USER CODE BEGIN PD */
-
- /* USER CODE END PD */
-
- /* Private macro -------------------------------------------------------------*/
- /* USER CODE BEGIN PM */
-
- /* USER CODE END PM */
-
- /* Private variables ---------------------------------------------------------*/
-
- /* USER CODE BEGIN PV */
-
- /* USER CODE END PV */
-
- /* Private function prototypes -----------------------------------------------*/
- void SystemClock_Config(void);
- /* USER CODE BEGIN PFP */
- void lcd_proc(void);
- void key_proc(void);
- void led_proc(void);
- void uart_rx(void);
- void clear_bit(unsigned char *num, int bit_index);
- void set_bit(unsigned char *num, int bit_index);
- void reverse_bit(unsigned char *num, int bit_index);
- /* USER CODE END PFP */
-
- /* Private user code ---------------------------------------------------------*/
- /* USER CODE BEGIN 0 */
-
- /* USER CODE END 0 */
-
- /**
- * @brief The application entry point.
- * @retval int
- */
- 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_USART1_UART_Init();
- MX_TIM3_Init();
- MX_TIM2_Init();
- MX_TIM8_Init();
- /* USER CODE BEGIN 2 */
- LCD_Init();
-
- LCD_SetBackColor(Black);
- LCD_SetTextColor(White);
-
- LCD_Clear(Black);
-
- HAL_TIM_Base_Start_IT(&htim4);
- //HAL_TIM_Base_Start_IT(&htim2);
- HAL_UART_Receive_IT(&huart1,&rxdat,1);//开启中断
-
- HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);//初始化
-
- HAL_TIM_IC_Start_IT(&htim8,TIM_CHANNEL_1);
- /* USER CODE END 2 */
-
- /* Infinite loop */
- /* USER CODE BEGIN WHILE */
- while (1)
- {
- lcd_proc();
- key_proc();
- led_proc();
-
-
- if(rx_p!=0)
- {
- int temp=rx_p;
- HAL_Delay(1);
- if(temp==rx_p) uart_rx();
- }
-
- /* USER CODE END WHILE */
-
- /* USER CODE BEGIN 3 */
- }
- /* USER CODE END 3 */
- }
-
-
- /* USER CODE BEGIN 4 */
- void lcd_proc(void)
- {
- char text[30];
- VR37=getADC(&hadc2);
- if(view)//数据界面
- {
- sprintf(text," DATA ");
- LCD_DisplayStringLine(Line3,(uchar*)text);
- sprintf(text," VR37:%.2lfV ",VR37);
- LCD_DisplayStringLine(Line4,(uchar*)text);
- sprintf(text," PA7:%dHz ",PA7);
- LCD_DisplayStringLine(Line5,(uchar*)text);
- }else//参数设置界面
- {
- sprintf(text," PARA ");
- LCD_DisplayStringLine(Line3,(uchar*)text);
- sprintf(text," VP1:%.1lfV ",VP1);
- LCD_DisplayStringLine(Line4,(uchar*)text);
- }
- }
-
- void key_proc(void)
- {
- if(keys[0].single_flag==1)
- {
- view=!view;
- LCD_Clear(Black);
- keys[0].single_flag=0;
- }else if(keys[1].single_flag==1)
- {
- if(view==0)
- {
- VP1+=0.3;
- if(VP1>=3.4) VP1=0.0;
- }
- keys[1].single_flag=0;
- }else if(keys[2].single_flag==1)
- {
- if(view==1)
- {
- PA7+=1000;
- if(PA7>=11000) PA7=1000;
- value=1000000/(PA7);
- __HAL_TIM_SetAutoreload(&htim3,value-1);
- __HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,(value+1)*pwm/100);
- }
- keys[2].single_flag=0;
- }
- }
-
- void led_proc(void)
- {
-
-
- if(VR37>VP1)
- {
- if(uwTick-ledTick<100) return ;
- ledTick=uwTick;
- reverse_bit(&led_sta,2);
- }else
- {
- clear_bit(&led_sta,2);
- }
-
- if(view==1)
- set_bit(&led_sta,0);
- else
- clear_bit(&led_sta,0);
- if(view==0)
- set_bit(&led_sta,1);
- else
- clear_bit(&led_sta,1);
- LED_Display(led_sta);
- }
-
- void uart_rx(void)
- {
- char text[30];
- if(rx_p>0)
- {
- if(rx_p==1)
- {
- char temp[2];
- sscanf(rxdata,"%s",temp);
- int t=temp[0]-'0';
- if(t>=1&&t<=9)
- {
- pwm=t*10;
- __HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,(value+1)*pwm/100);
- }else
- {
- sprintf(text,"Error\r\n");
- HAL_UART_Transmit(&huart1,(uint8_t*)text,strlen(text),50);
- }
- }
- rx_p=0;
- memset(rxdata,0,30);
- }
- }
-
- void clear_bit(unsigned char *num, int bit_index)
- {
- *num = (*num & ~(1 << bit_index));
- }
-
- void set_bit(unsigned char *num, int bit_index)
- {
- *num = (*num & ~(1 << bit_index)) | (1 << bit_index);
- }
- void reverse_bit(unsigned char *num, int bit_index) {
- unsigned char reversed = (*num) >> bit_index;
- reversed = reversed ^ (1 << bit_index);
- *num = (*num) ^ reversed;
- }
- /* USER CODE END 4 */
-
-
- #endif /* USE_FULL_ASSERT */

- #include "interrupt.h"
- #include "usart.h"
- struct key keys[4];
- extern int view;
- extern int LD3;
- extern uchar led_sta;
- void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
- {
-
- if(htim->Instance==TIM4)//中断来源
- {
- //读取四个按键的状态
- keys[0].key_status=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
- keys[1].key_status=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
- keys[2].key_status=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
- keys[3].key_status=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
-
- //状态机消抖
- for(int i=0;i<4;i++)
- {
- switch(keys[i].judge_status)
- {
- case 0:
- {
- if(keys[i].key_status==0)
- {
- keys[i].judge_status=1;
- keys[i].key_time=0;
- }
- }
- break;
- case 1:
- {
- if(keys[i].key_status==0)
- {
- keys[i].judge_status=2;
- }else
- {
- keys[i].judge_status=0;
- }
- }
- break;
- case 2:
- {
- if(keys[i].key_status==0)
- {
- keys[i].key_time++;
- if(keys[i].key_time>=70)
- {
- keys[i].long_flag=1;
- }
- }else
- {
- keys[i].judge_status=0;
- if(keys[i].key_time<70)
- {
- keys[i].single_flag=1;
- }
- }
- }
- break;
- }
- }
- }
-
- }
- char rxdata[30];
- uint8_t rxdat;
- uchar rx_p;
- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
- {
- rxdata[rx_p++]=rxdat;
- HAL_UART_Receive_IT(&huart1,&rxdat,1);
- }
-
- //输入捕获,测试所用
- double ccrl_vala=0,ccrl_valb=0;
- uint frq=0;
- float duty=0;
- void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
- {
- if(htim->Instance==TIM8)
- {
- if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1) //中断消息来源 选择直接输入的通道
- {
- //读取定时器的计时值
- ccrl_vala=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);
- ccrl_valb=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_2);
- //将定时器的计时值清零
- __HAL_TIM_SetCounter(htim,0);
- //计算频率 主频/分频系数/计时值
- frq=(80000000/80)/ccrl_vala;
-
- duty=(ccrl_valb/ccrl_vala)*100;
- HAL_TIM_IC_Start(htim,TIM_CHANNEL_1);
- HAL_TIM_IC_Start(htim,TIM_CHANNEL_2);
- }
-
- }
- }
-

- #ifndef _INTERRUPT_H_
- #define _INTERRUPT_H_
- #include "led.h"
- #include "main.h"
- #include "stdbool.h"
- void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
-
- struct key
- {
- bool single_flag;
- bool long_flag;
- unsigned int key_time;
- unsigned int key_status;
- unsigned int judge_status;
- };
-
- #endif

- #include "led.h"
-
- void LED_Display(uchar dsLED)
- {
- HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET); //将GPIOC的所有引脚全部置高电平,LED灯熄灭
- HAL_GPIO_WritePin(GPIOC,dsLED<<8,GPIO_PIN_RESET); //根据dsLEDd的数值将对应LED点亮
- HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET); //将锁存器打开
- HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET); //将锁存器关闭
- }
- #ifndef _LED_H_
- #define _LED_H_
-
- #include "main.h"
- void LED_Display(uchar dsLED);
-
- #endif
- #include "myadc.h"
-
- //读取adc
- double getADC(ADC_HandleTypeDef *pin)
- {
- unsigned int adc;
- HAL_ADC_Start(pin);
- adc=HAL_ADC_GetValue(pin);
- return adc*3.3/4096;
- }
- #ifndef _MYADC_H_
- #define _MYADC_H_
-
- #include "main.h"
-
- double getADC(ADC_HandleTypeDef *pin);
- #endif
----THE END-----
有关蓝桥杯嵌入式的模块知识请参考如下:
【蓝桥杯嵌入式学习G431】模块五:USART-CSDN博客
(还有几个模块没更新~)
有关蓝桥杯嵌入式历届真题请参考如下:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。