STM32F030R8Tx使用HAL库实现uart通信

  • 准备工程,此例程在以下链接的工程的基础上添加的uart功能

https://blog.csdn.net/mygod2008ok/article/details/106910607

  • 添加stm32f0xx_hal_uart.c和stm32f0xx_hal_uart_ex.c到工程

  • 在stm32f0xx_hal_conf.h中打开HAL_UART_MODULE_ENABLED宏

  • 新建BSP_uart.c和BSP_uart.h并加入到工程中

  • BSP_uart.c内容如下:

#include "BSP_uart.h"
#include "stm32f0xx_hal_uart.h"
#include "main.h"
#include "BSP_delay.h"
#include "BSP_pwm.h"
#include "stm_log.h"

/* UART handler declaration */
UART_HandleTypeDef UartHandle;
__IO ITStatus UartReady = RESET;
__IO uint32_t UserButtonStatus = 0;  /* set to 1 after User Button interrupt  */

/* Buffer used for transmission */



#define BUFFER_COUNT    2
#define TX_RX_LENGTH		20
static uint8_t aTxBuffer[TX_RX_LENGTH];

/* Buffer used for reception */
static uint8_t aRxBuffer[BUFFER_COUNT][TX_RX_LENGTH];   // 2组缓冲

static volatile uint8_t s_receive_index;
static volatile uint32_t uartReceiveCharTimeout;

uint8_t s_save_rx_buf[TX_RX_LENGTH];

static volatile uint8_t *p_rec_buf = &aRxBuffer[0][0];


uint8_t enter_stm32_dfu;

uint8_t from_app_stm32_version[4];




/**
* @brief 配置串口输入上拉
*/
static void uart_config_input(void)
{
	
	USARTx_TX_GPIO_CLK_ENABLE();
  USARTx_RX_GPIO_CLK_ENABLE();

	GPIO_InitTypeDef  GPIO_InitStruct;
	GPIO_InitStruct.Pin       = USARTx_TX_PIN;
  GPIO_InitStruct.Mode      = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull      = GPIO_PULLUP;
  GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct);

  /* UART RX GPIO pin configuration  */
  GPIO_InitStruct.Pin = USARTx_RX_PIN;
  HAL_GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStruct);
}

/**
  * @brief UART MSP Initialization 
  *        This function configures the hardware resources used in this example: 
  *           - Peripheral's clock enable
  *           - Peripheral's GPIO Configuration  
  *           - NVIC configuration for UART interrupt request enable
  * @param huart: UART handle pointer
  * @retval None
  */
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{  
  GPIO_InitTypeDef  GPIO_InitStruct;
  
  /*##-1- Enable peripherals and GPIO Clocks #################################*/
  /* Enable GPIO TX/RX clock */
  USARTx_TX_GPIO_CLK_ENABLE();
  USARTx_RX_GPIO_CLK_ENABLE();


  /* Enable USARTx clock */
  USARTx_CLK_ENABLE(); 
  
  /*##-2- Configure peripheral GPIO ##########################################*/  
  /* UART TX GPIO pin configuration  */
  GPIO_InitStruct.Pin       = USARTx_TX_PIN;
  GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull      = GPIO_PULLUP;
  GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.Alternate = USARTx_TX_AF;

  HAL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct);

  /* UART RX GPIO pin configuration  */
  GPIO_InitStruct.Pin = USARTx_RX_PIN;
  GPIO_InitStruct.Alternate = USARTx_RX_AF;

  HAL_GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStruct);
    
  /*##-3- Configure the NVIC for UART ########################################*/
  /* NVIC for USART */
  HAL_NVIC_SetPriority(USARTx_IRQn, 0, 1);
  HAL_NVIC_EnableIRQ(USARTx_IRQn);
	
	
}

/**
  * @brief UART MSP De-Initialization 
  *        This function frees the hardware resources used in this example:
  *          - Disable the Peripheral's clock
  *          - Revert GPIO and NVIC configuration to their default state
  * @param huart: UART handle pointer
  * @retval None
  */
