OpenEdv-开源电子网

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

关于51单片机交流检测的关题

[复制链接]

11

主题

58

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
401
金钱
401
注册时间
2024-8-27
在线时间
48 小时
发表于 2025-12-9 16:49:38 | 显示全部楼层 |阅读模式
1金钱

电路

电路
如题,有个项目需要用到单片机直接检测交流信号,按理说51单片机不是不能直接检测负电压吗,电路也没有使用电阻网络给偏置电压,是用软件算法来实现正常采样吗,有点想不通,麻烦哪位大佬能指点一下吗?谢谢

最佳答案

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

或许就只检测正半周,并假设负半周与正半周对称; 或许内部有上拉电阻。 建议示波器测一下波形看负半周有没有被削掉。
回复

使用道具 举报

13

主题

3489

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
9026
金钱
9026
注册时间
2020-5-11
在线时间
4617 小时
发表于 2025-12-9 16:49:39 | 显示全部楼层
本帖最后由 LcwSwust 于 2025-12-9 16:59 编辑

或许就只检测正半周,并假设负半周与正半周对称;
或许内部有上拉电阻。
建议示波器测一下波形看负半周有没有被削掉。
专治疑难杂症
回复

使用道具 举报

11

主题

58

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
401
金钱
401
注册时间
2024-8-27
在线时间
48 小时
 楼主| 发表于 2025-12-10 09:14:35 | 显示全部楼层
LcwSwust 发表于 2025-12-9 16:57
或许就只检测正半周,并假设负半周与正半周对称;
或许内部有上拉电阻。
建议示波器测一下波形看负半周有 ...

采样电阻上面的波形是交流正弦波,看来就像大佬说的,只能检测正半周的瞬时值,忽略掉负半周了,多谢大佬
回复

使用道具 举报

11

主题

58

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
401
金钱
401
注册时间
2024-8-27
在线时间
48 小时
 楼主| 发表于 2025-12-10 09:47:49 | 显示全部楼层
LcwSwust 发表于 2025-12-9 16:49
或许就只检测正半周,并假设负半周与正半周对称;
或许内部有上拉电阻。
建议示波器测一下波形看负半周有 ...

还有个问题,看了手册,这个芯片电源电压VDD的最小-0.3V,最高5.8V,看了波形,最低峰值电压已经到了-1.5V左右了,也没有坏,这是什么原因?是因为制造参数留有余地所以没有损坏吗?还有这种交流检测电路是否设计的有问题,不应该这样直接检测交流电而是应该先整流或偏置后再检测才是合乎规范的?
回复

使用道具 举报

13

主题

3489

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
9026
金钱
9026
注册时间
2020-5-11
在线时间
4617 小时
发表于 2025-12-10 10:19:49 | 显示全部楼层
KKGG 发表于 2025-12-10 09:47
还有个问题,看了手册,这个芯片电源电压VDD的最小-0.3V,最高5.8V,看了波形,最低峰值电压已经到了-1.5V ...

你得看IO口的输入电压范围,不是VDD的范围。一般单片机IO口会有两个钳位二极管,只要电流不要太大就不会坏,你看VOL不是串了10K电阻吗,可以测下这个电阻两端的电压差就知道电流有多大了。
专治疑难杂症
回复

使用道具 举报

11

主题

58

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
401
金钱
401
注册时间
2024-8-27
在线时间
48 小时
 楼主| 发表于 2025-12-12 14:23:11 | 显示全部楼层
LcwSwust 发表于 2025-12-10 10:19
你得看IO口的输入电压范围,不是VDD的范围。一般单片机IO口会有两个钳位二极管,只要电流不要太大就不会 ...

123 (2).png 大佬,我只检测正半周,采样100+个点,然后比较得到最大峰值,求出有效值的方法,最后计算出来的电压值大部分时候是正常的,但是总是周期性的出现电压下降后再马上又正常的现像,波动比较大,找了很久,也调整了定时器采样频率,都解不能解决,请大佬指点下,谢谢,或者有没有类假的例程?
回复

使用道具 举报

13

主题

3489

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
9026
金钱
9026
注册时间
2020-5-11
在线时间
4617 小时
发表于 2025-12-12 15:09:18 | 显示全部楼层
本帖最后由 LcwSwust 于 2025-12-12 15:11 编辑
KKGG 发表于 2025-12-12 14:23
大佬,我只检测正半周,采样100+个点,然后比较得到最大峰值,求出有效值的方法,最后计算出来的电压值 ...

两点建议:
1.数据点通过串口发送到电脑,找一个能绘制波形的软件,便于查看实时波形。 也可以结合示波器,看一下是实际电压有波动还是采样受干扰。
2.用峰值转换为有效值可能易受干扰,建议硬件滤波、软件滤波或采用“均方根”的方式计算有效值。

忘了问,你的采样率是多少?
专治疑难杂症
回复

使用道具 举报

11

主题

58

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
401
金钱
401
注册时间
2024-8-27
在线时间
48 小时
 楼主| 发表于 2025-12-12 16:04:41 | 显示全部楼层
