STM32HAL库【G431】--【蓝桥杯嵌入式第十一届省赛题】

完整工程(百度网盘免费下载,提取码:0403)和演示视频在文章末尾,需要请移步至文章末尾。

第十一届省赛题目

在这里插入图片描述

涉及模块主要代码

主要变量与结构体

struct keys
{
	uchar judge;//判断按键状态
	bool sta;//按键实时状态
	bool single;//短按按键标志位
};
struct keys key[4]={0,0,0};//初始化按键

bool view_flag=0;// 0数据显示界面 1参数界面
bool adc_flag=1;//adc开启标志位
bool auto_flag=1;//默认自动模式,模式标志位
char lcd_buffer[20];//lcd显示缓存
float R37_volt=0;//R37转换的模拟量
uint temp=0;//adc采集的数字量

uint pwm_cnt1=100;//PA6的占空比 (pwm_cnt1/1000)% 因为配置的arr=1000
uint pwm_cnt2=100;//PA7的占空比 (pwm_cnt2/1000)% 因为配置的arr=1000

uint pwm_auto=0;//自动模式下,PA7和PA6的占空比(pwm_auto/1000)%

LED指示灯

本题LED相对简单,在此不多赘述。
LED对应原理图:
在这里插入图片描述

代码如下:

void LED_disp(uchar dis)//LED显示
{
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8 |GPIO_PIN_11 |GPIO_PIN_12 |GPIO_PIN_13 |
	GPIO_PIN_15 |GPIO_PIN_14 |GPIO_PIN_9 |GPIO_PIN_10,GPIO_PIN_SET);
	
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);//LED锁存打开
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);//LED锁存关闭
	
	HAL_GPIO_WritePin(GPIOC,dis << 8,GPIO_PIN_RESET);
	
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);//LED锁存打开
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);//LED锁存关闭
}

void LED_indicate(void)//LED指示灯
{
	if(auto_flag)LED_disp(0x01);//LD1亮,其他全灭
	else LED_disp(0x02);//LD2亮,其他全灭
}

按键扫描

本次按键只涉及短按,相对简单,具体思路是检测按键——>按键消抖——>按键处理
按键原理图:
在这里插入图片描述
代码如下:

void Key_Scan(void)//按键扫描
{
	key[0].sta = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
	key[1].sta = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
	key[2].sta = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
	key[3].sta = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
	
	for(uchar i=0; i<4; i++)
	{
		switch(key[i].judge)
		{
			case 0://状态1:判断按键是否按下
			{
				if(key[i].sta==0)key[i].judge=1;
			}break;
			case 1://状态2:按键消抖
			{
				if(key[i].sta==0)key[i].judge=2;
				else key[i].judge=0;
			}break;
			case 2://状态3:确认按键按下进行相应处理
			{
				if(key[i].sta==1)//松开按键后
				{
					key[i].single=1;
					key[i].judge=0;
				}
			}break;
		}
	}
}

PWM输出

在cudemx中选取TIM16_CH1
在这里插入图片描述
打开TIM16,选取PWM生成通道1
在这里插入图片描述
PWM模式、频率(图片来源:https://blog.csdn.net/Naisu_kun/article/details/119214930):
在这里插入图片描述

对输入时钟进行配置,输入80M,时钟分频(80000000/(800)/(1000))==100HZ(PWM频率)
Pulse设置成100则初始占空比:100/1000*100%=10%
在这里插入图片描述

开启中断:
在这里插入图片描述
代码如下:

void PMW_duty(void)//PWM占空比输出
{
	if(auto_flag)
	{
		pwm_auto = R37_volt/3.3f*1000;
		TIM16->CCR1 = pwm_auto;//设置PA6输出pwm的占空比
		//__HAL_TIM_SetCompare(&htim16,TIM_CHANNEL_1,pwm_auto);本行代码与上一行代码作用一致
		TIM17->CCR1 = pwm_auto;//设置PA7输出pwm的占空比
		//__HAL_TIM_SetCompare(&htim16,TIM_CHANNEL_1,pwm_auto);本行代码与上一行代码作用一致
	}
	else
	{
		TIM16->CCR1 = pwm_cnt1;//设置PA6输出pwm的占空比
		//__HAL_TIM_SetCompare(&htim16,TIM_CHANNEL_1,pwm_cnt1);本行代码与上一行代码作用一致
		TIM17->CCR1 = pwm_cnt2;//设置PA7输出pwm的占空比
		//__HAL_TIM_SetCompare(&htim17,TIM_CHANNEL_1,pwm_cnt2);本行代码与上一行代码作用一致
	}
}

R37模拟输入

(因为在第十届省赛中已经写过一遍,这里就大概写一下,详细情况请看第十届省赛题的文章)
在此我们使用DMA来进行ADC采集
R37对应原理图(连接在PB15上):
在这里插入图片描述

Cudemx配置如下:
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

void ADC_R37(bool en)//R37adc开启与关闭
{
	if(en)HAL_ADC_Start_DMA(&hadc2,(uint32_t *)&temp,1);//开启DMA_ADC采集并保存数据到temp变量
	else HAL_ADC_Stop_DMA(&hadc2);//关闭DMA_ADC
}

LCD显示

本题中严格规定了LCD的显示格式和内容,精确到行和列,写代码的友友注意。
LCD原理图:
在这里插入图片描述
将上图中除LCD_RST以外的引脚在STM32CUDEMX中配置成输出模式。在赛点资源包中找出下图带红框的文件,加入到自己的工程文件夹下面即可。
在这里插入图片描述
LCD显示代码:

void LCD_view(void)//界面显示函数
{
	if(adc_flag==1){ADC_R37(adc_flag);adc_flag=0;}//开启ADC采集,只开启一次就可以,DMA设置的循环采集
	R37_volt = temp *3.3 /4096;
	if(view_flag==0)//数据显示界面
	{
		LCD_DisplayStringLine(Line0,"      Data");

		sprintf(lcd_buffer,"    V:%.2fV",R37_volt);
		LCD_DisplayStringLine(Line2,(uchar *)lcd_buffer);
		if(auto_flag==1)LCD_DisplayStringLine(Line4,"    Mode:AUTO");
		else LCD_DisplayStringLine(Line4,"    Mode:MANU");
	}
	else//参数设置界面
	{
		LCD_DisplayStringLine(Line0,"      Para");
		
		sprintf(lcd_buffer,"    PA6:%d%%",pwm_cnt1/10);//显示PA6的占空比
		LCD_DisplayStringLine(Line2,(uchar *)lcd_buffer);
		sprintf(lcd_buffer,"    PA7:%d%%",pwm_cnt2/10);//显示PA7的占空比
		LCD_DisplayStringLine(Line4,(uchar *)lcd_buffer);
	}
	PMW_duty();//PWM占空比输出
	LED_indicate();//LED指示
}

完整功能演示视频

完整工程文件

总结

自己写的代码,不喜勿喷,欢迎参考呀
以上就是本次的全部内容了,笔者水平有限,仅供参考。
想联系笔者请私信就好。

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值