void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
{
  /*##-1- Reset peripherals ##################################################*/
  USARTx_FORCE_RESET();
  USARTx_RELEASE_RESET();

  /*##-2- Disable peripherals and GPIO Clocks #################################*/
  /* Configure UART Tx as alternate function  */
  HAL_GPIO_DeInit(USARTx_TX_GPIO_PORT, USARTx_TX_PIN);
  /* Configure UART Rx as alternate function  */
  HAL_GPIO_DeInit(USARTx_RX_GPIO_PORT, USARTx_RX_PIN);
  
  /*##-3- Disable the NVIC for UART ##########################################*/
  HAL_NVIC_DisableIRQ(USARTx_IRQn);
	
  uart_config_input();
}



static uint8_t s_receive_byte;
/**
* @brief 计算checksum
* @param [in] uint8_t const*
*  - 待计算的数据
* @param [in] uint8_t 
*  - len 计算数据的长度
* @return uint8_t
*  - checksum计算结果
*
*/
static uint8_t get_checksum(uint8_t const*dat, uint8_t len)
{
	uint8_t chksum = 0;
 
	for (uint8_t i = 0; i < len; i++)
		chksum += dat[i];

	return chksum;
}


/**
* @brief uart1 initialization
*/
void BSP_uart_init(void)
{
	
  /*##-1- Configure the UART peripheral ######################################*/
  /* Put the USART peripheral in the Asynchronous mode (UART Mode) */
  /* UART configured as follows:
      - Word Length = 8 Bits
      - Stop Bit = One Stop bit
      - Parity = None
      - BaudRate = 9600 baud
      - Hardware flow control disabled (RTS and CTS signals) */
	
  UartHandle.Instance        = USARTx;

  UartHandle.Init.BaudRate   = 115200;
  UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
  UartHandle.Init.StopBits   = UART_STOPBITS_1;
  UartHandle.Init.Parity     = UART_PARITY_NONE;
  UartHandle.Init.HwFlowCtl  = UART_HWCONTROL_NONE;
  UartHandle.Init.Mode       = UART_MODE_TX_RX;
  UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; 
	HAL_StatusTypeDef err_code = HAL_UART_DeInit(&UartHandle);
	APP_ERROR_CHECK(err_code);
  err_code = HAL_UART_Init(&UartHandle);
	APP_ERROR_CHECK(err_code);
	
	HAL_UART_Receive_IT(&UartHandle,&s_receive_byte, 1);
        UartReady = RESET;
}



/**
* @brief uart de-initialization
*/
void BSP_uart_deinit(void)
{

  HAL_StatusTypeDef err_code = HAL_UART_DeInit(&UartHandle);
  APP_ERROR_CHECK(err_code);
  UartReady = RESET;	 
	NRF_LOG_INFO("BSP_uart_deinit");
}



/**
* @brief 回复版本
*/
void reply_stm32_version(void)
{
	
		uint8_t buf[5];
		uint8_t version_buf[] = FIRMWARE_VERSION_DEF;
		for(uint8_t i=0; i<4; i++)
		{
			buf[i] = version_buf[i];
		}
		buf[4] = enter_stm32_dfu;
		USART_Send_Data(UART_GET_VERSION,buf,5);
	 
}



void USART_Send_Data(uint8_t cmd,uint8_t *pData, uint8_t len)
{
  /*##-2- Start the transmission process #####################################*/  
  /* While the UART in reception process, user can transmit data through 
     "aTxBuffer" buffer */
 
       if(UartReady)
	  return;
	uint8_t index = 0;
	aTxBuffer[index++] = UART_HEAD;
	aTxBuffer[index++] = 4;
	aTxBuffer[index++] = cmd;
	if(pData != NULL)
	{
		for(uint8_t i=0; i<len; i++)
		{
			aTxBuffer[index++] = *pData++;
		}
		aTxBuffer[1] += len;
	}
	len = aTxBuffer[1]-1;
	aTxBuffer[len] = get_checksum(aTxBuffer,len);
	
	HAL_UART_Transmit_IT(&UartHandle, aTxBuffer, aTxBuffer[1]);
	UartReady = SET;
}