本帖最后由 KKGG 于 2025-12-12 16:34 编辑
LcwSwust 发表于 2025-12-12 15:09
两点建议:
1.数据点通过串口发送到电脑,找一个能绘制波形的软件,便于查看实时波形。 也可以结合示波 ...

1:有用示波器测试过一段时间,波形比较稳定的正弦波,负半周被嵌位了一部分最低的波形,正常情况。
2:至于“均方根”方式计算也试过,用每个采集到的数据平方后累加,求平均值后再*1.414得到有效值,但是好像还是有波动很大,不知道是不是我计算方法不对?
3:采样率大概1.7K或以上都有试过(ADC时钟375K/(采样周期数200+固定的完整转换时间为18.5个Tadck))
回复

使用道具 举报

13

主题

3489

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
9026
金钱
9026
注册时间
2020-5-11
在线时间
4617 小时
发表于 2025-12-12 16:48:35 | 显示全部楼层
本帖最后由 LcwSwust 于 2025-12-12 16:51 编辑
KKGG 发表于 2025-12-12 16:04
1:有用示波器测试过一段时间,波形比较稳定的正弦波,负半周被嵌位了一部分最低的波形,正常情况。
2: ...

采样率应该可以,均方根要注意采样总时间得是周期的整数倍,如20ms、40ms,峰值计算那就大于一个周期(20ms)就行。
还是看数据波形吧,有些串口助手可以绘制数据波形,如SSCOM、STC-ISP。

专治疑难杂症
回复

使用道具 举报

11

主题

58

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
401
金钱
401
注册时间
2024-8-27
在线时间
48 小时
 楼主| 发表于 2025-12-13 11:22:23 | 显示全部楼层
