基于STM32G431嵌入式竞赛板HAL库的程序设计——备赛蓝桥杯

基于STM32G431嵌入式竞赛板HAL库的程序设计——备赛蓝桥杯,第1张

LED的程序设计

8个LED在该嵌入式板子上分别与PC8-PC15相连,因为LED一段连接着VCC,高电平,所以低电平LED亮,高电平LED灭,LED的另一端连接着锁存器,而锁存器在高电平时不锁存数据,在低电平时候锁存数据,即低电平时输出不随输入变化,即使是PC8-PC15的电平发生变化,LED也不随之变化。因此我们可以既控制锁存器来对LED的状态进行控制,也可以调用这些引脚上的资源。

根据STMCubeMX进行配置 1.对时钟进行配置

将时钟配置成80MHz,我们在STMCubeMx上配置如下系数:

2.RCC配置

使用的是外部晶振,所以在配置中应该将模式配置成外部晶振模式。

3.SYS配置

将配置调制成SW下载模式。

4.引脚配置

将PC8-PC15初始配置为低电平,然后将PD2初始配置为低电平,都为开漏输出,如下图:

5.文件输出

在PROJECT MANGER中将编辑器改成MDK,新竞赛板子必须用KEIL V5以上的版本,文件路径不能有中文,否则起始的处理.s文件无法添加,起始会报错
在code generator中勾选一下选项

代码处理 1.led初始化

将 gpio.c中的MX_GPIO_Init(void)改写为LED_Init(void),这能方便后续程序的改下,和模块化的 *** 作能更加方便。

void LED_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOF_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8
                          |GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);

  /*Configure GPIO pins : PC13 PC14 PC15 PC8
                           PC9 PC10 PC11 PC12 */
  GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8
                          |GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pin : PD2 */
  GPIO_InitStruct.Pin = GPIO_PIN_2;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

}
2.LED处理函数(显示)
void LED_Disp(unsigned char ucLed)//unchar-8位控制 1-亮 0-灭
{
	HAL_GPIO_WritePin(GPIOC,ucLed<<8,GPIO_PIN_RESET);//控制pc8-pc15这8个led
	HAL_GPIO_WritePin(GPIOD,GPIO_Pin_2,GPIO_PIN_SET);//控制锁存器高电平数据让数据经过,LED开始显示
	HAL_GPIO_WritePin(GPIOD,GPIO_Pin_2,GPIO_PIN_RESET);//控制锁存器低电平锁存数据
}
独立按键的程序设计

4个独立摁键分别对应着引脚上的PB0(k1),PB1(k2),PB2(k3),PA0(k4),这四个独立摁键的另一端连接着地,当没摁下的时候,因为vcc的接入,所以引脚检测到的是高电平,当摁下时,摁键相当于短路,所以引脚直接接入地,检测电压为低电平。

1.cubemx配置信息

将gpio先配置成上拉模式(pull up)即上电为高电平,此时配置,其他的基本配置都相同时,应该如下图:

代码处理 1.KEY初始化

将 gpio.c中的MX_GPIO_Init(void)改写为KEY_Init(void),这能方便后续程序的改下,和模块化的 *** 作能更加方便。

void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOF_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin : PA0 */
  GPIO_InitStruct.Pin = GPIO_PIN_0;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pins : PB0 PB1 PB2 */
  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}
2.KEY处理

有消抖 *** 作

unsigned  char KEY_Scan(void)
{
	unsigned char ucKey_Val=0;
	if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==0)
	{
		HAL_Delay(10);
		if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==0)
		{
		ucKey_Val=1;
		}
	}
	if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==0)
	{
		HAL_Delay(10);
		if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==0)
		{
		ucKey_Val=2;
		}
	}
	if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==0)
	{
		HAL_Delay(10);
		if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==0)
		{
		ucKey_Val=3;
		}
	}
	if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==0)
	{
		HAL_Delay(10);
		if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==0)
		{
		ucKey_Val=4;
		}
	}
	return ucKey_Val;
}


void KEY_Proc(void)
{
	unsigned char ucKey_Val;
	ucKey_Val=KEY_Scan();
	if(ucKey_Val!=ucKey_Long)
	{
		ucKey_Long=ucKey_Val;
		ucKey_Time=ucTick_ms;
	}
	else
		ucKey_Val=0;
	if(ucKey_Val==1)//短摁处理
	{
		//短摁运行
	}
	if(ucKey_Long==1)//长摁处理
	{
		if(ucTick_ms-ucKey_Time>800)
		{
			ucKey_Time=ucTick_ms;
			//长摁运行
			
		}
	}
}

