三国小兵 发表于 2014-8-23 09:05:11

多次采样求平均

使用51内核的SOC单片机V9401,使用库函数读取电流有效值,送显示,有1%的跳差,想多次采样求平均,提高稳定度,现做想1秒读取一次,读3次然后做个平均,但是程序有点问题,显示不正常了,原来读取直接送显示,正常的while(1)
        {               
                CLRWDT();       
                ReadMeterPara(0x10d9); //秒平均电流有效值
                temp1=u32PMdatal;
                                                if(time_1s)
                                                {
                                                       time_1s=0;
                                                       ReadMeterPara(0x10d9);       
                                                       value_buf = u32PMdatal;
                                                       if(time_2s)
                                                       {
                                                               time_2s=0;
                                                                ReadMeterPara(0x10d9);
                                                                value_buf = u32PMdatal;
                                                                if(time_3s)
                                                                {
                                                                        time_3s=0;
                                                                        ReadMeterPara(0x10d9);
                                                                        value_buf = u32PMdatal;
                                                                        temp1=(value_buf+value_buf+value_buf)/3;
                                                                }
                                                       }
                                               }       
                        dislay_jisuan();
                if(Time_FLAG)
                {
                        Time_FLAG=0;                       
                  display();                                                                       
           }
        }                       
}


void Interrupt_Timer0 (void) interrupt 1 using 2
{

    TF0=0;
        Time_FLAG=1;
        TL0 =0x33;      //1ms
    TH0 =0xF3;
                coun++;
        if(coun==150)
        {
                coun=0;
                time_1s=1;
                if(coun==150)
                {
                        coun=0;
                        time_2s=1;
                        if(coun==150)
                        {
                                coun=0;
                                time_3s=1;
                        }
                }
        }
}

tam2907 发表于 2014-8-23 09:20:28

你是一个小兵。你这time_1s 2s 3s逻辑很是有问题。没你这样用有,如果time_1s是一秒,那么你数据temp1就是150*150秒更新一次。

三国小兵 发表于 2014-8-23 09:23:46

那应该如何操作呢,我想1秒读取一次秒平均

czg1411 发表于 2014-8-23 09:24:23

这个没2s 3s的事

三国小兵 发表于 2014-8-23 09:26:21

czg1411 发表于 2014-8-23 09:24
这个没2s 3s的事

间隔1秒读取一次的

三国小兵 发表于 2014-8-23 09:26:38

tam2907 发表于 2014-8-23 09:20
你是一个小兵。你这time_1s 2s 3s逻辑很是有问题。没你这样用有,如果time_1s是一秒,那么你数据temp1就是1 ...

那应该如何操作呢,我想间隔1秒读取一次秒平均

czg1411 发表于 2014-8-23 09:34:01

if(coun==150)
         {
               coun=0;   //0
               time_1s=1;
               if(coun==150)//前面已经等于0了。这里不可能等于150。下面也是一样
               {
                         coun=0;                                 
                         time_2s=1;
                         if(coun==150)   
                     {
                                 coun=0;
                                 time_3s=1;
                         }
               }
         }

tam2907 发表于 2014-8-23 09:35:36

加个变量 cnt
中断里 time_1s =1

主程序
if(time_1s)
{
time_1s=0;   ReadMeterPara(0x10d9);   value_buf = u32PMdatal;if(cnt>=2){cnt=0;temp1=(value_buf+value_buf+value_buf)/3; }
}

lcw_swust 发表于 2014-8-23 09:36:07

time_2s、time_3s那些都不要

