2020年嵌入式第十一届省赛真题解析

一、题目

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA57yW56iL5bCP54aK,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA57yW56iL5bCP54aK,size_20,color_FFFFFF,t_70,g_se,x_16

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA57yW56iL5bCP54aK,size_20,color_FFFFFF,t_70,g_se,x_16

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA57yW56iL5bCP54aK,size_20,color_FFFFFF,t_70,g_se,x_16

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA57yW56iL5bCP54aK,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA57yW56iL5bCP54aK,size_20,color_FFFFFF,t_70,g_se,x_16 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA57yW56iL5bCP54aK,size_20,color_FFFFFF,t_70,g_se,x_16

 

二、分析

根据题目画出整个程序的状态机的动作和变换以及条件

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA57yW56iL5bCP54aK,size_20,color_FFFFFF,t_70,g_se,x_16

 这里将界面和模式分开建立了两种类型的状态机,也可以将界面和模式设置为一种状态机也许。

按键控制着状态机的切换以及占空比的调节,然后LCD将各个状态机的动作显示出来。

考点:

调节PWM的频率:__HAL_TIM_SET_AUTORELOAD(__HANDLE__, __AUTORELOAD__)

第一个参数:定时器句柄

第二个参数:自动重装载值(设置周期)

设置200hz:__HAL_TIM_SET_AUTORELOAD(&htim17, 4999);

 假设主频80Mhz,经过80分频,得到计数频率1Mhz,每gif.latex?10%5E%7B-6%7Ds,CNT中的值就加1,若超过ARR也就是自动装载值,就会产生更新事件。若自动重载值为1000,则每计数到1000,就发生中断,发生中断的周期为gif.latex?10%5E%7B-3%7Ds,即频率1Khz。

 

调节PWM的占空比:__HAL_TIM_SET_COMPARE(__HANDLE__, __CHANNEL__, __COMPARE__) 

第一个参数:定时器句柄

第二个参数:PWM通道数

第三个参数:CCR,比较值

设置占空比60%:__HAL_TIM_SET_COMPARE(&htim17, TIM_CHANNEL_1, (5000*0.6);

占空比:高电平占周期的百分比

注:题目说在数据界面下每按一次B3,互换PA6和PA7输出脉冲信号频率,这里还要保存原来的占空比不变。还有显示内容的行数与列数要与试题上的一致。

 

三、程序

#include "main.h"
#include "RCC\bsp_rcc.h"
#include "KEY_LED\bsp_key_led.h"
#include "LCD\bsp_lcd.h"
#include "UART\bsp_uart.h"
#include "ADC\bsp_adc.h"
#include "TIM\bsp_tim.h"


//***全局变量声明区
//*减速变量
__IO uint32_t uwTick_Key_Set_Point = 0;//控制Key_Proc的执行速度
__IO uint32_t uwTick_Led_Set_Point = 0;//控制Led_Proc的执行速度
__IO uint32_t uwTick_Lcd_Set_Point = 0;//控制Lcd_Proc的执行速度


//*按键扫描专用变量
uint8_t ucKey_Val, unKey_Down, ucKey_Up, ucKey_Old;

//*LED专用变量
uint8_t ucLed;

//*LCD显示专用变量
uint8_t Lcd_Disp_String[21];//最多显示20个字符

float v37;
uint8_t lcd_set=0; // 0: 数据界面 1:参数界面
uint8_t state=2; //状态机
uint8_t PA6=10,PA7=10;//初始占空比



//***子函数声明区
void Key_Proc(void);
void Led_Proc(void);
void Lcd_Proc(void);
void Usart_Proc(void);


//***系统主函数
int main(void)
{

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

	/*bsp资源的初始化*/
	KEY_LED_Init();
	
	LCD_Init();
	LCD_Clear(Black);
  LCD_SetBackColor(Black);
  LCD_SetTextColor(White);	
	
	UART1_Init();
	ADC2_Init();

	PWM_OUTPUT_TIM3_Init();
	PWM_OUTPUT_TIM17_Init();
	//*启动定时器3和定时器17通道输出
  HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);	//PA6
  HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);		//PA7

  while (1)
  {
		Key_Proc();
		Led_Proc();
		Lcd_Proc();
  }

}


