OpenEdv-开源电子网

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

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

[复制链接]

11

主题

63

帖子

0

精华

中级会员

Rank: 3Rank: 3

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

电路

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

最佳答案

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

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

使用道具 举报

13

主题

3498

帖子

1

精华

论坛元老

Rank: 8Rank: 8

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

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

使用道具 举报

11

主题

63

帖子

0

精华

中级会员

Rank: 3Rank: 3

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

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

使用道具 举报

11

主题

63

帖子

0

精华

中级会员

Rank: 3Rank: 3

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

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

使用道具 举报

13

主题

3498

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
9072
金钱
9072
注册时间
2020-5-11
在线时间
4718 小时
发表于 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

主题

63

帖子

0

精华

中级会员

Rank: 3Rank: 3

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

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

使用道具 举报

13

主题

3498

帖子

1

精华

论坛元老

Rank: 8Rank: 8

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

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

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

使用道具 举报

11

主题

63

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
413
金钱
413
注册时间
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

主题

3498

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
9072
金钱
9072
注册时间
2020-5-11
在线时间
4718 小时
发表于 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

主题

63

帖子

0

精华

中级会员

Rank: 3Rank: 3

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

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

使用道具 举报

11

主题

63

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
413
金钱
413
注册时间
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

主题

3498

帖子

1

精华

论坛元老

Rank: 8Rank: 8

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

使用道具 举报

11

主题

63

帖子

0

精华

中级会员

Rank: 3Rank: 3

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

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

使用道具 举报

13

主题

3498

帖子

1

精华

论坛元老

Rank: 8Rank: 8

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

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

使用道具 举报

11

主题

63

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
413
金钱
413
注册时间
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

主题

3498

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
9072
金钱
9072
注册时间
2020-5-11
在线时间
4718 小时
发表于 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

主题

63

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
413
金钱
413
注册时间
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

主题

3498

帖子

1

精华

论坛元老

Rank: 8Rank: 8

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

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

使用道具 举报

11

主题

63

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
413
金钱
413
注册时间
2024-8-27
在线时间
48 小时
 楼主| 发表于 2026-2-3 19:18:45 | 显示全部楼层

大佬,我按照你的方法用定时器(定时接收上一次的ADC采样数据)+ADC中断采样的方式,定时器定时300us,每个周期采样67次(约20ms的交流电周期),达到采样次数后停止采样,然后开始处理放在缓存数组中的采样数据,我的处理方法是:一一比较数组中的67个数据,大于0的就计算出该数据对应的瞬时电压值,再进行平方和(计录大于0有效数据的个数),开方求得有效值电压,再开启下一个周期的采样,电流和电压轮流采样(利用标志变量来改变采样通道,并用不同的缓存数组存放采样数据),现在的结果是样品在连续测试很多天的情况下采样电压都比较稳定,其它的显示问题都解决了,但是在重新做了两个样品后烧录同样的程序发现电压有偏低或不稳的现像,把原来正常的样品拆机后再通电测试发现电压也不稳定了(线路板部分没动),判断是不是还是采样程序有问题,是不是我的处理还有错误的地方?或者是要用过零检测后开始采样的方式才行(查资料得到的想法),但是这个只有正半周的波形应该怎么检测过零点呢?泣血请求大佬指点,脑袋都要裂开了
回复

使用道具 举报

13

主题

3498

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
9072
金钱
9072
注册时间
2020-5-11
在线时间
4718 小时
发表于 2026-2-4 10:34:30 | 显示全部楼层
KKGG 发表于 2026-2-3 19:18
大佬,我按照你的方法用定时器(定时接收上一次的ADC采样数据)+ADC中断采样的方式,定时器定时300us,每个 ...

由于你采样总时间正好是一个交流电周期,我觉得没必要检测过零。
电压偏低或不稳,那就需要你自己去排查了,
比如用示波器监测ADC引脚的电压是否准确、ADC数据发送出来看看每个采样点是否准确,检查算法中是否有溢出。
专治疑难杂症
回复

使用道具 举报

11

主题

63

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
413
金钱
413
注册时间
2024-8-27
在线时间
48 小时
 楼主| 发表于 2026-2-4 11:17:24 | 显示全部楼层
LcwSwust 发表于 2026-2-4 10:34
由于你采样总时间正好是一个交流电周期,我觉得没必要检测过零。
电压偏低或不稳,那就需要你自己去排查 ...

