一、LED
1、引脚配置PC8~15 (8盏灯)
默认高电平(熄灭),推挽输出,上拉电阻,
使能PD2,配置默认低电平,即低电平时锁存数据,高电平时不锁存(即更新)数据
PD2锁存器的作用:引脚复用,解决与LCD引脚冲突的问题
2、编写LED更新函数
(1)、采用HAL_Delay();延时
添加LED.c LED.h
数据寄存器为32位,用低16位的高八位控制LED,所以左移的是8位
LED.c
#include "LED.h"
void LED_disp (uint led)
{
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);//熄灭all
HAL_GPIO_WritePin(GPIOC,led<<8,GPIO_PIN_RESET);//0x01<<8 往后补8位0
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);//更新数据
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);//锁存数据
}
LED.h
#ifndef _LED_H_
#define _LED_H_
#include "main.h"
void LED_disp (uint led);
#endif
在main.c中调用就可以
while(1)
{
LED_disp(0x44);
HAL_Delay(500);
LED_disp(0x00);
HAL_Delay(500);}
(2)、采用SysTick_Handler :系统定时器中断函数延时
在stm32g4xx_it.c中检索SysTick_Handler
在中断函数外编写更新函数
uint8_t led;
void led_task(uint8_t led)//更新函数
{
GPIOC->ODR &= 0x00ff;//清零ODR高8位
GPIOC->ODR|=(~led<<8);//给值点灯
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);//更新数据
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);//更新数据
}
在SysTick_Handler调用
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */
if(uwTick % 500 == 0 )
{
led^=(1<<0);//异或:换灯
}
led_task(led);//给值点灯
if(uwTick % 1000 == 0)
{
led^=(1<<4);
}
led_task(led);
/* USER CODE END SysTick_IRQn 1 */
}
uwTick % 500 == 0 //对系统时钟进行取模运算
led^=(1<<n);//n表示第几盏灯
不用再主函数中做什么
二、串口传输
1、配置 默认波特率115200MHz
使能串口
1
的收发功能,一般情况下
轮询发送
+
中断接收
方式都能满足需求,波特率看题目要求,
般为
9600
,
注意串口
1
默认使用
PC4
和
PC5
作为收发引脚,需要更改
2、接收固定长度的数据帧,调用HAL_UART_Receive_IT()函数
main.c中外部声明变量
extern char RxBuffer[30];//数据缓冲区
extern uint8_t Rxdata;//存放数据的变量
extern uchar Rx_point;//指向数据的指针在主函数中开启中断接受
HAL_UART_Receive_IT(&huart1,&Rxdata,1);//串口接收一位数据
在interrupt.c中
//串口接受数据的中断回调函数
char RxBuffer[30];//数据缓冲区
uint8_t Rxdata;//存放数据的变量
uchar Rx_point;//指向数据的指针
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//stm32g4xx_hal_uart.c
{
RxBuffer[Rx_point++] = Rxdata;//接收到一位数据就存放起来
HAL_UART_Receive_IT(&huart1,&Rxdata,1);//串口接收一位数据
}
在main.c中编写接受处理函数
//串口处理接受数据函数
void uart_Rx(void)
{
if(Rx_point>0)
{
printf("接受的数据为: %s",RxBuffer);
//...其他处理内容
Rx_point=0;
memset(RxBuffer,0,30);
}
}
3、接收不定长的数据帧,常用两种方案:
通信双方确定帧格式,比如
”\r\n“
结束符,适用于数据连续发送的场景
利用
串口空闲中断或者定时器
判断数据发送是否结束,适用于数据不连续发送的场景
main.c中
定义uint8_t RxBuffer[200];//数据缓冲区
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)//stm32g4xx_hal_uart.c 中断空闲函数
{
if(huart->Instance == USART1)
{
printf("接受到%d数据为:%s\r\n",Size,RxBuffer);
HAL_UARTEx_ReceiveToIdle_IT(&huart1,RxBuffer,sizeof(RxBuffer));//stm32g4xx_hal_uart_ex.c
}
memset(RxBuffer, 0, sizeof(RxBuffer));//清除接受缓存
}
主函数内
HAL_UARTEx_ReceiveToIdle_IT(&huart1,RxBuffer,sizeof(RxBuffer));//开启空闲中断