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

HAL_UART_Transmit_DMA函数在循环前正常,放入while(1)循环不正常

[复制链接]
Harry_wu 提问时间:2020-5-3 19:56 /
悬赏1ST金币已解决
尝试使用HAL_UART_Transmit_DMA进行发送数据到串口上位机。main()函数的代码主要为如下三段:
1. 用printf打印一些字符串到PC-----------运行正常
2. 用HAL_UART_Transmit_DMA打印一段字符串到PC---故意打印两遍均正常
3. 将HAL_UART_Transmit_DMA放在while(1)循环中每隔2s打印------不正常,PC端未见输出
不清楚什么影响了HAL_UART_Transmit_DMA在while(1)的正常运行? 在做debug时将断点设置到while(1)中的HAL_UART_Transmit_DMA行,再单步运行又可以打印出来字符串,不知道如何分析,求指点。

  1. int main(void)
  2. {
  3. ***
  4. uint8_t aTxMessage[] = "\r\n**** UART-Hyperterminal communication based on DMA ***\r\n    The 2nd line with DMA \r\n";

  5.         /* RS485发送前才使能发送模式,发送完毕马上转为接收模式 */
  6.         HAL_GPIO_WritePin(DMX_DIR_GPIO_Port, DMX_DIR_Pin, GPIO_PIN_SET);  //RS485输出使能
  7.         printf("***************************************************\r\n\r\n");
  8.         printf("*                                                 *\r\n");
  9.         printf("************* 测试一下中文字符 ********************\r\n");
  10.         printf("*                                                 *\r\n");
  11.         printf("***************************************************\r\n\r\n");
  12.         HAL_GPIO_WritePin(DMX_DIR_GPIO_Port, DMX_DIR_Pin, GPIO_PIN_RESET);  //RS485输入使能
  13.         HAL_Delay(1000);


  14.         HAL_GPIO_WritePin(DMX_DIR_GPIO_Port, DMX_DIR_Pin, GPIO_PIN_SET);  //RS485输出使能
  15.         HAL_Delay(1000);
  16.         HAL_UART_Transmit_DMA(&huart1, (uint8_t *)aTxMessage, sizeof(aTxMessage)-1);
  17.         HAL_GPIO_WritePin(DMX_DIR_GPIO_Port, DMX_DIR_Pin, GPIO_PIN_RESET);  //RS485输入使能
  18.         HAL_GPIO_WritePin(DMX_DIR_GPIO_Port, DMX_DIR_Pin, GPIO_PIN_SET);  //RS485输出使能
  19.         HAL_Delay(1000);
  20.         HAL_UART_Transmit_DMA(&huart1, (uint8_t *)aTxMessage, sizeof(aTxMessage)-1);
  21.         HAL_GPIO_WritePin(DMX_DIR_GPIO_Port, DMX_DIR_Pin, GPIO_PIN_RESET);  //RS485输入使能
  22.         HAL_Delay(1000);
  23.   /* USER CODE END 2 */


  24.   /* Infinite loop */
  25.   /* USER CODE BEGIN WHILE */
  26.   while (1)
  27.   {
  28.     /* USER CODE END WHILE */

  29.     /* USER CODE BEGIN 3 */
  30.                 HAL_GPIO_WritePin(DMX_DIR_GPIO_Port, DMX_DIR_Pin, GPIO_PIN_SET);  //RS485输出使能
  31.                 HAL_Delay(1000);
  32.                 HAL_UART_Transmit_DMA(&huart1, (uint8_t *)aTxMessage, sizeof(aTxMessage)-1);
  33.                 HAL_GPIO_WritePin(DMX_DIR_GPIO_Port, DMX_DIR_Pin, GPIO_PIN_RESET);  //RS485输入使能
  34.     HAL_Delay(1000);

  35.   }
  36.   /* USER CODE END 3 */
  37. }
复制代码




最佳答案

查看完整内容

把上述代码改为: 应该就可以了。 原因是串口数据未发送完成,就将RS485输出使能关闭了。采用延时后关闭,或者发送完成回调中开启RS485输入使能开启。
收藏 评论6 发布时间:2020-5-3 19:56

举报

6个回答
byronsong 回答时间:2020-5-3 19:56:53

  1.         HAL_GPIO_WritePin(DMX_DIR_GPIO_Port, DMX_DIR_Pin, GPIO_PIN_SET);  //RS485输出使能
  2.         HAL_Delay(1000);
  3.         HAL_UART_Transmit_DMA(&huart1, (uint8_t *)aTxMessage, sizeof(aTxMessage)-1);
复制代码

把上述代码改为:

  1.         HAL_GPIO_WritePin(DMX_DIR_GPIO_Port, DMX_DIR_Pin, GPIO_PIN_SET);  //RS485输出使能
  2.         HAL_Delay(5);
  3.         HAL_UART_Transmit_DMA(&huart1, (uint8_t *)aTxMessage, sizeof(aTxMessage)-1);
  4.         HAL_Delay(995);
  5.         HAL_GPIO_WritePin(DMX_DIR_GPIO_Port, DMX_DIR_Pin, GPIO_PIN_RESET);
复制代码

应该就可以了。


原因是串口数据未发送完成,就将RS485输出使能关闭了。采用延时后关闭,或者发送完成回调中开启RS485输入使能开启。

评分

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

查看全部评分

烟花绽放 回答时间:2020-5-3 21:45:06
判断下是否发送完成呢
Harry_wu 回答时间:2020-5-4 10:34:53
songshiqun2010 发表于 2020-5-4 08:00
把上述代码改为:

应该就可以了。

你说的完全正确:DMA串口发送数据需要时间,而我马上下一句我就关闭了RS485的输出,导致数据没有发出去。所以昨天我将while(1)循环前的代码改成了下面这样:
  1. HAL_GPIO_WritePin(DMX_DIR_GPIO_Port, DMX_DIR_Pin, GPIO_PIN_SET);  //RS485输出使能
  2.         HAL_UART_Transmit_DMA(&huart1, (uint8_t *)aTxMessage, sizeof(aTxMessage)-1);
  3.         HAL_Delay(500);
  4.         HAL_GPIO_WritePin(DMX_DIR_GPIO_Port, DMX_DIR_Pin, GPIO_PIN_SET);  //RS485输出使能
  5.         HAL_UART_Transmit_DMA(&huart1, (uint8_t *)aTxMessage, sizeof(aTxMessage)-1);
复制代码
将开启RS485输入使能放入回调函数,在Transmit_DMA和RS485输出使能之间加了延时。也是因为开头的原因:防止先执行开启了RS485的输出使能,然后回调函数后运行关闭了RS485输出使能,导致下一个Transmit_DMA发送失败

while(1)循环中也必须留意Transmit_DMA和RS485输出使能之间增加延时。


非常感谢!

Harry_wu 回答时间:2020-5-4 10:37:01
烟花绽放 发表于 2020-5-3 21:45
判断下是否发送完成呢

思路对的,确实是DMA搬运和下一句关RS485输出会“同时”进行,我还是按先执行DMA,再执行关RS485的想法去查问题了,导致一开始没考虑到此原因。
李康1202 回答时间:2020-5-4 18:53:06
检查一下发完没有
yzz163 回答时间:2020-12-10 17:47:39
HAL_Delay(995); 是关键。。没发完就开始干其他事情了。。

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版