第十一届蓝桥杯嵌入式研究生组赛题

成绩已经出来了,很难受没有得奖,本来预计能拿到二等,结果连三等都没混上,思前想后只有两种可能:

①我自己提交的axf文件出了问题  ②题目太简单,这届实力太强

复查结果出来了,确认是自己犯了低级错误,提交的axf文件无效,放在这里,希望自己和后来者引以为戒

虽然没得奖,但这也是一次难忘的经历,15天的强训,中午也在实验室敲代码,还有一个小伙伴和我一起学习,互相讨论,没得奖虽有遗憾,但也不后悔,希望自己总结经验教训,留足时间,细致检查。我的第十一届蓝桥杯正式落幕,明年再战。

记忆版本

研究生组的试题与大学组的区别

主观题(程序设计)部分在大学组的基础上:增加了数据显示界面按下B3交换PA6、PA7输出PWM波形频率

客观题(选择)部分在大学组的基础上:加了5个选择,共15个选择题

【主观题部分-编程】

目的:让PA6、PA7输出固定频率,不同占空比的PWM波形

初始输出状态为:

(1)PA6输出100Hz,占空比10%的PWM波形

(2)PA7输出200Hz,占空比10%的PWM波形

占空比调节方法:根据电压值自动控制占空比,或根据按键手动控制占空比

【LCD模块】

设计界面有数据显示界面、参数显示界面,背景为黑色、字体为白色

数据显示界面显示:电压值、工作模式

参数显示界面显示:PA6占空比、PA7占空比

【LED模块】

使用LED灯作为状态指示

自动模式下,LD2亮;手动模式下,LD2灭

数据显示界面下,LD1亮;参数显示界面下LD1灭

【Timer模块】

扫描按键时间不大于10ms

adc采样间隔不大于0.1s

【KEY模块】

按下B1,切换数据显示界面和参数显示界面

参数显示界面下,按下B2,增加PA6输出PWM波的占空比,步进值10%,调节范围10%~90%,当增加到90%后,下一次按下回到10%

参数显示界面下,按下B3,增加PA7输出PWM波的占空比,步进值10%,调节范围10%~90%,当增加到90%后,下一次按下回到10%

按下B4,切换自动模式和手动模式

数据显示界面下,按下B3,交换PA6和PA7输出PWM波形的频率

【ADC模块】

采集电位器R37(PB0)的电压值,作为自动控制PWM波形的调节参数

【PWM模块】

使用TIM3的通道1(PA6)、通道2(PA7)输出PWM波形,频率固定,占空比可调节

PWM控制策略

自动模式:占空比转换公式,VR37 = 3.3 * D,其中,VR37为电压值,D为占空比

(1)电压值为0V时,PA6、PA7持续输出低电平

(2)电压值为3.3V时,PA6、PA7持续输出高电平

(3)电压值在0~3.3V之间,输出电压值对应的占空比波形

手动模式:通过按键调节PA6、PA7输出波形的占空比

系统上电后默认为数据显示界面,工作模式为自动模式,默认参数为PA6频率100Hz,占空比10%,PA7频率200Hz,占空比10%

系统性能要求:

按键消抖处理,按键响应时间不大于10ms

adc刷新时间不大于0.1s

输出频率精度误差范围±5%

输出占空比精度误差范围±5%

.......

main.c

/*
  程序说明: 第十一届蓝桥杯大赛嵌入式-第二场
  软件环境: Keil uVision 4.11 
  硬件环境: CT117E嵌入式竞赛板(代码兼容ILI932X系列、uc8230液晶控制器)
  日    期: 2020年10月22日
  作    者:乐观的lishan
*/
#include "stm32f10x.h"
#include "lcd.h"
#include "stdio.h"
#include "led.h"
#include "timer.h"
#include "key.h"
#include "adc.h"
#include "pwm.h"

u32 TimingDelay = 0;
u8 data_buf[20];

u8 Mode = 0;
u8 Figure = 0;
u16 adc_value = 0;
float volt_value = 3.02;
u8 flag_manu_pwm = 0;
u8 flag_auto_pwm = 0;

u8 PA6_Duty_Para = 10;
u8 PA7_Duty_Para = 10;
u8 PA6_Freq_Para = 100;
u8 PA7_Freq_Para = 200;