//***按键扫描子函数
void Key_Proc(void)
{
	if((uwTick -  uwTick_Key_Set_Point)<50)	return;//减速函数
		uwTick_Key_Set_Point = uwTick;

	ucKey_Val = Key_Scan();
	unKey_Down = ucKey_Val & (ucKey_Old ^ ucKey_Val); 
	ucKey_Up = ~ucKey_Val & (ucKey_Old ^ ucKey_Val);	
	ucKey_Old = ucKey_Val;
	
	if(unKey_Down == 1) //数据界面和参数界面切换
	{
		if(lcd_set==0)
		{
			lcd_set=1;
			LCD_Clear(Black);
		}
		else if(lcd_set ==1)
		{
			lcd_set =0;
			LCD_Clear(Black);
		}
	}
	
	if(unKey_Down == 4) //模式切换
	{
		if(state==2)state=0;
		else if(state==0)state=2;
		else if(state==1)state=3;
		else if(state==3)state=1;
	}	
	if(unKey_Down == 2)
	{
		if(lcd_set==1) //参数界面
		{
			PA6 += 10;
			if(PA6>90)PA6=10;
		}
		
	}
	if(unKey_Down == 3)
	{
		if(lcd_set==1) //参数界面
		{
			PA7 += 10;
			if(PA7>90)PA7=10;
		}
		else if(lcd_set==0)  //在数据界面下,交换频率保持占空比不变
		{
			if(state==2)state=3;
			else if(state==0)state=1;
			else if(state==1)state=0;
			else if(state==3)state=2 ;
		}
	}
}


//***LED扫描子函数
void Led_Proc(void)
{
	if((uwTick -  uwTick_Led_Set_Point)<200)	return;//减速函数
		uwTick_Led_Set_Point = uwTick;

	if(state==2||state==3) //自动模式LED1亮
	{
		ucLed |= (1<<0);
	}
	else if(state ==0 ||state ==1)
	{
		
		ucLed &= ~(1<<0);
	}
	
	if(lcd_set ==0) //数据界面 led2亮
	{
		ucLed |= (1<<1);
	}
	else if(lcd_set ==1)
	{
		ucLed &= ~(1<<1);
	}
		
	LED_Disp(ucLed);
}


void Lcd_Proc(void)
{
	if((uwTick -  uwTick_Lcd_Set_Point)<100)	return;//减速函数
		uwTick_Lcd_Set_Point = uwTick;
	
	v37 = 3.3*getADC2()/4096;

	if(lcd_set ==0) //数据界面
	{
		sprintf((char *)Lcd_Disp_String, "      Data");
		LCD_DisplayStringLine(Line0, Lcd_Disp_String);	
		
		sprintf((char *)Lcd_Disp_String, "    V:%4.2fV",v37);
		LCD_DisplayStringLine(Line2, Lcd_Disp_String);	
		
		if(state ==2 || state ==3)
			sprintf((char *)Lcd_Disp_String, "    Mode:AUTO");
		else if(state==0 || state==1)
			sprintf((char *)Lcd_Disp_String, "    Mode:MANU");
		LCD_DisplayStringLine(Line4, Lcd_Disp_String);	
		
	}
	else if(lcd_set==1) //参数界面
	{
		sprintf((char *)Lcd_Disp_String, "      Para  ");
		LCD_DisplayStringLine(Line0, Lcd_Disp_String);	
		
		sprintf((char *)Lcd_Disp_String, "    PA6:%2d%%  ",PA6);
		LCD_DisplayStringLine(Line2, Lcd_Disp_String);	
		
		sprintf((char *)Lcd_Disp_String, "    PA7:%2d%%  ",PA7);
		LCD_DisplayStringLine(Line4, Lcd_Disp_String);	
	}	

	// state
	switch(state) // 2<->3 , 0<->1 在数据界面下b3按下交换频率和保持占空比不变
	{
		
		case 2:
			PA6 = v37/3.3*100; //转为百分比
			PA7 = PA6;
			__HAL_TIM_SET_AUTORELOAD(&htim3, 9999);	//PA6(绿色)的频率为200hz
			__HAL_TIM_SET_AUTORELOAD(&htim17, 4999);//PA7(黄色)的频率为100hz
			//占空比设置
			__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, (10000*v37/3.3));
			__HAL_TIM_SET_COMPARE(&htim17, TIM_CHANNEL_1, (5000*v37/3.3));		
		
			break;
		case 3:
			PA6 = v37/3.3*100;
			PA7 = PA6;
			__HAL_TIM_SET_AUTORELOAD(&htim3, 4999);	
			__HAL_TIM_SET_AUTORELOAD(&htim17, 9999);
			//占空比设置
			__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, (5000*v37/3.3));
			__HAL_TIM_SET_COMPARE(&htim17, TIM_CHANNEL_1, (10000*v37/3.3));	
			break;
		case 0:
			__HAL_TIM_SET_AUTORELOAD(&htim3, 9999);	
			__HAL_TIM_SET_AUTORELOAD(&htim17, 4999);
			//占空比设置
			__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, PA6*100); // 10000 *pa6 /100
			__HAL_TIM_SET_COMPARE(&htim17, TIM_CHANNEL_1, 50*PA7);	
			break;
		case 1:
			__HAL_TIM_SET_AUTORELOAD(&htim3, 4999);
			__HAL_TIM_SET_AUTORELOAD(&htim17, 9999);
			//占空比设置
			__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 50*PA7);
			__HAL_TIM_SET_COMPARE(&htim17, TIM_CHANNEL_1, 100*PA6);	
			break;
		
	}		
}

void Error_Handler(void)
{
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
}

 

 

 

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Super.Bear

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

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

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

打赏作者

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

抵扣说明:

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

余额充值