/**
  * @brief  Tx Transfer completed callback
  * @param  UartHandle: UART handle. 
  * @note   This example shows a simple way to report end of IT Tx transfer, and 
  *         you can add your own implementation. 
  * @retval None
  */
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *UartHandle)
{
  /* Set transmission flag: transfer complete */
  UartReady = RESET;
//	NRF_LOG_INFO("TX_Handle");	
  
}

/**
  * @brief  Rx Transfer completed callback
  * @param  UartHandle: UART handle
  * @note   This example shows a simple way to report end of DMA Rx transfer, and 
  *         you can add your own implementation.
  * @retval None
  */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
  /* Set transmission flag: transfer complete */
	  static uint8_t index = 0;
    HAL_UART_Receive_IT(UartHandle, &s_receive_byte, 1);
	  aRxBuffer[index][s_receive_index] = s_receive_byte;
		
	  uartReceiveCharTimeout = UART_RECEIVE_CHAR_TIMEOUT;
	  if((++s_receive_index >= TX_RX_LENGTH) || (aRxBuffer[index][0] != UART_HEAD))
		{
			s_receive_index = 0;
		}
		else if((aRxBuffer[index][1] == s_receive_index) && (s_receive_index>=4))
		{
			s_receive_index -= 1;
			if(get_checksum(aRxBuffer[index], s_receive_index) == aRxBuffer[index][s_receive_index])
			{
				uartReceiveCharTimeout = 0;		   
        p_rec_buf = &aRxBuffer[index][0];
				if(++index >= BUFFER_COUNT)
				{
					index = 0;
				}	
         					
				s_wakeup_flag |= UART_RECEIVE_WAKEUP;
			}
		 
			s_receive_index = 0;
			
		}
}

/**
  * @brief  UART error callbacks
  * @param  UartHandle: UART handle
  * @note   This example shows a simple way to report transfer error, and you can
  *         add your own implementation.
  * @retval None
  */
void HAL_UART_ErrorCallback(UART_HandleTypeDef *UartHandle)
{
     NRF_LOG_INFO("HAL_UART_ErrorCallback");	
     UartReady = RESET;
	
//	  APP_ERROR_CHECK(UartHandle->ErrorCode);
}



/**
* @brief 串口接收超时处理,此函数25H中调用
*/
void uart1_rec_timeout(void)
{
  
  if(uartReceiveCharTimeout == 0)
	   return;
	if(--uartReceiveCharTimeout == 0)
	{
		s_receive_index = 0;
		NRF_LOG_INFO("uartTimeoutHandler");
	}
}

/**
* @brief 串口接收到的数据处理
*/
void uart_data_handler(void)
{
	if((s_wakeup_flag & UART_RECEIVE_WAKEUP)==0)
		return;
	s_wakeup_flag &= CLEAR_UART_RECEIVE_WAKEUP;
	
	switch(p_rec_buf[2])
	{
	
		case STM32_ENTER_DFU:
		{
			enter_stm32_dfu = 1;
			for(uint8_t i=0; i<4;i++)
			{
				from_app_stm32_version[i] = p_rec_buf[3+i];
				NRF_LOG_INFO("ver=%x ",from_app_stm32_version[i]);
			}
		}
		break;
		case UART_GET_VERSION:
			reply_stm32_version();
		  NRF_LOG_INFO("UART_GET_VERSION");	
			break;
		default:
			break;
	}
}
  • BSP_uart.h的内容如下:

#ifndef __BSP_UART_H_
#define __BSP_UART_H_
#include "main.h"