大佬,我用这种方法计算出来并在数码管显示的RMS有效值电压与用万用表测出的ADC采样电的电压不一样,相差有点多(比如万用表测到实际为0.96V,但程序计算并显示出来的为1.06),我的处理方式是统计所有的程序计算结果,再根据电路计算,用线性方程的方式计算出最终的输入电压。这种方式是否正确呢?是不是程序计算出来的ADC采样点RMS电压必须与万用表测试结果一样呢?是不是就是这个原因?
回复

使用道具 举报

13

主题

3498

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
9072
金钱
9072
注册时间
2020-5-11
在线时间
4718 小时
发表于 2026-2-4 11:59:29 | 显示全部楼层
KKGG 发表于 2026-2-4 11:17
大佬,我用这种方法计算出来并在数码管显示的RMS有效值电压与用万用表测出的ADC采样电的电压不一样,相差 ...

先要确定你的万用表是“真有效值”,而不是平均值乘系数得来的值。
傲游截图20260204115601.jpg
专治疑难杂症
回复

使用道具 举报

11

主题

63

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
413
金钱
413
注册时间
2024-8-27
在线时间
48 小时
 楼主| 发表于 2026-2-4 13:10:07 | 显示全部楼层
本帖最后由 KKGG 于 2026-2-4 13:14 编辑
LcwSwust 发表于 2026-2-4 11:59
先要确定你的万用表是“真有效值”,而不是平均值乘系数得来的值。

通过采用标准示波器检测到ADC采样点的Vrms=0.912V,万用表测得到的是0.899(考滤到测量误差应该是真有效值),而产品程序计算出来的数码管显示电压是0.98-1.00之间跳动,基本判断是程序计算出来的结果与实际RMS不一致,那么程序计算出来的结果必须要与实际示波器或万用表没得的RMS一致吗?用方程计算的方式校准可以吗?我以前的处理方式是不考滤与实际RMS的区别,而是直接用线性方程计算的得到最终输入电压值
回复

使用道具 举报

13

主题

3498

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
9072
金钱
9072
注册时间
2020-5-11
在线时间
4718 小时
发表于 2026-2-4 13:27:27 | 显示全部楼层
KKGG 发表于 2026-2-4 13:10
通过采用标准示波器检测到ADC采样点的Vrms=0.912V,万用表测得到的是0.899(考滤到测量误差应该是真有效值) ...

示波器本身也会有误差,比如有些示波器是8位ADC,探头可能不匹配。
万用表应该能更准确,最好是以万用表为准。
那就按你的想法去校准一下吧,比如不同的PCB板焊的电阻会有差异,供电电压或参考电压也可能有差异,
还是校准一下比较好。
专治疑难杂症
回复

使用道具 举报

11

主题

63

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
413
金钱
413
注册时间
2024-8-27
在线时间
48 小时
 楼主| 发表于 2026-2-4 13:43:21 | 显示全部楼层
本帖最后由 KKGG 于 2026-2-4 13:45 编辑
LcwSwust 发表于 2026-2-4 13:27
示波器本身也会有误差,比如有些示波器是8位ADC,探头可能不匹配。
万用表应该能更准确,最好是以万用表 ...

好的大佬,只要你教的采样方法是没问题的话,那应该就可以。另外问下,如果我用过零检测的方法,在这个项目中只有正半周的波形能检测到的情况下,我该怎么判断过零点?是用条件判 断大于0的ADC值产生时就判断过零点了吗?
回复

使用道具 举报

13

主题

3498

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
9072
金钱
9072
注册时间
2020-5-11
在线时间
4718 小时
发表于 2026-2-4 13:55:30 | 显示全部楼层
KKGG 发表于 2026-2-4 13:43
好的大佬,只要你教的采样方法是没问题的话,那应该就可以。另外问下,如果我用过零检测的方法,在这个项 ...

可以啊,不过考虑到可能有干扰、误触发,建议把判断的值调大些,如同示波器的触发电平。
缓存一定量的数据,判断达到触发条件后,再回头查找0的位置。
或者对多个数据进行判断,比如连续N个值大于0才认为是过零。
专治疑难杂症
回复

使用道具 举报

11

主题

63

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
413
金钱
413
注册时间
2024-8-27
在线时间
48 小时
 楼主| 发表于 2026-2-4 14:22:26 | 显示全部楼层
LcwSwust 发表于 2026-2-4 13:55
可以啊,不过考虑到可能有干扰、误触发,建议把判断的值调大些,如同示波器的触发电平。
缓存一定量的数 ...

好的,非常感谢大佬的耐心指点,请收下我的膝盖
回复

使用道具 举报

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

本版积分规则


关闭

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

正点原子公众号

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

GMT+8, 2026-2-22 05:56

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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