打印
[STM32F1]

模拟量计算遇到了奇怪的问题

[复制链接]
365|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jiajs|  楼主 | 2021-12-9 22:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
做的是定时器定时采样模拟量(50hz),然后进行均方根运算的程序。采样周期是312us,采样点是64点。
就是在一个周期内(0.02s)采集64个点,一共有5个通道。采集完5个通道后进入DMA中断,使用均方根公式进行运算。

使用特权

评论回复
沙发
llljh| | 2021-12-9 22:18 | 只看该作者

楼主程序可以公开吗?贴程序看下吧,这么说看不出什么原因

使用特权

评论回复
板凳
jiajs|  楼主 | 2021-12-9 22:20 | 只看该作者
下面是我的中断部分和均方根换算子程序:
//ADC_DMA中断服务程序
void DMA1_Channel1_IRQHandler(void)
{
        if(DMA_GetITStatus(DMA1_IT_TC1) != RESET)
        {               
                Get_Adc_Current();
        }
        DMA_ClearITPendingBit(DMA1_IT_TC1);
}
void Get_Adc_Current(void){
        u32 j;
        float temp,Rms,youxiao;
        float  temp1,Rms1,youxiao1;        
        float  temp2,Rms2,youxiao2;
        ADC_Cmd(ADC1, DISABLE);
        for(j=0;j<64;j++){               
                youxiao = ADC_SourceData[j][0]*(3.3/4095);//1.658
                temp=(youxiao-1.65)*(youxiao-1.65);
                Rms+=temp;
        }
        Rms=sqrt(Rms/64);
        voltage = Rms*216;        
        /*
        for(j=0;j<64;j++){               
                youxiao1 = ADC_SourceData[j][1]*(3.3/4095);//1.658
                temp1=(youxiao1-1.65)*(youxiao1-1.65);
                Rms1+=temp1;
        }
        Rms1=sqrt(Rms1/64);
        currentA = Rms1*2000;*/
               
        for(j=0;j<64;j++){               
                youxiao2 = ADC_SourceData[j][2]*(3.3/4095);//1.658
                temp2=(youxiao2-1.65)*(youxiao2-1.65);
                Rms2+=temp2;
        }
        Rms2=sqrt(Rms2/64);
        currentB =Rms2*2000;
         ADC_Cmd(ADC1, ENABLE);         
}

使用特权

评论回复
地板
jiajs|  楼主 | 2021-12-9 22:22 | 只看该作者
如果在Get_Adc_Current()程序中只进行1个ADC的换算,结果没有问题;如果把float改成double,那么2组换算的结果都没问题,但是只要进行2个以上的运算,后面的几个模拟量结果就不对。

使用特权

评论回复
5
jiajs|  楼主 | 2021-12-9 22:23 | 只看该作者
如果我把Get_Adc_Current()中声明的变量(如temp,Rms,youxiao等)放到函数外变成全局变量后,结果全是错的。

使用特权

评论回复
6
zhenykun| | 2021-12-9 22:25 | 只看该作者
这个 Get_Adc_Current()不能放在中断服务程序里,可以考虑在服务程序里设置一个标记,在主循环里进行处理

使用特权

评论回复
7
zhenykun| | 2021-12-9 22:26 | 只看该作者
否则因为计算的任务量大,造成很多延时,产生非预期的问题。

使用特权

评论回复
8
chuxh| | 2021-12-9 22:27 | 只看该作者
算法应该可以优化的,---比如把除法换成乘法什么的。

使用特权

评论回复
9
stly| | 2021-12-9 22:29 | 只看该作者
你也可以自己考虑一下,是不是真的有必要转换成电压然后再计算。

使用特权

评论回复
10
yinxiangh| | 2021-12-9 22:30 | 只看该作者
Get_Adc_Current()不能放在中断服务程序里,可以考虑在服务程序里设置一个标记,在主循环里进行处理

使用特权

评论回复
11
tian111| | 2021-12-9 22:31 | 只看该作者
放在中断服务程序里,太浪费时间了!

使用特权

评论回复
12
pengf| | 2021-12-9 22:31 | 只看该作者
for(j=0;j<64;j++){               
                youxiao = ADC_SourceData[j][0]*(3.3/4095);//1.658
                temp=(youxiao-1.65)*(youxiao-1.65);
                Rms+=temp;
        }
        Rms=sqrt(Rms/64);
        voltage = Rms*216;        
        /*
        for(j=0;j<64;j++){               
                youxiao1 = ADC_SourceData[j][1]*(3.3/4095);//1.658
                temp1=(youxiao1-1.65)*(youxiao1-1.65);
                Rms1+=temp1;
        }
        Rms1=sqrt(Rms1/64);
        currentA = Rms1*2000;*/
               
        for(j=0;j<64;j++){               
                youxiao2 = ADC_SourceData[j][2]*(3.3/4095);//1.658
                temp2=(youxiao2-1.65)*(youxiao2-1.65);
                Rms2+=temp2;
        }
        Rms2=sqrt(Rms2/64);
        currentB =Rms2*2000;

使用特权

评论回复
13
supernan| | 2021-12-9 22:32 | 只看该作者
这个计算 非常复杂的!

使用特权

评论回复
14
heweibig| | 2021-12-9 22:33 | 只看该作者
中断服务程序里边做这么复杂的运算干嘛

使用特权

评论回复
15
zhanghqi| | 2021-12-9 22:34 | 只看该作者
不要做什么乘除法 用左右移

使用特权

评论回复
16
jiajs|  楼主 | 2021-12-9 22:34 | 只看该作者

嗯,预料中的结果,多谢大家啦

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

940

主题

11975

帖子

6

粉丝