#ifdef __cplusplus
 extern "C" {
#endif

/* Definition for USARTx clock resources */
#define USARTx                           USART1
#define USARTx_CLK_ENABLE()              __HAL_RCC_USART1_CLK_ENABLE()
#define USARTx_RX_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOA_CLK_ENABLE()
#define USARTx_TX_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOA_CLK_ENABLE()

#define USARTx_FORCE_RESET()             __HAL_RCC_USART1_FORCE_RESET()
#define USARTx_RELEASE_RESET()           __HAL_RCC_USART1_RELEASE_RESET()

/* Definition for USARTx Pins */
#define USARTx_TX_PIN                    GPIO_PIN_9
#define USARTx_TX_GPIO_PORT              GPIOA
#define USARTx_TX_AF                     GPIO_AF1_USART1
#define USARTx_RX_PIN                    GPIO_PIN_10
#define USARTx_RX_GPIO_PORT              GPIOA
#define USARTx_RX_AF                     GPIO_AF1_USART1

/* Definition for USARTx's NVIC */
#define USARTx_IRQn                      USART1_IRQn
#define USARTx_IRQHandler                USART1_IRQHandler

/* Size of Trasmission buffer */
#define TXBUFFERSIZE                      (COUNTOF(aTxBuffer) - 1)
/* Size of Reception buffer */
#define RXBUFFERSIZE                      TXBUFFERSIZE
  
/* Exported macro ------------------------------------------------------------*/
#define COUNTOF(__BUFFER__)   (sizeof(__BUFFER__) / sizeof(*(__BUFFER__)))
	


#define U32_MAX_VALUE       0xffffffff
#define U16_MAX_VALUE       0xffff
#define U8_MAX_VALUE        0x1f


typedef enum
{
	
	UART_GET_VERSION = 0x01,
	STM32_ENTER_DFU = 0X02,
	UART_HEAD = 0xff,
}E_UART_COMMAND;


extern UART_HandleTypeDef UartHandle;

extern uint8_t from_app_stm32_version[4];
extern uint8_t enter_stm32_dfu;




void BSP_uart_init(void);
void BSP_uart_deinit(void);
void uart1_rec_timeout(void);
void uart_data_handler(void);

void reply_stm32_version(void);
void USART_Send_Data(uint8_t cmd,uint8_t *pData, uint8_t len);

#ifdef __cplusplus
}
#endif
#endif
  • 在stm32f0xx_it.c的USARTx_IRQHandler中断处理函数中调用HAL_UART_IRQHandler函数

/**
  * @brief  This function handles UART interrupt request.  
  * @param  None
  * @retval None
  * @Note   This function is redefined in "main.h" and related to DMA  
  *         used for USART data transmission     
  */
void USARTx_IRQHandler(void)
{
  HAL_UART_IRQHandler(&UartHandle);
}
  • 在main函数中调用BSP_uart_init函数初时化串口,调用reply_stm32_version函数将版本信息通过串口发出,主循环中调用uart_data_handler函数处理串口接收数据


/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
	RTT_INIT();
  HAL_Init();
  SystemClock_Config();
 
  BSP_adc_init();
	
  BSP_wdt_init(IWDG_OVER_TIME);
   
  delay_init();
  
	//--------初时化串口------------------------------------
  
   BSP_uart_init();
	
	 MX_RTC_Init();
	
	 BSP_start_adc_count(8);
	
	start_buzzer_beep_sound();
	
	reply_stm32_version();
	
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
		if(s_wakeup_flag)  //任务处理模式
		{
			BSP_wdt_feed();
			tick_25hz_handler();
			tick_1hz_handler();
			uart_data_handler();
		}
		else  // 省电模式
		{
		}
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
  • 在tick_25hz_handler函数中调用uart1_rec_timeout函数处理串口接收超时 


/**
* @brief 25Hz handler
*
*/
static void tick_25hz_handler(void)
{
	if((s_wakeup_flag & TICK_FOR_25HZ) == 0)
	  return;
	s_wakeup_flag &= CLEAR_TICK_FOR_25HZ;
//####################################################################################
	//---------TODO this to add 25hz event handler-----------
	BSP_adc_convert_handler();
  buzzer_beep_sound_handler();
	uart1_rec_timeout();
}
  • 串口收发采用了自定义协议,协议格式如下

head byte+total package length+command+0~n bytes data + checksum

  • 运行结果如下

  • demo下载地址,如果关注了的可以私信要资源

https://download.csdn.net/download/mygod2008ok/12540838

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风雨依依

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值