OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5869|回复: 18

看了F429视频感觉HAL库的处理方式感觉好麻烦

[复制链接]

37

主题

246

帖子

0

精华

高级会员

Rank: 4

积分
774
金钱
774
注册时间
2016-9-10
在线时间
310 小时
发表于 2017-3-26 19:40:05 | 显示全部楼层 |阅读模式
1金钱
看了串口中断和外部中断,在中断里面去调用函数,而且调用的函数里面再去调用回调函数,难道调用函数不要开销,像标准库一样直接在中断里面写要实现的功能多好,还有串口中断调用那个函数,还要先确定接收到的是几个字符,万一数据有长有短,并且不知道即将来的数据个数,又怎么去处理?刚从标准库过来,还不习惯,还望大神解惑

最佳答案

查看完整内容[请看2#楼]

实际上 类似Linux系统 这种回调函数的模式还是挺多的。 这么做的目的我认为主要还是把软件分层,做上层应用的只需要在相关事件的回调函数写好自己定义的动作就好,不用管其他的比如清楚标志位什么的,就串口单个外设来看确实麻烦,但是系统整体上看,所有外设都可以套用一种模式是可以缩短开发进程的
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

174

帖子

0

精华

高级会员

Rank: 4

积分
725
金钱
725
注册时间
2016-1-9
在线时间
64 小时
发表于 2017-3-26 19:40:06 | 显示全部楼层
本帖最后由 whyviking 于 2017-3-26 20:36 编辑
1491430114 发表于 2017-3-26 20:26
进一次中断就需要做这么多的判断,就算能实现,也不利于代码的阅读吧

实际上 类似Linux系统 这种回调函数的模式还是挺多的。 这么做的目的我认为主要还是把软件分层,做上层应用的只需要在相关事件的回调函数写好自己定义的动作就好,不用管其他的比如清楚标志位什么的,就串口单个外设来看确实麻烦,但是系统整体上看,所有外设都可以套用一种模式是可以缩短开发进程的
回复

使用道具 举报

0

主题

174

帖子

0

精华

高级会员

Rank: 4

积分
725
金钱
725
注册时间
2016-1-9
在线时间
64 小时
发表于 2017-3-26 19:50:39 | 显示全部楼层
接收不用先确定接收几个字符啊,串口的中断是每接收1个字节中断一次,原子的源码是通过在中断回调函数中判断是否接收到0X0D和 0X0A来判断数据是否接收结束。
回复

使用道具 举报

0

主题

174

帖子

0

精华

高级会员

Rank: 4

积分
725
金钱
725
注册时间
2016-1-9
在线时间
64 小时
发表于 2017-3-26 19:53:13 | 显示全部楼层
HAL库 确实开销大点 ,主要是为了增加软件的可移植性。对CPU开销敏感的话可以用DMA或者直接用寄存器操作
回复

使用道具 举报

37

主题

246

帖子

0

精华

高级会员

Rank: 4

积分
774
金钱
774
注册时间
2016-9-10
在线时间
310 小时
 楼主| 发表于 2017-3-26 20:02:13 | 显示全部楼层
whyviking 发表于 2017-3-26 19:50
接收不用先确定接收几个字符啊,串口的中断是每接收1个字节中断一次,原子的源码是通过在中断回调函数中判 ...

那个UART_Receive_IT()里面定义了接收到几个字符后进入回调函数,如果是数据长度不确定,也没有确定的结束符,怎么来写这个回调函数?
回复

使用道具 举报

37

主题

246

帖子

0

精华

高级会员

Rank: 4

积分
774
金钱
774
注册时间
2016-9-10
在线时间
310 小时
 楼主| 发表于 2017-3-26 20:06:06 | 显示全部楼层
whyviking 发表于 2017-3-26 19:53
HAL库 确实开销大点 ,主要是为了增加软件的可移植性。对CPU开销敏感的话可以用DMA或者直接用寄存器操作

主要是感觉它管得太多了
回复

使用道具 举报

0

主题

174

帖子

0

精华

高级会员

Rank: 4

积分
725
金钱
725
注册时间
2016-1-9
在线时间
64 小时
发表于 2017-3-26 20:07:04 | 显示全部楼层
UART_Receive_IT()这里是接收BUFFER的长度 也就是最大接收长度
回复

使用道具 举报

0

主题

174

帖子

0

精华

高级会员

Rank: 4

积分
725
金钱
725
注册时间
2016-1-9
在线时间
64 小时
发表于 2017-3-26 20:12:53 | 显示全部楼层
而且原子的源码里  串口的处理是在回调函数中的另一个数组,在原子的源码里UART_Receive_IT()中的buffer实际上只用了1个位,然后在中断回调里不停的读buffer[0]到自己的数组里。结束符是0X0D 0X0A 来判断,这里0X0D 0X0A 是根据调试助手的发送新行选项来的也就是\r\n  你要想自己的写的话可以用定时器定个100ms 然后接收一个字节就喂一次狗,定时器溢出了就说明接完了
回复

使用道具 举报

37

主题

246

帖子

0

精华

高级会员

Rank: 4

积分
774
金钱
774
注册时间
2016-9-10
在线时间
310 小时
 楼主| 发表于 2017-3-26 20:17:12 | 显示全部楼层
whyviking 发表于 2017-3-26 20:07
UART_Receive_IT()这里是接收BUFFER的长度 也就是最大接收长度

在UART_Receive_IT()中有这么一个判断if(--huart->RxXferCount == 0)后才进回调函数,如果按最大设置,可能来的是一组短数据不能触发回调函数怎么办
回复

使用道具 举报

0

主题

174

帖子

0

精华

高级会员

Rank: 4

积分
725
金钱
725
注册时间
2016-1-9
在线时间
64 小时
发表于 2017-3-26 20:24:09 | 显示全部楼层
1491430114 发表于 2017-3-26 20:17
在UART_Receive_IT()中有这么一个判断if(--huart->RxXferCount == 0)后才进回调函数,如果按最大设置,可 ...

RxXferCount 的值是1   每收到一个字节都会调回调函数  并且再重新调用HAL_UART_Receive_IT()
回复

使用道具 举报

37

主题

246

帖子

0

精华

高级会员

Rank: 4

积分
774
金钱
774
注册时间
2016-9-10
在线时间
310 小时
 楼主| 发表于 2017-3-26 20:24:34 | 显示全部楼层
whyviking 发表于 2017-3-26 20:12
而且原子的源码里  串口的处理是在回调函数中的另一个数组,在原子的源码里UART_Receive_IT()中的buffer实 ...

在标准库里面我直接定义一个临时变量,让它自减,如果减完前接收到一个新的字符就重置,减完所用的时间大概为串口接收三五个字符的时间,这样可以一次性接收一组完整数据
回复

使用道具 举报

37

主题

246

帖子

0

精华

高级会员

Rank: 4

积分
774
金钱
774
注册时间
2016-9-10
在线时间
310 小时
 楼主| 发表于 2017-3-26 20:26:53 | 显示全部楼层
whyviking 发表于 2017-3-26 20:24
RxXferCount 的值是1   每收到一个字节都会调回调函数  并且再重新调用HAL_UART_Receive_IT()

进一次中断就需要做这么多的判断,就算能实现,也不利于代码的阅读吧
回复

使用道具 举报

37

主题

246

帖子

0

精华

高级会员

Rank: 4

积分
774
金钱
774
注册时间
2016-9-10
在线时间
310 小时
 楼主| 发表于 2017-3-26 20:50:33 | 显示全部楼层
whyviking 发表于 2017-3-26 20:33
实际上 类似Linux系统 这种回调函数的模式还是挺多的。 这么做的目的我认为主要还是把软件分层,做上层应 ...

或许真如你所说吧,而且ST这么大个公司主推HAL库想必也不会自砸招牌的,先忍着学下去,期待哪一天会有意想不到惊喜吧
回复

使用道具 举报

2

主题

171

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3792
金钱
3792
注册时间
2016-6-26
在线时间
276 小时
发表于 2017-3-27 08:27:53 | 显示全部楼层
确实比较麻烦。
回复

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12012
金钱
12012
注册时间
2013-9-10
在线时间
427 小时
发表于 2017-3-27 12:29:16 | 显示全部楼层
就没人想到串口的空闲中断么
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12012
金钱
12012
注册时间
2013-9-10
在线时间
427 小时
发表于 2017-3-27 12:30:32 | 显示全部楼层
whyviking 发表于 2017-3-26 20:12
而且原子的源码里  串口的处理是在回调函数中的另一个数组,在原子的源码里UART_Receive_IT()中的buffer实 ...

DMA结合串口空闲中断,我就是这么干的,不定长的数据通讯
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复

使用道具 举报

86

主题

567

帖子

0

精华

高级会员

Rank: 4

积分
825
金钱
825
注册时间
2014-9-30
在线时间
139 小时
发表于 2017-3-27 14:28:37 | 显示全部楼层
whyviking 发表于 2017-3-26 19:50
接收不用先确定接收几个字符啊,串口的中断是每接收1个字节中断一次,原子的源码是通过在中断回调函数中判 ...

每一个字节 都 判断一次,显然 CPU 开销 很大 。

这是 无奈之举 了,建议 楼主 用 超时机制 + DMA

可以传输 任意长度,才是 高效应用 HAL库的王道。
回复

使用道具 举报

37

主题

246

帖子

0

精华

高级会员

Rank: 4

积分
774
金钱
774
注册时间
2016-9-10
在线时间
310 小时
 楼主| 发表于 2017-3-28 15:32:59 | 显示全部楼层
八度空间 发表于 2017-3-27 12:30
DMA结合串口空闲中断,我就是这么干的,不定长的数据通讯

确实是个好办法
回复

使用道具 举报

37

主题

246

帖子

0

精华

高级会员

Rank: 4

积分
774
金钱
774
注册时间
2016-9-10
在线时间
310 小时
 楼主| 发表于 2017-3-28 15:35:28 | 显示全部楼层
caosix 发表于 2017-3-27 14:28
每一个字节 都 判断一次,显然 CPU 开销 很大 。

这是 无奈之举 了,建议 楼主 用 超时机制 + DMA

以前用的是超时判断,没有用DMA
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-19 08:46

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表