void Delay_Ms(u32 nTime);
void Show_Data(void);
void Show_Para(void);
void LCD_Show(void);
void PWM_Control(void);

//Main Body
int main(void)
{
	SysTick_Config(SystemCoreClock/1000);
	Delay_Ms(200);
	STM3210B_LCD_Init();
	LCD_Clear(Black);
	LCD_SetBackColor(Black);
	LCD_SetTextColor(White);
	LED_Init();
	TIM4_Init();
	ADC_Channel_8_Init();
	KEY_Init();
	LED_Control(LD1,1);
	LED_Control(LD2,1);

  //测试PWM波输出
//	TIM3_PWM_OCToggle();
//	TIM3_PWM_CH1(100,0.1);
//	TIM3_PWM_CH2(200,0.1);

  //测试持续输出高、低电平
//	TIM3_Normal();
//	GPIO_ResetBits(GPIOA, GPIO_Pin_6);
//	GPIO_SetBits(GPIOA, GPIO_Pin_7);

	while(1)
	{
		LCD_Show();
		PWM_Control();
		if(flag_10ms)
		{
			flag_10ms = 0;
			KEY_Read();
			KEY_Process();	
		}
		if(flag_80ms)
		{
			flag_80ms = 0;
			adc_value = ADC_GetConversionValue(ADC1);
			volt_value = adc_value * 3.3 / 4095; 	
		}		
	}
}

//
void Delay_Ms(u32 nTime)
{
	TimingDelay = nTime;
	while(TimingDelay != 0);	
}
void LCD_Show(void)
{
	if(Figure)	   //参数界面
	{
		Show_Para();	
	}
	else	       //数据界面
	{
		Show_Data();	
	}	
}			  
void Show_Data(void)
{
	LCD_DisplayStringLine(Line0, "      Data");	
	sprintf((char*)data_buf, "    V:%.2fV", volt_value);
	LCD_DisplayStringLine(Line2, data_buf);	
	if(Mode)  //手动模式
	{
		LCD_DisplayStringLine(Line4, "    Mode:MANU");	
	}
	else
	{
		LCD_DisplayStringLine(Line4, "    Mode:AUTO");	
	}
	
	//验证AD采集数字量	
//	sprintf((char*)data_buf, "    AD:%4d", adc_value);
//	LCD_DisplayStringLine(Line6, data_buf);		
}

void Show_Para(void)
{
	LCD_DisplayStringLine(Line0, "      Para");	

	sprintf((char*)data_buf, "    PA6:%2d%%", PA6_Duty_Para);
	LCD_DisplayStringLine(Line2, data_buf);	

	sprintf((char*)data_buf, "    PA7:%2d%%", PA7_Duty_Para);
	LCD_DisplayStringLine(Line4, data_buf);	

	//验证频率变化情况	
//	sprintf((char*)data_buf, "    PA6:%3dHz", PA6_Freq_Para);
//	LCD_DisplayStringLine(Line6, data_buf);	
//
//	sprintf((char*)data_buf, "    PA7:%3dHz", PA7_Freq_Para);
//	LCD_DisplayStringLine(Line7, data_buf);		
}
void PWM_Control(void)
{
	if(Mode)  //手动模式
	{
		if(flag_manu_pwm == 0)
		{
			flag_manu_pwm = 1;
			flag_auto_pwm = 0;
			TIM3_PWM_OCToggle();
		}
		else
		{
			TIM3_PWM_CH1(PA6_Freq_Para, PA6_Duty_Para/100.f);
			TIM3_PWM_CH2(PA7_Freq_Para, PA7_Duty_Para/100.f);
		}	
	}
	else
	{
		if(adc_value <= 6)	       //电压0V
		{
			flag_auto_pwm = 0; 
			flag_manu_pwm = 0;
			TIM3_Normal();	
			GPIO_ResetBits(GPIOA, GPIO_Pin_6);
			GPIO_ResetBits(GPIOA, GPIO_Pin_7);	
		}
		else if(adc_value >= 4095-6 && adc_value <= 4095)	//电压3.3V
		{	
			flag_auto_pwm = 0; 
			flag_manu_pwm = 0;
			TIM3_Normal();	
			GPIO_SetBits(GPIOA, GPIO_Pin_6);
			GPIO_SetBits(GPIOA, GPIO_Pin_7);		
		}
		else					   //电压0~3.3V
		{
			if(flag_auto_pwm == 0)
			{
				flag_auto_pwm = 1;
				flag_manu_pwm = 0;
				TIM3_PWM_OCToggle();
			}
			else
			{
				TIM3_PWM_CH1(PA6_Freq_Para, adc_value/4095.f);
				TIM3_PWM_CH2(PA7_Freq_Para, adc_value/4095.f);
			}		
		}		
	}	
}

 key.c

