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

再次质疑 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管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版