LCD应用程序设计

根据比赛时会给lcd…c和font.c还有.h文件添加到我们的工程里,并且进行调用,先在keil图标中
在c/c++中添加.c.h的路径 即
添加后我们需要了解的函数有

LCD_Init();
LCD_Clear(颜色);
LCD_SetBackColor(颜色);
LCD_SetTextColor(颜色);
LCD_DisplayChar(行,列,数值);
LCD_DisplayStringLine(行,字符串);

void LCD_Proc(void)
{
}
USART应用程序设计 NVIC中断系统

G431有111个中断,属于内核,NVIC控制芯片中断,STM32 NVIC是CotorM4的子集,寄存器都定义在core_cm4.h的文件中,看start_stm32g431.s文件中可以查看到中断向量表。

1.中断优先级

对于中断来讲,自然优先级是在没有其他优先级,根据数的大小来判断优先级,如果数越小,优先级就越大,如果要自定义优先级,可以通过更改以下的数值来更改优先级,他们分别为抢占优先级和响应优先级。
抢占优先级有四位,相应优先级有四位。
高抢占优先级可以在具有优先级。
用hal库的函数来更改优先级即为

void HAL_NVIC_SetPriority(中断名,uint32_t PreemptPriority主优先级, uint32_t SubPriority))

硬件配置

竞赛板上的USART通过电平转换与九针的d型CN6相连,USART与UART——USB转换与USB插座cn2相连,所用的引脚对应的是PA9(usart1 tx),PA10(usart1 rx)相连。

1.配置引脚

勾选usart1会自动跳到pc4和pc5,而竞赛板上的uart是pa9和pa10,手动更改引脚为pa9和pa10,并将模式更改为Asynchronous异步模式,波特率为9600,word length为8bit,无效验位,有一个停止位,并且使能中断,调整usart的优先级,时钟的配置虽然是80mhz,但是不能用hse来配置,因为用hse来输出,是输出不了的。需要将配置换成hsi。
即配置如下:


代码处理 1.引脚时钟使能
void MX_GPIO_Init(void)
{
  __HAL_RCC_GPIOF_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

}
2.USART初始化
USART_HandleTypeDef husart1;

void USART1_Init(void)
{

  husart1.Instance = USART1;
  husart1.Init.BaudRate = 9600;
  husart1.Init.WordLength = USART_WORDLENGTH_8B;
  husart1.Init.StopBits = USART_STOPBITS_1;
  husart1.Init.Parity = USART_PARITY_NONE;
  husart1.Init.Mode = USART_MODE_TX_RX;
  husart1.Init.CLKPolarity = USART_POLARITY_LOW;
  husart1.Init.CLKPhase = USART_PHASE_1EDGE;
  husart1.Init.CLKLastBit = USART_LASTBIT_DISABLE;
  husart1.Init.ClockPrescaler = USART_PRESCALER_DIV1;
  husart1.SlaveMode = USART_SLAVEMODE_DISABLE;
  if (HAL_USART_Init(&husart1) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_USARTEx_SetTxFifoThreshold(&husart1, USART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_USARTEx_SetRxFifoThreshold(&husart1, USART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_USARTEx_DisableFifoMode(&husart1) != HAL_OK)
  {
    Error_Handler();
  }

}
3.USART处理函数 (1)发送函数

sprintf函数需要调用

void Usart_Proc(void)
{
	if(uwTick-uwTick_Usart_Set_Point<500)	return;
	uwTick_Usart_Set_Point=uwTick;
	sprintf(str,"%04:HELLOW World.\r\n",counter);
	HAL_USART_Transmit(unsigned char *)str,strlen(str),50;
	HAL_Delay(500);
}
(2)单字符发送
int fputc(int ch, FILE *f)
{
	HAL_UART_Transmit(&huart1, (unsigned char *)&ch, 1, 1000);
	return(ch);
}
(3)接收函数
void USART1_IRQHandler(void) //串口中断
{
	HAL_UART_IRQHandler(&huart1);
}

//串口中断回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) 
{
	if(uart_rx_buf[0] == 'a') //接收导数据 a ,回应 Hello
	{
		printf("Hello\r\n");
	}
	
	HAL_UART_Receive_IT(&huart1, uart_rx_buf, 1); //设置串口中断缓冲区及中断阈值(当前为1)
}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/719409.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-25
下一篇 2022-04-25

发表评论

登录后才能评论

评论列表(0条)

保存