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

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

第十届省赛题目

在这里插入图片描述

涉及模块主要代码

主要变量与结构体

struct keys
{
	uchar judge;
	bool single;
	bool sta;
};
float R37_volt;//R37的电压
struct keys key[4]={0,0,0};//按键初始化

uchar ctimer=0;  //led闪烁计时
bool led_flag=0; //led闪烁flag
bool view_flag=0;// 0:数据显示界面 1:参数设置界面
char lcd_buffer[20];//lcd显示缓存
uint temp=0;//adc采集的数字量
uchar adc_ctimer;//adc刷新时间
uchar param_mode=0;//0:设置上限电压 1:设置下限电压   2:设置上限LED   3:设置下限LED

float Max_volt=2.4,Min_volt=1.2;//上限电压和下限电压
uchar up_led=0,low_led=1;//上限和下限LED
bool adc_flag=1;//adc2_DMA开启与停止flag,默认开启状态

按键判断

在这里插入图片描述
读完按键的功能后,我们发现,本次赛题按键只涉及短按,所以相对简单。
按键主要代码如下:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance==TIM16)//定时器10ms中断一次
	{
		Key_Scan();
	}
}
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://状态0,判断按键是否按下
			{
				if(key[i].sta==0)key[i].judge=1;
			}break;
			case 1://状态1,按键消抖
			{
				if(key[i].sta==0)key[i].judge=2;
				else key[i].judge=0;
			}break;
			case 2://状态2,按键按下处理
			{
				if(key[i].sta==1)
				{ 
					key[i].single=1;//短按按键标志位
					key[i].judge=0;
				}
			}break;
		}
	}
}

LCD显示

在这里插入图片描述
将图中除LCD_RST引脚外的其他引脚,在cudemx中配置成输出模式
在这里插入图片描述
从给的赛点资源包中,将上面的带红框的文件加入到自己的工程文件夹里面。
LCD主要代码:

void LCD_view(void)//lcd显示界面
{
	if(view_flag==0)//数据显示界面
	{
		if(adc_flag==1){ADC2_enable(adc_flag);adc_flag=0;}//cudumx中配置的循环测量,所有只需要开启一次即可
		if(adc_ctimer>=30){R37_volt = temp *3.3/4096;adc_ctimer=0;}//adc 0.3秒刷新一次
		LCD_SetBackColor(White);
		LCD_SetTextColor(Blue2);
		LCD_DisplayStringLine(Line1,"        Main");
		sprintf(lcd_buffer,"    Volt:%.2fV",R37_volt);
		LCD_DisplayStringLine(Line3,(uchar *)lcd_buffer);
		if(R37_volt > Max_volt)sprintf(lcd_buffer,"    Status:Upper ");//后面多打一个空格(长度就保持一致了,会覆盖掉的)就不用刷新行了
		else if(R37_volt < Min_volt)sprintf(lcd_buffer,"    Status:Lower ");//后面多打一个空格就不用刷新行了
		else sprintf(lcd_buffer,"    Status:Normal");
		LCD_DisplayStringLine(Line4,(uchar *)lcd_buffer);
		LED_flicker();//led指示灯闪烁
	}
	else//参数设置界面
	{
		if(adc_flag==0){ADC2_enable(adc_flag);adc_flag=1;}
		LED_disp(0x00);//设置界面关闭所有LED
		LCD_SetBackColor(White);
		LCD_DisplayStringLine(Line1,"      Setting");
		
		if(param_mode==0)LCD_SetBackColor(Green);
		else LCD_SetBackColor(White);
		
		sprintf(lcd_buffer,"   Max Volt:%.1fV ",Max_volt);
		LCD_DisplayStringLine(Line3,(uchar *)lcd_buffer);
		
		if(param_mode==1)LCD_SetBackColor(Green);
		else LCD_SetBackColor(White);;
		
		sprintf(lcd_buffer,"   Min Volt:%.1fV ",Min_volt);
		LCD_DisplayStringLine(Line4,(uchar *)lcd_buffer);
		
		if(param_mode==2)LCD_SetBackColor(Green);
		else LCD_SetBackColor(White);
		sprintf(lcd_buffer,"   Upper:LD%d ",up_led+1);
		LCD_DisplayStringLine(Line5,(uchar *)lcd_buffer);
		
		if(param_mode==3)LCD_SetBackColor(Green);
		else LCD_SetBackColor(White);
		sprintf(lcd_buffer,"   Lower:LD%d ",low_led+1);
		LCD_DisplayStringLine(Line6,(uchar *)lcd_buffer);
	}
}

ADC_DMA采集

在这里插入图片描述
竞赛要求的是R37,我们打开原理图发现,R37对应的是PB15引脚
在这里插入图片描述
因此,我们在cudemx中找到PB15配置成ADC2_IN15
在这里插入图片描述
因为配置的ADC2,所以我们在Analog中点开ADC2,找到IN15
在这里插入图片描述
在这里插入图片描述
ADC2_DMA主要代码:

void ADC2_enable(bool en)//adc2_DMA的开启与停止
{
	if(en)HAL_ADC_Start_DMA(&hadc2,(uint32_t *)&temp,1);
	else HAL_ADC_Stop_DMA(&hadc2);
}

LED模块

由于LED相对简单,在此不多赘述。
LED主要代码:

void LED_disp(uchar dis)//led显示
{
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8 |GPIO_PIN_10 |GPIO_PIN_13 |GPIO_PIN_14 |
					  GPIO_PIN_9 |GPIO_PIN_11 |GPIO_PIN_12 |GPIO_PIN_15 ,GPIO_PIN_SET);//拉高LED
	LED_latch();//led锁存
	HAL_GPIO_WritePin(GPIOC,dis << 8,GPIO_PIN_RESET);LED_latch();//左移八位就到了PC8~PC15,LED就可以正常显示了
}
void LED_com(uchar dis)//关于本次功能的LED
{
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8 |GPIO_PIN_10 |GPIO_PIN_13 |GPIO_PIN_14 |
					  GPIO_PIN_9 |GPIO_PIN_11 |GPIO_PIN_12 |GPIO_PIN_15 ,GPIO_PIN_SET);
	LED_latch();
	HAL_GPIO_WritePin(GPIOC,0x01 << dis+8,GPIO_PIN_RESET);//+8是左移八位,让LED能正常显示,dis是在第几个LED亮
	LED_latch();
}
void LED_latch(void)//led锁存
{
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
void LED_flicker(void)//led闪烁
{
	if(R37_volt>Max_volt)//采集电压大于上限电压
	{
		if(led_flag)LED_com(up_led);
		else LED_disp(0x00);
	}
	else if(R37_volt<Min_volt)//采集电压小于下限电压
	{
		if(led_flag)LED_com(low_led);
		else LED_disp(0x00);
	}
	else LED_disp(0x00);//电压在范围内,LED全部熄灭
}

完整功能演示视频

完整工程文件

总结

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

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值