/*
  程序说明: CT117E嵌入式竞赛板KEY驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT117E嵌入式竞赛板(代码兼容ILI932X系列、uc8230液晶控制器)
  日    期: 2013-10-9
*/
#include "key.h"
#include "lcd.h"
#include "led.h"

u8 ReadData = 0;

u8 key1_press = 0;
u8 key2_press = 0;
u8 key3_press = 0;
u8 key4_press = 0;

u8 key1_time = 0;
u8 key2_time = 0;
u8 key3_time = 0;
u8 key4_time = 0;

void KEY_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_8;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);	

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOB, &GPIO_InitStructure);	
}

void KEY_Read(void)
{
	ReadData = ~(KEYPORT);
	if(ReadData == 0x01){++key1_time;}
	else if(ReadData == 0x02){++key2_time;}
	else if(ReadData == 0x04){++key3_time;}
	else if(ReadData == 0x08){++key4_time;}
	if(ReadData == 0)
	{
		if(key1_time > 0){key1_press = 1;}
		else if(key2_time > 0){key2_press = 1;}
		else if(key3_time > 0){key3_press = 1;}
		else if(key4_time > 0){key4_press = 1;}
	}
}

void KEY_Process(void)
{
	if(key1_press)
	{
		if(Figure)   
		{
			Figure = 0;	  //数据界面
			LED_Control(LD2,1);
		}
		else       
		{
			Figure = 1;	  //参数界面
			LED_Control(LD2,0);	
		}
		LCD_Clear(Black);	
	}
	else if(Figure && key2_press)
	{
		PA6_Duty_Para += 10;
		if(PA6_Duty_Para > 90)
		{
			PA6_Duty_Para = 10;
		}
	}
	else if(Figure && key3_press)
	{
		PA7_Duty_Para += 10;
		if(PA7_Duty_Para > 90)
		{
			PA7_Duty_Para = 10;
		}
	}
	else if(Figure == 0 && key3_press)
	{
		u8 temp;
		temp = PA7_Freq_Para;
		PA7_Freq_Para = PA6_Freq_Para;
		PA6_Freq_Para = temp;
	}
	else if(key4_press)
	{
		if(Mode)   
		{
			Mode = 0;	  //自动
			LED_Control(LD1,1);
		}
		else       
		{
			Mode = 1;	  //手动
			LED_Control(LD1,0);	
		}
	}
	if(ReadData == 0)
	{
		key1_time = 0; key2_time = 0; key3_time = 0; key4_time = 0;
		key1_press = 0; key2_press = 0;	key3_press = 0;	key4_press = 0;	
	}	
}

使用Keil软件的逻辑分析仪

按下Ctrl+F5,进入调试模式

测试输出固定频率、占空比的PWM波形 

 

 测试持续输出高低电平

 示波器测试

图中测试结果:

频率:200Hz,占空比:40.00%

完整的测试视频:  第十一届蓝桥杯大赛省赛嵌入式第二场试题_哔哩哔哩_bilibili

              视频测试

【客观题部分-选择】

客观题部分共15个选择题

 (11)一般嵌入式系统设计时不追求的目标是()

             A.低功耗   B.低成本   C.实时性    D.高性能

(12)以下可作为高速数据缓存的器件是()

             A.Flash   B.DRAM   C.EEPROM    D.SRAM

(13)

(14)

(15)以下是典型的文件格式的有()

             A.NTFS   B.FAT32   C.DOS    D.EXT

仅供参考:

(1)B       (2)B      (3)A       (4)B    (5)C

(6)A       (7)AB   (8)BD    (9)B    (10)B

(11)D   (12)D  (13)        (14)     (13)ABD

  • 14
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

乐观的lishan

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

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

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

打赏作者

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

抵扣说明:

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

余额充值