突击蓝桥杯嵌入式(九)——康复训练,第十一届省赛第二场真题
好长时间不敲代码,做个康复训练
一、题干
二、赛题解析
我们先确定一下需求:
按键:PB0 PB1 PB2 PA0
LED:把锁存器配置好
PWM输出:PA6,PA7 输出比较
ADC测量: PB15
逻辑没啥难度,难点就是输出比较,我上篇有写过
//变量声明区
__IO uint32_t uwTick_KEY_Speed;
__IO uint32_t uwTick_LCD_Speed;
__IO uint32_t uwTick_change_Speed;
__IO uint32_t uwTick_LED_Speed;
uint8_t key_value;
uint8_t key_down;
uint8_t key_up;
uint8_t key_old;
uint8_t str[21];
uint8_t MODE_flag;
uint8_t LCD_flag;
float V;
float duty_PA6 = 10;
float duty_PA7 = 10;
int time_pa6, time_pa7;
uint8_t flag_pa6,flag_pa7;
float duty_pa6,duty_pa7;
LCD没啥逻辑
void Data_Display()
{
V = (3.3 * get_R37_value())/4096;
sprintf((char *)str," Data ");
LCD_DisplayStringLine(Line0,str);
sprintf((char *)str," V:%.2f ",V);
LCD_DisplayStringLine(Line2,str);
if(MODE_flag == 0)
{
sprintf((char *)str," Mode:AUTO ");
LCD_DisplayStringLine(Line4,str);
}
if(MODE_flag == 1)
{
sprintf((char *)str," Mode:MANU ");
LCD_DisplayStringLine(Line4,str);
}
}
void Param_Display()
{
sprintf((char *)str," Para ");
LCD_DisplayStringLine(Line0,str);
sprintf((char *)str," PA6:%.0lf%% ",duty_PA6);
LCD_DisplayStringLine(Line2,str);
sprintf((char *)str," PA7:%.0lf%% ",duty_PA7);
LCD_DisplayStringLine(Line4,str);
}
void LCD_Proc()
{
if(uwTick - uwTick_LCD_Speed < 100) return;
else uwTick_LCD_Speed = uwTick;
if(LCD_flag == 0){
Data_Display();
}
if(LCD_flag == 1){
Param_Display();
}
}
按键,老八股了
uint8_t Key_Scan()
{
static uint8_t value;
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0) == GPIO_PIN_RESET) value = 1;
else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == GPIO_PIN_RESET) value = 2;
else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2) == GPIO_PIN_RESET) value = 3;
else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == GPIO_PIN_RESET) value = 4;
else value = 0;
return value;
}
void Key_Proc()
{
if(uwTick - uwTick_KEY_Speed < 100) return;
else uwTick_KEY_Speed = uwTick;
key_value = Key_Scan();
key_down = key_value & (key_value ^ key_old);
key_up = -key_value & (key_value ^ key_old);
key_old = key_value;
switch (key_down)
{
case 1:
LCD_flag^=1;
break;
case 2:
if(LCD_flag == 1)
{
duty_PA6 +=10;
if(duty_PA6 == 100)
{
duty_PA6 = 10;
}
}
break;
case 3:
if(LCD_flag == 1)
{
duty_PA7 +=10;
if(duty_PA7 == 100)
{
duty_PA7 = 10;
}
}
break;
case 4:
if(LCD_flag == 0){
MODE_flag^=1;
}
break;
default:
break;
}
}
LED
void LED_Disp(uint8_t ucled)
{
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
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(GPIOC,ucled<<8,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
void LED_Proc()
{
if(uwTick - uwTick_LED_Speed < 100) return;
else uwTick_LED_Speed = uwTick;
if(MODE_flag == 0)
{
if(LCD_flag == 0)
{
LED_Disp(0X03);
}
else
{
LED_Disp(0X01);
}
}
else
{
if(LCD_flag == 0)
{
LED_Disp(0X02);
}
else
{
LED_Disp(0X00);
}
}
}
输出比较,难点
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
if(duty_pa6 == 0 | duty_pa7 == 0)
{
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_6,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_RESET);
return;
}
if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
{
if(flag_pa6 == 1)
{
flag_pa6 ^= 1;
TIM3->CCR1 = time_pa6*duty_pa6 + TIM3->CCR1;
__HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1,TIM_OCPOLARITY_LOW);
}
else
{
flag_pa6 ^= 1;
TIM3->CCR1 = time_pa6*(1-duty_pa6) + TIM3->CCR1;
__HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1,TIM_OCPOLARITY_HIGH);
}
}
if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
{
if(flag_pa7 == 1)
{
flag_pa7 ^= 1;
TIM3->CCR2 = time_pa7*duty_pa7 + TIM3->CCR2;
__HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_2,TIM_OCPOLARITY_LOW);
}
else
{
flag_pa7 ^= 1;
TIM3->CCR2 = time_pa7*(1-duty_pa7) + TIM3->CCR2;
__HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_2,TIM_OCPOLARITY_HIGH);
}
}
}
void set_duty(uint8_t id,float duty)
{
if(id == 1)
{
duty_pa6 = duty;
}
if(id == 2)
{
duty_pa7 = duty;
}
}
ADC
uint16_t get_R37_value()
{
static uint16_t value;
HAL_ADC_Start(&hadc2);
HAL_ADCEx_Calibration_GetValue(&hadc2,10);
HAL_ADC_PollForConversion(&hadc2,3);
value = HAL_ADC_GetValue(&hadc2);
HAL_ADC_Stop(&hadc2);
return value;
}
电压改变进程
void Change_Proc()
{
if(uwTick - uwTick_change_Speed < 50) return;
else uwTick_change_Speed = uwTick;
if(MODE_flag == 0) //自动模式
{
set_duty(1,V/3.3);
set_duty(2,V/3.3);
}
else if(MODE_flag == 1) //手动
{
set_duty(1,duty_PA6/100);
set_duty(2,duty_PA7/100);
}
}
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_ADC2_Init();
MX_TIM3_Init();
/* USER CODE BEGIN 2 */
LCD_Init();
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
LCD_Clear(Black);
time_pa6 = 10000;
time_pa7 = 5000;
HAL_TIM_OC_Start_IT(&htim3,TIM_CHANNEL_1);
HAL_TIM_OC_Start_IT(&htim3,TIM_CHANNEL_2);
LED_Disp(0x00);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
LCD_Proc();
Key_Proc();
Change_Proc();
LED_Proc();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}