你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

关于STM32cubemx 串口如何中断接收发来的不定长数据

[复制链接]
张亚飞 提问时间:2017-6-1 16:39 /
阅读主题, 点击返回1楼
收藏 评论47 发布时间:2017-6-1 16:39
47个回答
时光虫子 回答时间:2017-6-5 14:55:05
串口缓冲区开大点,接收和读取用环形缓冲区
张亚飞 回答时间:2017-6-5 15:11:41
时光虫子 发表于 2017-6-5 14:55
串口缓冲区开大点,接收和读取用环形缓冲区

有点答非所问吧。 stm32cubemx 串口中断接收函数只能定长接收数据。
深谷幽泉 回答时间:2017-6-6 00:42:26
张亚飞 发表于 2017-6-5 09:06
标准库的接收不用定长接收吧。

DMA+总线空闲中断,是实现不定长度接收的最好的办法。
另外,如果你接收的数据帧是有固定格式,只是每帧长度不一样,比如帧格式中有数据长度位,可以通过判断已接收的长度是否等于帧中数据长度位来判定当前数据是否接收完成。不过这样做相比用DMA+空闲中断接收要麻烦一些,效率低还容易出错。
haogong-325897 回答时间:2017-7-1 17:28:18
还是没能解决,看来hal库有待于完善。
loodao 回答时间:2017-8-1 06:28:16
来帮搂主挺,本人遇到同样的问题,看了那篇“串口+DMA..."文章,但总觉得不是我要的,我的要得跟楼主一样
kylongmu 回答时间:2017-8-3 20:43:43
这个问题很简单,但是你首先要把函数的接收缓冲区长度,与你要接收任意长度两个概念分开。
你的接收缓冲区工作在自动填充启动模式,比如你设置100个字节接收,然后在接收完了自动再调用一次,重新设置100个字节接收。等于说接收函数处于无穷状态,随时等待接收。
-----------------------------------------------------------------------------------------
在中断函数里,对每次接收到的数据进行判断,分解到你希望的任意长度,并复制数据到你希望的缓冲区。
搞清楚你要的,与函数的实现方式,才是本质问题。
张亚飞 回答时间:2017-8-4 09:56:07
kylongmu 发表于 2017-8-3 20:43
这个问题很简单,但是你首先要把函数的接收缓冲区长度,与你要接收任意长度两个概念分开。
你的接收缓冲区 ...

你的意思是改HAL库的源码了?不改源码我就只能在接收完成的回调函数里进行我的操作,但是跟不定长接收没关系了。
kylongmu 回答时间:2017-8-4 10:05:58
张亚飞 发表于 2017-8-4 09:56
你的意思是改HAL库的源码了?不改源码我就只能在接收完成的回调函数里进行我的操作,但是跟不定长接收没 ...

改hal源码?你想歪了。
张亚飞 回答时间:2017-8-4 11:17:48
kylongmu 发表于 2017-8-4 10:05
改hal源码?你想歪了。

在中断函数里,对每次接收到的数据进行判断,分解到你希望的任意长度,并复制数据到你希望的缓冲区。 这是你说的。 在stm32cubemx的工程里如果是固定长度接收的话只需要在接收完成的回调函数里处理即可,谈何在中断函数里对数据进行判断呢?  
kylongmu 回答时间:2017-8-5 12:58:03
张亚飞 发表于 2017-8-4 11:17
在中断函数里,对每次接收到的数据进行判断,分解到你希望的任意长度,并复制数据到你希望的缓冲区。 这 ...

HAL_UART_Receive_IT(&huart3,UART3_R_Msg.Recive_Buf, QUEUE_MESSAGE_MAX_SIZE)
这个函数是设置固定接受缓冲区长度的。
-------------------------------------------------------
这是CubeMX给你生成的中断函数:
void USART3_IRQHandler(void)
{
  /* USER CODE BEGIN USART3_IRQn 0 */

  /* USER CODE END USART3_IRQn 0 */
  HAL_UART_IRQHandler(&huart3);
  /* USER CODE BEGIN USART3_IRQn 1 */

  /* USER CODE END USART3_IRQn 1 */
}
里面有2处添加你自己代码的地方,在这里增加你的代码判断,并复制数据到你希望的缓冲区。把串口工作的数据缓冲区当作从头到尾循环工作的方式,判断接收到尾后重新调用HAL_UART_Receive_IT。
设置全局变量,或者信号量,在检测到你希望的数据流时通知线程处理。
把HAL_UART_Receive_IT,HAL_UART_IRQHandler里面源代码好好看看,理解了你才能明白如果做。
kylongmu 回答时间:2017-8-5 13:00:53
时光虫子 发表于 2017-6-5 14:55
串口缓冲区开大点,接收和读取用环形缓冲区

接收和读取用环形缓冲区
这是关键点,你想明白了就明白。
avenbbs-241604 回答时间:2017-8-8 16:01:50
int main(void)
{
  ...
  HAL_UART_Receive_IT(&huart1, (uint8_t *)&RxByte1, 1);
  ...
  whine(1)
  {
  ...
  }
  ...
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
        printf("%c",RxByte1);
        HAL_UART_Receive_IT(&huart1, (uint8_t *)&RxByte1, 1);
}

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

一叶清风 回答时间:2018-1-5 22:55:11
学习了
a1312 回答时间:2018-5-10 16:17:08

虽然你把每个数据都打印出来了,看起来RxByte1像是保存了不止一个数据,但实际上RxByte1里只保存1字节数据

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

karzn 回答时间:2018-5-14 08:40:39
谢谢分享!!

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版