if(time_1s)
{
time_1s=0;
ReadMeterPara(0x10d9);         
value_buf=value_buf;//FIFO
value_buf=value_buf;
value_buf = u32PMdatal;
temp1=(value_buf+value_buf+value_buf)/3;

maimaige 发表于 2014-8-23 09:38:27

中断里面的time_1s =1 ,后面的代码是不是永远不会执行,应该把coun=0去掉,然后300,然后450,这样

三国小兵 发表于 2014-8-23 09:44:28

好的啊,学习了呢,我修改下试试

三国小兵 发表于 2014-8-23 09:50:41

lcw_swust 发表于 2014-8-23 09:36
time_2s、time_3s那些都不要

if(time_1s)


学习了呢,我再修改下

三国小兵 发表于 2014-8-23 09:52:29

lcw_swust 发表于 2014-8-23 09:36
time_2s、time_3s那些都不要

if(time_1s)


因为秒平均,单片机是1秒更新一次,这样是不是相当于3秒才更新一次显示呢

三国小兵 发表于 2014-8-23 09:58:18

还有一个问题,这样相当于3秒更新一次显示,一开始上电也要读一次秒平均有效值ReadMeterPara(0x10d9);直接送显示,

三国小兵 发表于 2014-8-23 10:01:58

一开始上电也要读一次秒平均有效值ReadMeterPara(0x10d9);直接送显示,,,,,应该将第一次显示ReadMeterPara(0x10d9); //秒平均电流有效值               temp1=u32PMdatal;,               放在WHILE(){}循环的   之前吗,WHILE()循环放了读3次求平均,还有显示刷新这些      

三国小兵 发表于 2014-8-23 10:11:25

czg1411 发表于 2014-8-23 09:34
if(coun==150)
         {
               coun=0;   //0


一开始也要直接读取平均送显示一次,应该放在MAIN主函数里,还是应该放在WHILE循环里的呢

czg1411 发表于 2014-8-23 10:46:52

放MAIN主函数WHILE循环前。代码更简单。
和3次平均和放一起模块化做的更好。


三国小兵 发表于 2014-8-23 10:53:20

czg1411 发表于 2014-8-23 10:46
放MAIN主函数WHILE循环前。代码更简单。
和3次平均和放一起模块化做的更好。



好的啊,要是和3次平均和放一起,放在WHILE循环里,应该如何处理好呢,关键是就第一次上电显示一次,后面就用采样3次求平均的办法了呢

三国小兵 发表于 2014-8-23 10:55:33

lcw_swust 发表于 2014-8-23 09:36
time_2s、time_3s那些都不要

if(time_1s)


一开始上电也要直接读取采样值送显示一次,应该放在MAIN主函数里,还是应该放在WHILE循环里的呢,要是放在WHILE循环里,应该如何做呢,

czg1411 发表于 2014-8-23 10:55:42

//time_1s 初值等于1
if(time_1s)
{
        time_1s=0;   
        ReadMeterPara(0x10d9);   
        if(cnt==0)   //第一次
        {
                temp1=u32PMdatal;
                cnt=1;               
        }
        value_buf=u32PMdatal;
        if(cnt>=3)   //三次平均
        {
                temp1=(value_buf+value_buf+value_buf)/3;
                cnt=1;
        }
        else
        {
                cnt++;
        }
}

三国小兵 发表于 2014-8-23 10:56:00

tam2907 发表于 2014-8-23 09:35
加个变量 cnt
中断里 time_1s =1



一开始上电也要直接读取采样值送显示一次,应该放在MAIN主函数里,还是应该放在WHILE循环里的呢,要是放在WHILE循环里,应该如何做呢,

babysnail 发表于 2014-8-23 10:58:16

小白
51这种低端的,最好做优化,像3次这种不科学。最好是2的N次,如 2,4,8,16............

三国小兵 发表于 2014-8-23 10:58:30

czg1411 发表于 2014-8-23 10:55
//time_1s 初值等于1
if(time_1s)
{


好的啊,向您学习下,我C语言基础太差了,回去恶补下,多写写子程序

三国小兵 发表于 2014-8-23 11:00:55

babysnail 发表于 2014-8-23 10:58
小白
51这种低端的,最好做优化,像3次这种不科学。最好是2的N次,如 2,4,8,16............ ...

关键是3次的话,已经是3秒更新一次了,2N次,会不会,显示更新上延迟太久了呢

三国小兵 发表于 2014-8-23 11:01:48

babysnail 发表于 2014-8-23 10:58
小白
51这种低端的,最好做优化,像3次这种不科学。最好是2的N次,如 2,4,8,16............ ...

那我改成4次吧

babysnail 发表于 2014-8-23 11:08:11

三国小兵 发表于 2014-8-23 11:00
关键是3次的话,已经是3秒更新一次了,2N次,会不会,显示更新上延迟太久了呢 ...

举个特殊的例子吧, /256 ,就是把低字节直接去了,根本不用运算

lcw_swust 发表于 2014-8-23 11:11:46

三国小兵 发表于 2014-8-23 10:11
一开始也要直接读取平均送显示一次,应该放在MAIN主函数里,还是应该放在WHILE循环里的呢 ...

自己多想想,多试试。
上电时,可以把第一次读的数复制到整个数组的每个元素,这样取平均值就没影响了。

三国小兵 发表于 2014-8-23 11:13:15

lcw_swust 发表于 2014-8-23 11:11
自己多想想,多试试。
上电时,可以把第一次读的数复制到整个数组的每个元素,这样取平均值就没影响了。 ...

好的,自己再琢磨下

三国小兵 发表于 2014-8-23 11:13:51

babysnail 发表于 2014-8-23 11:08
举个特殊的例子吧, /256 ,就是把低字节直接去了,根本不用运算

好的啊

street 发表于 2014-8-23 11:18:25

没仔细看程序。不知道你的变量定义是多少位的?是否累加的时候溢出了?

三国小兵 发表于 2014-8-23 11:22:57

unsigned long 32位

三国小兵 发表于 2014-8-25 07:54:08

czg1411 发表于 2014-8-23 10:55
//time_1s 初值等于1
if(time_1s)
{


想再咨询下,要是建立一个数组,有5个元素,   第一的平均值为(a1);第二次平均(a1+a2)/2;。。第3次平均(a1+a2+a3)/3。。第4次平均(a1+a2+a3+a4)/4。。第5次平均为(a1+a2+a3+a4+a5)/5;这样应该如何操作好的呢,然后先进,后出,这样显示值应该更稳定,这样C语言应该如何表述好点呢

三国小兵 发表于 2014-8-25 07:54:25

lcw_swust 发表于 2014-8-23 11:11
自己多想想,多试试。
上电时,可以把第一次读的数复制到整个数组的每个元素,这样取平均值就没影响了。 ...

想再咨询下,要是建立一个数组,有5个元素,   第一的平均值为(a1);第二次平均(a1+a2)/2;。。第3次平均(a1+a2+a3)/3。。第4次平均(a1+a2+a3+a4)/4。。第5次平均为(a1+a2+a3+a4+a5)/5;这样应该如何操作好的呢,然后先进,后出,这样显示值应该更稳定,这样C语言应该如何表述好点呢

三国小兵 发表于 2014-8-25 07:54:41

babysnail 发表于 2014-8-23 10:58
小白
51这种低端的,最好做优化,像3次这种不科学。最好是2的N次,如 2,4,8,16............ ...

想再咨询下,要是建立一个数组,有5个元素,   第一的平均值为(a1);第二次平均(a1+a2)/2;。。第3次平均(a1+a2+a3)/3。。第4次平均(a1+a2+a3+a4)/4。。第5次平均为(a1+a2+a3+a4+a5)/5;这样应该如何操作好的呢,然后先进,后出,这样显示值应该更稳定,这样C语言应该如何表述好点呢

三国小兵 发表于 2014-8-25 07:59:17

babysnail 发表于 2014-8-23 11:08
举个特殊的例子吧, /256 ,就是把低字节直接去了,根本不用运算

想再咨询下,要是建立一个数组,有5个元素,   第一的平均值为(a1);第二次平均(a1+a2)/2;。。第3次平均(a1+a2+a3)/3。。第4次平均(a1+a2+a3+a4)/4。。第5次平均为(a1+a2+a3+a4+a5)/5;这样应该如何操作好的呢,然后先进,后出,这样显示值应该更稳定,这样C语言应该如何表述好点呢

三国小兵 发表于 2014-8-25 08:02:01

tam2907 发表于 2014-8-23 09:35
加个变量 cnt
中断里 time_1s =1



想再咨询下,要是建立一个数组,有5个元素,   第一的平均值为(a1);第二次平均(a1+a2)/2;。。第3次平均(a1+a2+a3)/3。。第4次平均(a1+a2+a3+a4)/4。。第5次平均为(a1+a2+a3+a4+a5)/5;这样应该如何操作好的呢,然后先进,后出,这样显示值应该更稳定,这样C语言应该如何表述好点呢
页: [1]
查看完整版本: 多次采样求平均