完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
最近为了配置一个芯片使用到了串口发送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 } ...省略 } ...省略 } 提示:最后就是记得在头文件中声明该函数! |
|
|
|
只有小组成员才能发言,加入小组>>
3314 浏览 9 评论
2995 浏览 16 评论
3494 浏览 1 评论
9059 浏览 16 评论
4088 浏览 18 评论
1178浏览 3评论
605浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
599浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2335浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1896浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 11:52 , Processed in 1.106840 second(s), Total 77, Slave 58 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号