STM32笔记——串口发送宽度为9位的数据

最近为了配置一个芯片使用到了串口发送9位数据位的情况,在此小记一下。

1. 串口硬件和参数初始化

将数据位宽度配置成:UART_WORDLENGTH_9B ,其他参数和常规配置一样。

UART_HandleTypeDef husart3;

void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{

  GPIO_InitTypeDef GPIO_InitStruct;
  if(huart->Instance==USART3)
  {
 	 __HAL_RCC_GPIOC_CLK_ENABLE();//IO时钟使能
  
    GPIO_InitStruct.Pin = USARTx_Tx_GPIO_PIN|USARTx_Rx_GPIO_PIN;//PB10和PB11
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = USARTx_AFx;
    HAL_GPIO_Init(USARTx_Tx_GPIO, &GPIO_InitStruct);
    
    GPIO_InitStruct.Pin = USARTx_Rx_GPIO_PIN;
    HAL_GPIO_Init(USARTx_Rx_GPIO, &GPIO_InitStruct);
  }
}

void MX_USART3_Init(void)
{
 	 __HAL_RCC_USART3_CLK_ENABLE();//串口3时钟使能
  
    huart3.Instance = USART3;
    huart3.Init.BaudRate = USART3_BAUDRATE;
    huart3.Init.WordLength = UART_WORDLENGTH_9B;//数据位宽度改为9位
    huart3.Init.StopBits = UART_STOPBITS_1;//一位停止位
    huart3.Init.Parity = UART_PARITY_NONE;//无奇偶校验位
    huart3.Init.Mode = UART_MODE_TX_RX;
    huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart3.Init.OverSampling = UART_OVERSAMPLING_16;
    HAL_UART_Init(&huart3);
   
    HAL_UART_Receive_IT(&huart3,Usart3_TempData,1);  
	HAL_NVIC_SetPriority(USART3_IRQn, 2, 2);
    HAL_NVIC_EnableIRQ(USART3_IRQn);
}

2. 串口发送相关库函数的修改

看了下库函数,如果想要收发数据位宽度为9位的数据,貌似只能够通过阻塞模式发送,如下是阻塞模式下串口发送数据的库函数(省略部分函数,只留取了最关键的代码):

/**
  * @brief  Sends an amount of data in blocking mode. 
  * @param  huart: pointer to a UART_HandleTypeDef structure that contains
  *                the configuration information for the specified UART module.
  * @param  pData: Pointer to data buffer
  * @param  Size: Amount of data to be sent
  * @param  Timeout: Timeout duration  
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
      ...省略
      if(huart->Init.WordLength == UART_WORDLENGTH_9B)
      {
            ...省略
	        tmp = (uint16_t*) pData;
	        huart->Instance->DR = (*tmp & (uint16_t)0x01FF);
	        ...省略
      }
      ...省略
}

我发现这个库函数发送数据宽度为9位数据时时这样的,如果第9位数据为0的话,本质就是在停止位前添加一位数据0,如果第九位想发1的话,那就不需要这个函数了,即通过正常的8N1格式发送即可,直接用停止位当第9位就可以.

这样的话是可以实现,只是比较麻烦。比如在使用9位数据宽度配置一些传感器时需要反复的将第9位变为1或0,如果按照官方提供的这种库函数来实现的话,那就得反复将串口配置成8B或9B的模式,非常的不方便,也很不直观。所以我把这个函数做了一些简单的修改,多加了一个第9位位选择的参数。

程序如下:

/**
  * @brief  Sends an amount of data in blocking mode. 
  * @param  huart: pointer to a UART_HandleTypeDef structure that contains
  *                the configuration information for the specified UART module.
  * @param  pData: Pointer to data buffer
  * @param  Size: Amount of data to be sent
  * @param  Bit_9 : bit 9 state
  * @param  Timeout: Timeout duration  
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_UART_Transmit_9B(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint8_t Bit_9, uint32_t Timeout)
{
      ...省略
      if(huart->Init.WordLength == UART_WORDLENGTH_9B)
      {
          ...省略  
          tmp = (uint16_t*) pData;
          //huart->Instance->DR = (*tmp & (uint16_t)0x01FF);之前的数据处理方式屏蔽掉
          //以下是自己添加的第九位数据位处理的相关代码
          if(Bit_9 == 1)
          {
              huart->Instance->DR = (*tmp | (uint16_t)0x0100);//将第九位置1
          }
          else
          {
              huart->Instance->DR = (*tmp & (uint16_t)0x00FF);//将第九位置0
          }
	      ...省略
      }
      ...省略
}

提示:最后就是记得在头文件中声明该函数!

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值