LcwSwust 发表于 2025-12-12 16:48
采样率应该可以,均方根要注意采样总时间得是周期的整数倍,如20ms、40ms,峰值计算那就大于一个周期(20m ...

多谢大佬的指点,问题差不多解决了,我每次只采样一个周期就送去显示的话确实数据非常不稳定,我把采样多个周期的数据一起再比较出最大值送去显示处理的话,数据就比较正常稳定了,还有就是因为使用了定时器的关系,需要考滤到定时周期与采样的冲突问题
回复

使用道具 举报

11

主题

58

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
401
金钱
401
注册时间
2024-8-27
在线时间
48 小时
 楼主| 发表于 2025-12-18 15:44:18 | 显示全部楼层
LcwSwust 发表于 2025-12-12 16:48
采样率应该可以,均方根要注意采样总时间得是周期的整数倍,如20ms、40ms,峰值计算那就大于一个周期(20m ...

大佬,还是这个项目,请教一下,这个ADC采样交流电压或电流时,每个周期采样200个瞬时数据计算均方根值后,再把存储的10次均方根值进行均值滤波计算出来的电压值比较准确。这个函数比较费时费资源,周期要求也需要比较准确,需要放在20MS一次的定时器中断中执行才会比较稳定准确,并且实时性好,但这样就出现了一个问题,导致数码管闪烁的历害,如果放在主函数中执行,显示函数放定时中断执行的话数据就会不稳定,不准确,试过定时40MS,30MS都会有闪烁问题,减少采样次数又会出现数据不稳定,不准确,别的函数还好,占用资源小不影响显示,就这个采样函数次数多了影响,请问下大佬,现在种程序中碰到占用资源大,又要放定时器中执行的情况,应该怎么做才能让程序比较稳定?
回复

使用道具 举报

13

主题

3489

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
9026
金钱
9026
注册时间
2020-5-11
在线时间
4617 小时
发表于 2025-12-18 16:15:02 | 显示全部楼层
你要在一次定时中断里执行200个采样吗?那肯定不行,太过耗时。
建议:
1.若有DMA就用DMA。
2.若没有DMA,ADC若采用单次模式,就用一个1kHz(按你需要的采样率来)左右的定时器(若利用ADC转换完成中断)去采集,不要等待,先读数据、再启动,相当于本次是读取上次的结果。
3.ADC若有连续模式那就定时去读结果就好了。
4.费时的操作想办法放入主循环。
5.数码管的驱动放入定时器,以状态机处理。
专治疑难杂症
回复

使用道具 举报

11

主题

58

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
401
金钱
401
注册时间
2024-8-27
在线时间
48 小时
 楼主| 发表于 2025-12-18 19:55:10 | 显示全部楼层
LcwSwust 发表于 2025-12-18 16:15
你要在一次定时中断里执行200个采样吗?那肯定不行,太过耗时。
建议:
1.若有DMA就用DMA。

好的非常感谢大佬指点,那么如果是没有ADC中断功能,也没有DMA中断,只能通过轮询的方式读取ADC转换状态的话,应该用什么方法来避免轮询等待的情况呢?
回复

使用道具 举报

13

主题

3489

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
9026
金钱
9026
注册时间
2020-5-11
在线时间
4617 小时
发表于 2025-12-18 21:05:01 | 显示全部楼层
KKGG 发表于 2025-12-18 19:55
好的非常感谢大佬指点,那么如果是没有ADC中断功能,也没有DMA中断,只能通过轮询的方式读取ADC转换状态 ...

确保轮询间隔大于转换时间,定时读取然后开启下次转换就完了。
专治疑难杂症
回复

使用道具 举报

11

主题

58

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
401
金钱
401
注册时间
2024-8-27
在线时间
48 小时
 楼主| 发表于 2025-12-19 16:38:26 | 显示全部楼层
LcwSwust 发表于 2025-12-18 16:15
你要在一次定时中断里执行200个采样吗?那肯定不行,太过耗时。
建议:
1.若有DMA就用DMA。

大佬我现在是这样做的:
1:定时器定时156.25us开启一次ADC转换,每个周期采样128次
2:使用ADC中断的方式(ADC中断里面执行的程序有:每次中断读取一次ADC转换值,然后计算为ADC检测点电压值(FLOAT),然后累加平方和,累加到128次后求平均值,再求平方根得到均方根电压值,累加求和,达到10次后求平均,再求最终的电压有效值。(后面的求有效值及最终电压值的函数也有放在主函数执行过,效果不好)
3:显示函数(状态机)放在定时器中断里面执行,其他的按键检测(状态机),EEPROM参数读取/保存函数(也比较费时),状态刷新函数等都放在主函数里面执行。
4:测试后结果:ADC检测值不准,定时器定时太短,大量占用系统时间,别的函数执行不了,比如按键没有效果。也调整过中断优先级,都不行。
5:后来再次不断调整定时时间,比如再次改为20-30MS的定时,依量采用ADC中断方式+定时器中断显示,并且不断调整采样次数,但是检测到的ADC有效电压值都不行,要么不准确,要么不稳定,眼睛都快肿了,难搞,怎么做才能稳定
回复

使用道具 举报

13

主题

3489

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
9026
金钱
9026
注册时间
2020-5-11
在线时间
4617 小时
发表于 2025-12-19 16:57:34 | 显示全部楼层
本帖最后由 LcwSwust 于 2025-12-19 16:58 编辑
KKGG 发表于 2025-12-19 16:38
大佬我现在是这样做的:
1:定时器定时156.25us开启一次ADC转换,每个周期采样128次
2:使用ADC中断的 ...

ADC中断里就别用float运算了,过于耗时,建议优化算法:
比如你当前是a*1.2+b*1.2+c*1.2;
可以优化为(a+b+c)*1.2;或把float转换为整数运算如:(a+b+c)*12/10;
如果实在不知道怎么优化,那就ADC中断里把采样值存入buf[],主循环等采完一个周期再计算,
这样中断里总不会占用太多时间吧?

专治疑难杂症
回复

使用道具 举报

11

主题

58

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
401
金钱
401
注册时间
2024-8-27
在线时间
48 小时
 楼主| 发表于 2025-12-19 19:35:38 | 显示全部楼层
本帖最后由 KKGG 于 2025-12-20 08:49 编辑
LcwSwust 发表于 2025-12-19 16:57
ADC中断里就别用float运算了,过于耗时,建议优化算法:
比如你当前是a*1.2+b*1.2+c*1.2;
可以优化为( ...

1:大佬,我试了下定时器156.25us定时,这种情况下就算不开其它中断,只开定时器中断,显示程序放中断里面,主函数只放一个按键检测函数,测试了下,发现按键检测功能都被中断影响了,检测不到按下,只有把按键函数也放中断执行才能正常检测按键,但显示会闪烁(系统时钟为48M,ADC一般为系统时钟256分频),所以是否能基本上能确定,用这种短时间的定时触发ADC转换的方法行不通?因为通过实测能看出来,定时器定时太短(频率太高,严重占用系统资源),会导致除了中断里面的函数,主函数里面的程序根本无法正常运行?能否确定?还有没有别的方法能准确检测?2:另外请教下:我现在只采样一个周期里的正半周瞬时电压值,那么负半周期间ADC检测到的值应该是0吧,那么我采样时是不是要加一句条件判断?比如if(adc_val>0){temp=Get_AdcResult()};这样?因为我试过不加这句条件的话,最后求得的电压很低,加了这句后电压才会升高,是不是因为采样把负半周0这个值也采集了,导致最后结果被拉低了,所以每个周期正负半周所有采样点应该怎么处理(采样方法?)?
回复

使用道具 举报

13

主题

3489

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
9026
金钱
9026
注册时间
2020-5-11
在线时间
4617 小时
发表于 2025-12-19 21:58:51 | 显示全部楼层
KKGG 发表于 2025-12-19 19:35
好的大佬,我试下你说的方法,另外需要请教下:我现在只采样一个周期里的正半周瞬时电压值,那么负半周期 ...

自己考虑一下
专治疑难杂症
回复

使用道具 举报

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

本版积分规则


关闭

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

正点原子公众号

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

GMT+8, 2026-1-9 18:28

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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