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

HAL怎么写串口接收函数?

[复制链接]
sos博 提问时间:2019-7-13 11:01 /
我想实现的就是,能收到其他设备发来的命令比如  openled  ,然后mcu收到命令就点GPIO。

我现在的情况是:

芯片:042
库:HAL
串口方式:DMA串口收和发


我现在的问题是:
uint8_t cc[] = "hello sos";
1,可以正常发数据  使用HAL_UART_Transmit_DMA(&huart1, cc, (strlen(cc)));    //这里不知道用strlen对不对,反正我用sizeof不能读空格后面的sos。
2,我不知道接收数据函数怎么使用,HAL_UART_Receive_DMA(&huart1, cc, (strlen(cc)));
3,HAL_UART_RxCpltCallback这个串口接收完成回调函数是,收到数据后,才进这个函数吗?我在这里面放了点灯函数,结果上电灯就亮。我没给它发数据,为什么还是进到了这个函数呢?




综上,我的问题是,怎么能收到命令?我有30多条命令要接收,判断执行不同功能。
这个HAL有点懵。


谢谢好心人。自己研究好几天了也没头绪。


收藏 评论11 发布时间:2019-7-13 11:01

举报

11个回答
sos博 回答时间:2019-7-13 11:07:28
我写了2个函数
  1. void send_str(uint8_t *cc)
  2. {
  3.         HAL_UART_Transmit_DMA(&huart1, cc, (strlen(cc)));
  4. }

  5. uint8_t* rev_str()
  6. {
  7.         uint8_t *cc;
  8.         HAL_UART_Receive_DMA(&huart1, cc, (strlen(cc)));
  9.         return cc;
  10. }
复制代码
1,把send_str放到main的while(1)里面好用,正常输出。
2,我这样弄,send_str(rev_str());   收不到我发送给mcu的数据
3,我又看人有这样的if(strcmp(rev_str(),getdown)==0)     //uint8_t getdown[] = "get_down";
没效果。

4,我不知道应该怎样收数据,来判断收到的是啥。

radio2radio 回答时间:2019-7-13 11:22:25
UART是人人都用的,建议您找一套UART收发正常的底包,然后改成自己适用的。
不能指望一条语句就搞定。

参考:
https://www.stmcu.org.cn/module/forum/thread-616613-1-1.html
https://www.stmcu.org.cn/module/forum/thread-619702-1-1.html
wenyangzeng 回答时间:2019-7-13 11:27:18
sos博 发表于 2019-7-13 11:07
我写了2个函数
1,把send_str放到main的while(1)里面好用,正常输出。
2,我这样弄,send_str(rev_str());  ...

ST官方有很多DEMO可以参考呀:
UART_Printf.rar (43.06 KB, 下载次数: 6)
sos博 回答时间:2019-7-13 12:32:24
本帖最后由 sos博 于 2019-7-13 13:05 编辑
radio2radio 发表于 2019-7-13 11:22
UART是人人都用的,建议您找一套UART收发正常的底包,然后改成自己适用的。
不能指望一条语句就搞定。

看了你文章,想问一个太低端的问题。。。
如果在main的while里面这样写,我这个写法肯定不对,但是我的意思你应该明白了。
  1. if(rx_flag==1)
  2.                 {
  3.                         switch(UART1_Rx_Buffer)//HAL_UART_Receive_DMA(&huart1, UART1_Rx_Buffer, DMA_RX_BUFFER_SIZE);
  4.                         {
  5.                                 case "openled": HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);break;
  6.                                 case "closeled": HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);break;
  7.                                 case "temp": HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);break;
复制代码
就是怎么把指针UART1_Rx_Buffer里面的内容,变成明文?用来让我识别读出。还有switch里面case直接接 “字符串命令”,这样可以吗?
回答时间:2019-7-13 16:22:59
确实不太方便,我使用的时候,把他这个改掉了。用的环形队列接收数据。
mikecai 回答时间:2019-7-13 19:29:56
接收可用DMA, 发送就不必。DMA接收函数用一次启动即可,不必每次用callback接收到DMA;用环形DMA是好主意,可参考本论坛原创:”基于DMA循环接收的串口不定长数据处理方案“一文:  https://www.stmcu.org.cn/module/forum/thread-613418-1-57.html
再参考串口 波特率,如单字节传送时间为3 ms, 设15 ms 查询或定时中断即可晓得是否结束了 串口不定长数据接收, 实在还不行,加换行或回车符 检查啊。

评分

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

查看全部评分

sos博 回答时间:2019-7-13 21:22:06
安 发表于 2019-7-13 16:22
确实不太方便,我使用的时候,把他这个改掉了。用的环形队列接收数据。

能分享一下你的串口相关的几句代码吗?感谢。
radio2radio 回答时间:2019-7-13 21:25:18
本帖最后由 radio2radio 于 2019-7-13 21:28 编辑
sos博 发表于 2019-7-13 12:32
看了你文章,想问一个太低端的问题。。。
如果在main的while里面这样写,我这个写法肯定不对,但是我的意 ...

你说的是UART接受数据的解析,如果命令少可以很简单, 如果命令很多,有可能很复杂麻烦。
关键是把逻辑搞清楚。我也不是很有经验,只能说一说我使用过的方法。

1. 把收到的字符串放入一个数组变量,也就是那个缓冲区Buffer[x]
2. 三个命令只解析前面的4个字符,open/clos/temp
3. 每当接收到4个字符,就产生一次rx_flag=1
      4. 使用memcmp(),比较是否三个命令之一,如果是就执行相应动作.
      5. 清空Buffer,rx_flag=0
6. 搞一个timeout机制,当一定的时间内,比如10ms,只收到<=3个字符,清空Buffer。

至于是用while/switch/if来做开关,看您自己的喜欢。

除了memcmp()内存比较函数,还有个strstr()函数可以用于复杂情况(不建议用)。


评分

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

查看全部评分

sos博 回答时间:2019-7-13 21:34:11
radio2radio 发表于 2019-7-13 21:25
你说的是UART接受数据的解析,如果命令少可以很简单, 如果命令很多,有可能很复杂麻烦。
关键是把逻辑搞 ...

哦,我学你那个,然后把flag=1放到HAL_UART_RxCpltCallbacki里面了,我DMA_RX_BUFFER_SIZE也学习你的先写了128,然后我就发现,确实好用,现象是,必须收够128个才进入flag=1,比如我发12345678,我得发16次,凑够128个数才进入接收完成回调函数。
我想问,它能根据发来的数据自动判断是多少个DMA_RX_BUFFER_SIZE吗?比如见到空格就算一次接收完成。
我现在真的什么都不记得了。记得以前的标准库是可以实现的。
12下一页

所属标签

相似问题

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