Bootstrap

STM32G431RB--基于HAL库(蓝桥杯嵌入式赛前梳理)

目录

前言

第一步需要做的事情

Cube MX中的设置

LED

KEY 

I2C


前言

梳理每个模块的使用和代码,小技巧以及整个比赛的设计流程。

第一步需要做的事情

比赛官方提供了LCD的驱动程序,直接在此程序上添加其他的,就不需要点LCD的引脚也不需要移动LCD的驱动程序。

●新建一个文件夹将官方提供的HAL_LCD移入新建的文件夹中,注意文件夹不能含有中文字符。

●main.c中有很多关于LCD的显示函数,将不需要的删去即可。

●官方还提供了I2C的驱动程序,将I2C的驱动程序直接添加进去。

Cube MX中的设置

因为比赛时间原因,我们将比赛内容所需要的功能系统的进行统一的设置。

GPIO引脚设置

LED的设置:(PC8~PC15)output

将out—level设置为high高电平使程序开始LED处于灭的状态,

给LED起上自己的名字(LED1,LED2)方便程序的书写,

PD2output,设置锁存器,使LED与LCD不起冲突。

按键的设置:(PB0~PB2,PA0) intput,起名B1~B4。

为按键设置计数器TIM3,将Clock Source设置为 Internal Clock,设置parameter将Prescal 设置为79,Counter Period设置为9999,打开中断。

 

ADC的设置:在Aanalog中选择ADC2,选择N15接口。

USAT的设置:在Connectivity中选择USAT1,模式选择Asynhrous,根据题意设置波特率(一般为9600),打开中断。

I2C的设置:将PB6,PB7设置output。

RCC,SYS,COLCK的设置:

RCC->Crystal/Ceramic Resonator

SYS->Serial Wire

Clock->24HZ->HSE->PLLCLK->80HZ


LED

新建两个空白文件分别命名为led.c、led.h,保存后添加在工程里。

led.c文件:

#include "led.h"
void LED_Disp(unsigned char dsled)
{
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);//将所有灯初始化为高电平
	HAL_GPIO_WritePin(GPIOC,dsled<<8,GPIO_PIN_RESET); //点亮dsled
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);  //锁存器的开启
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}

 led.h文件

#ifndef _LED_
#define _LED_

#include "main.h"//避免定义和命名重复
void LED_Disp(unsigned char dsled);
#endif

main.c

添加LED显示函数void LED_Disp(unsigned char dsled);

#include "led.h"

初始化LED_Disp(0x00);

点亮LED1:

        LED_Disp(0x01);
        HAL_Delay(500);
        LED_Disp(0x00);
        HAL_Delay(500);

LED2为(0x02),LED3为(0x04)....2进制转16进制。


KEY 

 新建两个空白文件分别命名为interrupt.c、interrupt.h,保存后添加在工程里。

interrupt.c

#include "intterupt.h"
struct keys key[]={0,0,0,0};

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance==TIM3)
	{
		key[0].key_sta=HAL_GPIO_ReadPin(B1_GPIO_Port,B1_Pin);
		key[1].key_sta=HAL_GPIO_ReadPin(B2_GPIO_Port,B2_Pin);
		key[2].key_sta=HAL_GPIO_ReadPin(B3_GPIO_Port,B3_Pin);
		key[3].key_sta=HAL_GPIO_ReadPin(B4_GPIO_Port,B4_Pin);
	}
	for(int i=0;i<4;i++)
	{
		switch(key[i].key_judge)
		{
			case 0:     //防抖
			{
				if(key[i].key_sta==0)
					key[i].key_judge=1;
			}
			break;
			case 1:
			{
				if(key[i].key_sta==0)
				{
					key[i].key_flag=1;
					key[i].key_judge=2;
				}
				else
				{
					key[i].key_judge=0;
				}
				break;
			 case 2:
			{
				if(key[i].key_sta==1)
				{
					key[i].key_judge=0;
				}
			}
			}
		}
	}
}

 interrupt.h

#ifndef _intterupt_
#define _intterupt_

#include "main.h"
#include "stdbool.h"
struct keys
{
	unsigned char key_judge;
	bool key_sta;
	bool key_flag;
};
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
#endif

 main.c

 添加函数void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);

引入变量extern struct keys key[];

#include "intterupt.h"

打开tim3   HAL_TIM_Base_Start_IT(&htim3);

按键实现:

if(key[0].key_flag==1)
        {
        ............写需要实现的功能
         key[0].key_flag=0;//置零
        }

 不加计时器的按键(简单的实现按键功能)

void Key_Scan()
{
    if(HAL_GPIO_ReadPin(B1_GPIO_Port,B1_Pin)==GPIO_PIN_RESET)
    {
        HAL_Delay(10);
        if(HAL_GPIO_ReadPin(B1_GPIO_Port,B1_Pin)==GPIO_PIN_RESET)
            {
               while(HAL_GPIO_ReadPin(B1_GPIO_Port,B1_Pin)==GPIO_PIN_RESET)
                {
                    .........

                }
              
            }
    }
}


I2C

在I2C.c中或main.c中添加一段初始化程序 。(在主函数中添加#include i2c.h)

uint8_t eeprom_read(unsigned char address)
{
	unsigned char val;
	I2CStart( );  //起始
	I2CSendByte(0xa0);  //从设备地址发送字节(0xa0)末位为0表示写入
	I2CWaitAck( ); //等待确认
	
	I2CSendByte(address);//发送存储位置
	I2CWaitAck( );
	
	I2CStart( );
	I2CSendByte(0xa1);  //发送位置读入
	I2CWaitAck( );
	val=I2CReceiveByte( ); //接收的字节
	I2CWaitAck( );
	I2CStop( );
	return (val);
}

uint8_t eeprom_write(unsigned char address,unsigned char info)
{
	I2CStart( );
	I2CSendByte(0xa0);
	I2CWaitAck( );
	
	I2CSendByte(address);
	I2CWaitAck( );
	I2CSendByte(info);
	I2CWaitAck( );
	I2CStop( );
}

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;