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

再次质疑 HAL_UART_Receive_IT函数  

[复制链接]
GKoSon 提问时间:2018-4-19 17:38 /
阅读主题, 点击返回1楼
收藏 1 评论37 发布时间:2018-4-19 17:38
37个回答
shuihehe 回答时间:2019-4-30 16:58:13
用寄存器 解决
edmundlee 回答时间:2019-5-1 13:13:06
兄弟,你会遇到这问题是因为你的编程思维方式还是停留在面向过程, 去搜一下状态机编程方法, 会对你有很大的帮助
streamlee 回答时间:2019-6-14 11:30:31
本人也是从传统的51单片机走过来的,习惯用寄存器直接操作串口,std标准库也比较顺手,最近搞cube接触了这个hal库,不得不说这个库很繁琐,封装太多,自然没有直接操作寄存器和std标准库效率高,但是还是探索了一番:在cube的FreeRTOS环境下,利用HAL操作串口, 发送使用非中断,接收使用中断。
streamlee 回答时间:2019-6-14 11:33:13
本帖最后由 streamlee 于 2019-6-14 12:13 编辑

1、初始化直接使用cube生产的代码,不做修改/* USART1 init function */
static void MX_USART1_UART_Init(void)
{
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_8;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
}

2、发送重写printf,加互斥量
static char string[512];
void my_printf(char *fmt,...)
{
  va_list ap;
  osMutexWait(debug_mutex_id,osWaitForever);
  va_start(ap,fmt);
  vsprintf(string,fmt,ap);
  HAL_UART_Transmit(&huart1, (uint8_t*)string, strlen(string), 100);
  //HAL_UART_Transmit_IT(&huart1, (uint8_t*)string, strlen(string));
  va_end(ap);
  osMutexRelease(debug_mutex_id);
}

3、接收单独一个task处理,使用中断方式,配合FreeRTOS的等待信号量超时操作,处理不定长接收。超时时间定为10ms。
void taskUart(void const * argument)
{
  uint8_t *buf1 = pvPortMalloc(256);
  uint8_t *buf2 = pvPortMalloc(256);
  uint8_t *uartTXbuf= buf1;
  uint8_t *recvData = uartTXbuf;
  uint16_t lenth;
  (char*)argument;
  osSemaphoreWait(uartRx_sem_id,0);
  if(!buf1 || !buf2)
  {
    my_printf("%s[%d]:pvPortMalloc buf1 or buf2 fail!\r\n",__FUNCTION__,__LINE__);
    while(1){};
  }
  my_printf("%s:ready\r\n",__FUNCTION__);
  HAL_UART_Receive_IT(&huart1,uartTXbuf,256);
  while(1)
  {
     osSemaphoreWait(uartRx_sem_id,10);
     recvData = uartTXbuf;
     lenth = 256 - huart1.RxXferCount;
     HAL_UART_AbortReceive_IT(&huart1);
     if(uartTXbuf == buf1)//乒乓操作
       uartTXbuf = buf2;
     else
       uartTXbuf = buf1;
     if(HAL_UART_Receive_IT(&huart1,uartTXbuf,256)!=HAL_OK)
     {
        my_printf("%s:HAL_UART_Receive_IT not ok!\r\n",__FUNCTION__);
     }
     if(lenth>0)
     {
      uartDataPro(recvData,lenth);
     }
  }
}

4、接收完成中断自然是发送信号量
/* USER CODE BEGIN 0 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  osSemaphoreRelease(uartRx_sem_id);
}
/* USER CODE END 0 */

5、串口实际效果如下图所示:(uartDataPro(recvData,lenth);直接把接收的数据打印了出来并添加回车换行)
由于接收超时时间是10ms,串口工具发送时间是随机,所以可以看到有些数据被分成了2段接收,但是并没有数据丢失,得益于我们采用的乒乓操作和串口任务的高优先级,接收超时后,立刻切换buf后重新开启接收中断。
uart.png
edmundlee 回答时间:2019-6-14 13:07:41
库, 我只来配置外设。
zhjb1 回答时间:2019-10-17 10:47:36
谢谢各位同仁!因为搬家一直没有时间玩这些,稳定后会回来的!
Ankky 回答时间:2020-1-5 11:27:01
ringsp 发表于 2018-9-8 07:10
一大帮干单片机的,看到st的驱动库惊为高科技。用过环形队列做串口收发吗?真正理解钩子函数吗?用过链表 ...

建议赶紧去医院检查一下脑子。
shiinakaze 回答时间:2023-11-6 16:45:45

Dandjinh 发表于 2018-4-20 13:30
HAL_UART_Receive_IT(&amp;huart1, (uint8_t *)aRxBuffer, Number);意思是接收到Number个字节后,触发HAL<em>UART</em> ...

老哥一针见血,怪不得怎么不触发中断,原来得 *pData 满才会触发。

123

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版