搜索
bottom↓
回复: 64

求助,交流采样的算法(不是请教,是求助)

[复制链接]

出0入0汤圆

发表于 2008-2-28 10:00:09 | 显示全部楼层 |阅读模式
求助,交流采样的算法(不是请教,是求助)

求交流采样的算法,我搞了快半年了,还是一点眉目都没有,开始我想用准同步算法的,可发现计算量太大,想用非同步算法,可是能求出一个周期的实际采样点,却不知道,在频率变化时怎么补尝,所以求非同步算法(硬件没有做过0检测).
我以前也发过帖子,可还是没能解决

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2008-2-28 11:04:43 | 显示全部楼层
楼主什么地方用的?信号频率变化大么?要求精度多高还要补偿? 我以前写过一个简单的12点傅式采样算法程序,默认频率不变的。

出0入0汤圆

发表于 2008-2-28 11:33:46 | 显示全部楼层
一个项目全部软硬件都是新的,硬件软件都不是熟悉的,成功率会很低,建议你别用AVR32,给你的建议你要仔细看看,就目前状态你应该选用一颗比较熟悉的MCU,采样、计量用ATT7022B,用第7路去做谐波,其他所有的数据项都直接使用7022B内部计算结果。

出0入0汤圆

发表于 2008-2-28 11:49:44 | 显示全部楼层
用均方根算法,如果要计算谐波用傅立叶如果要求准确用锁相环控制采样。MCP有一片文章讲过一种方法,也是一种同步采样的方法,但是我还没看的很懂。

出0入0汤圆

发表于 2008-2-28 11:55:14 | 显示全部楼层
不用那么麻烦,根据频率设定定时去读7022B的采样寄存器就行了,外部用模拟开关选择采集那一路信号。

出0入0汤圆

 楼主| 发表于 2008-2-28 12:42:46 | 显示全部楼层
在电力上,信号频率是45-55HZ,关键是的要求三相的3,5,7次谐波,电压有效值,有功功率,电量,频率,所以不能用计量芯片,

出0入0汤圆

发表于 2008-2-28 13:03:42 | 显示全部楼层
晕倒,你不知道有三相多功能的计量芯片,无语。

出0入0汤圆

 楼主| 发表于 2008-2-28 13:13:19 | 显示全部楼层
不是,我刚才字打错了,我知道,我还用过CS5463,我是说求三相的3,5,7次谐波,还有每次谐波的电压畸变率所以不能用计量芯片

出0入0汤圆

发表于 2008-2-28 14:15:40 | 显示全部楼层
CS5463,ATT7022都可以输出采样值,根据频率选取整周期采样点去计算就行了

出0入0汤圆

 楼主| 发表于 2008-2-29 09:07:51 | 显示全部楼层
顶一下

出0入0汤圆

发表于 2008-4-1 11:50:58 | 显示全部楼层
请问一下tidsp,ATT7022B如何访问采样寄存器,我看资料上面没有提供三相电压、电流采样寄存器的入口地址

出0入0汤圆

发表于 2008-4-1 12:16:38 | 显示全部楼层
第7路可以访问

出0入0汤圆

发表于 2008-4-1 12:30:51 | 显示全部楼层
哦,是的,那就是说需要采用第7路AD对三相电压、电流进行分时采样咯!
不知道有没有什么后门能够提供另外六路AD的采样值寄存器的访问入口啊,呵呵
非常感谢!

出0入0汤圆

发表于 2008-4-1 12:35:10 | 显示全部楼层
只有ACTION的才知道有无后门

出0入0汤圆

发表于 2008-4-1 12:37:28 | 显示全部楼层
呵呵,那是,谢谢

出0入0汤圆

 楼主| 发表于 2008-4-10 17:50:38 | 显示全部楼层
那么请问,用第7路去采样(采样频率是3.2K)的话,是否是第7路能直接输出瞬时值,那么在50HZ的情况下就是一个周期采样64个点,而ATT7022B又没有缓存,那么就是说,MCU和计量新片之间要通过SPI总线要有两种速度进行通信,比如1秒钟读一次前六路的值,而读第7路则要0.0003125S(是采样频率3.2K的倒数)读一次,而且读的时间要很准,否则数据就会出错?

出0入0汤圆

发表于 2008-4-10 18:42:13 | 显示全部楼层
是要读的很准时,一定要用硬件SPI去读,最好使用有FIFO的,读回来算也是个麻烦事情,频率改变一点,只要不是50,算谐波就要用一定的算法了,直接FFT结果一塌糊涂。

出0入46汤圆

发表于 2008-4-10 19:51:49 | 显示全部楼层
关注!

出0入0汤圆

发表于 2008-4-11 02:25:26 | 显示全部楼层
跟踪中

出0入0汤圆

 楼主| 发表于 2008-4-11 08:43:02 | 显示全部楼层
关键是计量新片没有缓存,就算是用中断的方式,比如在要读第7路的时候,同时要读前6路的参数了,那读出的第7路的数据就可能错过一位,那你做FFT就会有问题,另你把读出的数据加窗了没?

出0入0汤圆

发表于 2008-4-11 09:09:35 | 显示全部楼层
7022没中断,只能以更高的速度去读,读回来丢弃重复的,想同时读6路不现实,丢数据或频率不是50加窗起不了多大作用,用迭代法吧。

出0入0汤圆

发表于 2008-4-11 09:29:59 | 显示全部楼层
记号!

出0入0汤圆

发表于 2008-4-11 09:42:40 | 显示全部楼层
还真没搞过三相的.....

出0入0汤圆

 楼主| 发表于 2008-4-11 18:55:21 | 显示全部楼层
丢数据你怎么处理?频率不是50到不难办,读6路的AD转换值,如果一秒钟出一次数据,我认为那可能还来得急,比如每一路读5个周期,那么6路在30个周期左右是能读完的.

tidsp你是哪里的?是做电力的吗?我是南京的,你呢?能留个联系方式吗?我的QQ:824879061

出0入0汤圆

发表于 2008-4-11 19:51:40 | 显示全部楼层
看看这个PIC的,MAX197采样根据频率调节采样时间(转)

/* ***********************************************************************
** 系统程序:多路信号实时采集和处理,并将处理后的数据以不同的
**                                         方式显示.同时可根据按键输入实现任务调度.
** 时    间:2005/08/05.
*************************************************************************** */
#include "pic18f458.h"                                                                                                                //PIC18F458单片机头文件.
#include "math.h"                                                                                                                        //C语言头文件.
#include "stdlib.h"                                                                                                                //C语言头文件.

#define PI 6.283

//"HELP界面"
const char HELP[3][64]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
                                                                                        0xFF,0xFF,0xFF,0xFF,0x83,0x7D,0x5D,0x9B,0xFF,0x81,0x7F,0x7F,0x81,0xFF,0x7D,0x01,
                                                                                        0x7D,0xFF,0x7D,0x01,0x7D,0x7D,0x83,0xFF,0x01,0x6D,0x6D,0x6D,0xFF,0xFF,0xFF,0xFF,
                                                                                        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
                                                                                        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x83,0x7D,0x7D,0x83,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
                                                                                        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7B,0x01,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
                                                                                        0xFF,0xFF,0xFF,0xFF,0xFF,0x3B,0x5D,0x6D,0x73,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
                                                                                        0xFF,0xFF,0xFF,0xFF,0xFF,0xBB,0x6D,0x6D,0x93,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
                                                                                        0xFF,0xFF,0xFF,0xE7,0xC3,0x81,0xE7,0xE7,0xE7,0xE7,0xE7,0xE7,0xFF,0xFF,0xFF,0xFF,
                                                                                        0xFF,0xFF,0xFF,0xFF,0xE7,0xE7,0xE7,0xE7,0xE7,0xE7,0x81,0xC3,0xE7,0xFF,0xFF,0xFF,
                                                                                        0xFF,0xFF,0xFF,0xFF,0x81,0xBD,0xBD,0x81,0xFF,0x81,0xEF,0xD7,0xBB,0xFF,0xFF,0xFF,
                                                                                        0xFF,0xFF,0xFF,0xFF,0x81,0xEF,0xEF,0x81,0xFF,0x81,0xBF,0xBF,0xBF,0xFF,0xFF,0xFF,};
//        "A相 B相        C相        三相 HELP"
const char ABC[20][8]={0x00,0x3E,0x41,0x41,0x22,0x00,0x7F,0x08,0x08,0x7F,0x00,0x7F,0x41,0x41,0x7F,0x00,
                                                                                        0x7F,0x41,0x41,0x7F,0x00,0x26,0x49,0x49,0x32,0x00,0x7F,0x49,0x49,0x49,0x00,0x00,
                                                                                        0x00,0x40,0x7C,0x13,0x13,0x7C,0x40,0x14,0x0C,0x7F,0x14,0x04,0x7F,0x55,0x55,0x7F,
                                                                                        0x00,0x41,0x7F,0x49,0x49,0x36,0x00,0x14,0x0C,0x7F,0x14,0x04,0x7F,0x55,0x55,0x7F,
                                                                                        0x00,0x3E,0x41,0x41,0x41,0x22,0x00,0x14,0x0C,0x7F,0x14,0x04,0x7F,0x55,0x55,0x7F,
                                                                                        0x00,0x20,0x2A,0x2A,0x2A,0x2A,0x20,0x14,0x0C,0x7F,0x14,0x04,0x7F,0x55,0x55,0x7F,
                                                                                        0x26,0x49,0x49,0x32,0x00,0x7F,0x49,0x49,0x49,0x00,0x01,0x01,0x7F,0x01,0x01,0x00,
                                                                                        0x00,0x7F,0x08,0x08,0x7F,0x00,0x7F,0x49,0x49,0x49,0x00,0x41,0x7F,0x41,0x00,0x00,
                                                                                        0x00,0x01,0x47,0x48,0x28,0x1F,0x00,0x7F,0x49,0x49,0x49,0x00,0x26,0x49,0x49,0x32,
                                                                                        0x7F,0x08,0x08,0x7F,0x00,0x7F,0x49,0x49,0x00,0x7F,0x40,0x40,0x41,0x7F,0x51,0X0E,};
//"U1 U2 U3"
const char UB[3][8]={0x3F,0x40,0x40,0x3F,0x00,0x42,0x7F,0x40,0x3F,0x40,0x40,0x3F,0x62,0x51,0x49,0x46,
                                                                         0x3F,0x40,0x40,0x3F,0x22,0x49,0x49,0x36,};
//"I1 I2 I3"
const char IB[3][8]={0x41,0x7F,0x41,0x00,0x42,0x7F,0x40,0x00,0x41,0x7F,0x41,0x62,0x51,0x49,0x46,0x00,
                                                                          0x41,0x7F,0x41,0x22,0x49,0x49,0x36,0x00,};
//"P1 P2 P3"
const char PB[3][8]={0x41,0x7F,0x49,0x06,0x00,0x42,0x7F,0x40,0x41,0x7F,0x49,0x06,0x62,0x51,0x49,0x46,
                                                                                0x41,0x7F,0x49,0x06,0x22,0x49,0x49,0x36,};
//"Q1 Q2 Q3"
const char QB[3][8]={0x3E,0x51,0x61,0x3E,0x00,0x42,0x7F,0x40,0x3E,0x51,0x61,0x3E,0x62,0x51,0x49,0x46,
                                                                                0x3E,0x51,0x61,0x3E,0x22,0x49,0x49,0x36,};
//"S1 S2 S3"
const char SB[3][8]={0x26,0x49,0x49,0x32,0x00,0x42,0x7F,0x40,0x26,0x49,0x49,0x32,0x62,0x51,0x49,0x46,
                                                                                0x26,0x49,0x49,0x32,0x22,0x49,0x49,0x36,};
//        "φ1 φ2 φ3"
const char LB[3][8]={0x3E,0x49,0x49,0x3E,0x00,0x42,0x7F,0x40,0x3E,0x49,0x49,0x3E,0x62,0x51,0x49,0x46,
                                                                                0x3E,0x49,0x49,0x3E,0x22,0x49,0x49,0x36,};
//        "φ1 φ2 φ3"
const char FB[3][8]={0x7F,0x09,0x09,0x00,0x42,0x7F,0x40,0x00,0x7F,0x09,0x09,0x62,0x51,0x49,0x46,0x00,
                                                                                0x7F,0x09,0x09,0x22,0x49,0x49,0x36,0x00,};

//"+ - % "
const char JS[8]={0x00,0x00,0x08,0x08,0x3E,0x08,0x08,0x00,};
const char JC[8]={0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00,};
const char JJ[8]={0x00,0x00,0x00,0x44,0x44,0x5F,0x44,0x44,};
const char BH[8]={0x00,0x40,0x26,0x16,0x68,0x64,0x02,0x00,};
//"0 1 2 3 4 5 6 7 8 9 0. 1. 2. 3. 4. 5. 6. 7. 8. 9."
const char NUM[20][8]={0x00,0x00,0x00,0x3E,0x41,0x41,0x3E,0x00,0x00,0x00,0x00,0x00,0x42,0x7F,0x40,0x00,
                                                                                        0x00,0x00,0x00,0x62,0x51,0x49,0x46,0x00,0x00,0x00,0x00,0x22,0x49,0x49,0x36,0x00,
                                                                                        0x00,0x00,0x18,0x14,0x13,0x7F,0x10,0x00,0x00,0x00,0x00,0x37,0x45,0x45,0x39,0x00,
                                                                                        0x00,0x00,0x00,0x3E,0x49,0x49,0x32,0x00,0x00,0x00,0x00,0x01,0x79,0x05,0x03,0x00,
                                                                                        0x00,0x00,0x00,0x36,0x49,0x49,0x36,0x00,0x00,0x00,0x00,0x26,0x49,0x49,0x3E,0x00,
                                                                                        0x00,0x00,0x3E,0x41,0x41,0x3E,0x00,0x40,0x00,0x00,0x00,0x42,0x7F,0x40,0x00,0x40,
                                                                                        0x00,0x00,0x62,0x51,0x49,0x46,0x00,0x40,0x00,0x00,0x22,0x49,0x49,0x36,0x00,0x40,
                                                                                        0x00,0x00,0x18,0x14,0x13,0x7F,0x10,0x40,0x00,0x00,0x37,0x45,0x45,0x39,0x00,0x40,
                                                                                        0x00,0x00,0x3E,0x49,0x49,0x32,0x00,0x40,0x00,0x00,0x01,0x79,0x05,0x03,0x00,0x40,
                                                                                        0x00,0x00,0x36,0x49,0x49,0x36,0x00,0x40,0x00,0x00,0x26,0x49,0x49,0x3E,0x00,0x40,};

signed int DATA[6][64];                                                                                                                                                //AD采样数据存储区.
int FT[20];                                                                                                                                                                                          //频率采样数据存储区.
//U I P Q S F计算数据存储区.
long UI[2][6],UP[2][6],P[3],Q[3],S[3],L[3],F;
//MAX197基控制字,采样模式标志,频率采样计数,采样频率调整参数.
int ADCAN=0X48,ADMO=1,CCP=0,AD=50,CHX=1;
//MAX197控制字,PORTA状态暂存字,PORTB状态暂存字,AD采样计数,按键状态暂存字,AD采样通道标志位.
int ADWORDS,ATRL,BTRL,ADD,KEY,CHAN;
//按键功能标志位.
int MAXD,MAXA,BACK,NEXT,SURE,GUID;

/* ************************************************************************
** 函 数 名:void INITIAL()
** 功能描述:系统初始子程序.
*************************************************************************** */
void INITIAL()
{
        INTCON=0X00;                                                                                                                                        //<0000,0000>关总中断.
        ADCON1=0X07;                                                                                                                                        //<0111,0000>设置数字量输入/输出口.
        PIE1=0X00;                                                                                                                                                //<0000,0000>关外围中断1.
        PIE2=0X00;                                                                                                                                                //<0000,0000>关外围中断2.
        PIE3=0X00;                                                                                                                                                //<0000,0000>关外围中断3.
        CMCON=0X07;                                                                                                                                                //<0000,0111>关比较器.
        TRISA=TRISA&0XF0;                                                                                                                        //<uuuu,0000>设置PORTA<3:0>为输出.
        TRISB=TRISB&0X0F;                                                                                                                        //<0000,uuuu>设置PORTB<7:4>为输出.
}

/* *************************************************************************
** 函 数 名:void DEALY(long TIME)
** 功能描述:根据TIME给定延时.
**************************************************************************** */
void DELAY(long TIME)
{
        long T;                                                                                                                                                                //计数参数.
        for(T=0;T<TIME;T++)                                                                                                                //延时.
                ;                                                                                                                                                                                //空语句.
}

/* ************************************************************************
** 函 数 名:void T3INIT()
** 功能描述:TMR3作为定时器,定时10us,产生系统时钟点滴.
*************************************************************************** */
void T3INIT()
{
        T3CON=0X20;                                                                                                                                        //<1010,0000>设定TMR3工作于8位定时器方式,使用内部时钟.
        TMR3IE=1;                                                                                                                                                //TMR3中断允许.
        TMR3IF=0;                                                                                                                                                //清除TMR3中断标志位.
        TMR3IP=0;                                                                                                                                                //置TMR3为断为低优先级.
        IPEN=1;                                                                                                                                                        //使能中断优先级.
        TMR3L=0X9A;                                                                                                                                        //<1111,0101>Focs/4=1us,Focs/4*定时10u
}
/* ************************************************************************
** 函 数 名:void CCPINIT()
** 功能描述:对CCP1初始化,以捕捉方式工作.
*************************************************************************** */
void CCPINIT()
{
    TRISC2=1;                                                                                                                                        //RC2为输入.
    T1CON=0XA1;                                                                                                                    //TMR1作为了16位定时器.
    PEIE=1;                                                                                                                                                //打开外围中断.
    CCP1IE=1;                                                                                                                                        //CCP1中使能.
    CCP1CON=0X05;                                                                                                                        //CCP1工作在捕捉方式.
}

/* ************************************************************************
** 函 数 名:int KEYIN()
** 功能描述:按键扫描子程序,并返回键值.
*************************************************************************** */
int KEYIN()
{
        int WORDS;                                                                                                                                        //定义数据入口变量.
        TRISD=0XFF;                                                                                                                                        //<1111,1111>设置PORTD为输入.
        PORTA=(PORTA|0X0D)&0XFD;                                                                                //<uuuu,1101>译码后实现地址选择.
        WORDS=PORTD;                                                                                                                                //读取PORTD端口的数据.
        WORDS=PORTD|WORDS;                                                                                                        //按键抖动处理.
        PORTA=PORTA&0XF0;                                                                                                                //屏蔽所有地址.
        return WORDS;                                                                                                                                //将读取的数据作为返回值.
}

/* ************************************************************************
** 函 数 名:int GATEAIN()
** 功能描述:读取A组开关量,并返回其值.
*************************************************************************** */
int GATEAIN()
{
        int WORDS;                                                                                                                                        //定义数据入口变量.
        TRISD=0XFF;                                                                                                                                        //<1111,1111>设置PORTD为输入.
        PORTA=(PORTA|0X0B)&0XFB;                                                                                //<uuuu,1011>译码后实现地址选择.
        WORDS=PORTD;                                                                                                                                //读取PORTD端口的数据.
        PORTA=PORTA&0XF0;                                                                                                                //屏蔽所有地址.
        return WORDS;                                                                                                                                //将读取的数据作为返回值.
}

/* ************************************************************************
** 函 数 名:int GATEBIN()
** 功能描述:读取B组开关量,并返回其值.
*************************************************************************** */
int GATEBIN()
{
        int WORDS;                                                                                                                                        //定义数据入口变量.
        TRISD=0XFF;                                                                                                                                        //<1111,1111>设置PORTD为输入.
        PORTA=(PORTA|0X0C)&0XFC;                                                                                //<uuuu,1100>译码后实现地址选择.
        WORDS=PORTD;                                                                                                                                //读取PORTD端口的数据.
        PORTA=PORTA&0XF0;                                                                                                                //屏蔽所有地址.
        return WORDS;                                                                                                                                //将读取的数据作为返回值.
}

/* ************************************************************************
** 函 数 名:void LEDOUT(int WOEDS)
** 功能描述:将数据WORDS输出,并由8个LED显示.
*************************************************************************** */
void LEDOUT(int WORDS)
{
        TRISD=0X00;                                                                                                                                        //<0000,0000>设置PORTD为输出.
        PORTA=(PORTA|0X08)&0XF8;                                                                                //<uuuu,1000>译码后实现地址选择.
        PORTD=WORDS;                                                                                                                                //将数据赋给PORTD端口.
        PORTA=PORTA&0XF0;                                                                                                                //屏蔽所有地址.
}

/* ************************************************************************
** 函 数 名:void LCDSTA(int E)
** 功能描述:查询LCD显示器第E片的状态.
*************************************************************************** */
void LCDSTA(int E)
{
        int STA;                                                                                                                                                //定义数据入口参数.
        TRISD=0XFF;                                                                                                                                        //<1111,1111>设置PORTD为输入.
        while(1)                                                                                                                                                //循环,查询.
        {
                if(E==1)                                                                                                                                        //选择第E片LCD.
                        PORTA=(PORTA|0X09)&0XF9;                                                                //<uuuu,1001>译码后选择第1片LCD.
                else
                        PORTA=(PORTA|0X0A)&0XFA;                                                                //<uuuu,1010>译码后选择第2片LCD.
                PORTB=(PORTB|0X60)&0XEF;                                                                        //<u110,uuuu>控制信号:可读-读-命令.
                STA=PORTD&0X80;                                                                                                                //读取LCD的状态字Bt7=0/1.
                PORTB=PORTB&0X8F;                                                                                                        //<u000,uuuu>控制信号:锁存数据.
                if(STA==0X0000)                                                                                                                //判断LCD状态是不为空闲.
                        break;                                                                                                                                        //是,跳出查询.
        }
}

/* ************************************************************************
** 函 数 名:void LCDTRA(int TRANS,int E)
** 功能描述:向第E片LCD输入显示地址(TRANS)或命令(TRANS).
*************************************************************************** */
void LCDTRA(int TRANS,int E)
{
        TRISD=0X00;                                                                                                                                        //<0000,0000>设置PORTD为输出.
        if(E==1)                                                                                                                                                //选择第E片LCD.
                PORTA=(PORTA|0X09)&0XF9;                                                                        //<uuuu,1001>译码后选择第1片LCD.
        else
                PORTA=(PORTA|0X0A)&0XFA;                                                                        //<uuuu,1010>译码后选择第2片LCD.
        PORTD=TRANS;                                                                                                                                //将数据赋给PORTD端口.
        PORTB=(PORTB|0X40)&0XCF;                                                                                //<u100,uuuu>控制信号:可读-写-命令.
        PORTB=PORTB&0X8F;                                                                                                                //<u000,uuuu>控制信号:锁存数据.
}

/* ************************************************************************
** 函 数 名:void LCDOUT(char WORDS,int CLMD,int PAGE,int E)
** 功能描述:数据WORDS由PORTD输出,并在第E片LCD的第CLMD列,第PAGE页显示.
*************************************************************************** */
void LCDOUT(int WORDS,int CLMD,int PAGE,int E)
{
        LCDTRA(CLMD,E);                                                                                                                        //设置列地址.
        LCDTRA(PAGE,E);                                                                                                                        //设置页地址.
        TRISD=0X00;                                                                                                                                        //<0000,0000>设置PORTD为输出.
        if(E==1)                                                                                                                                                //选择第E片LCD.
                PORTA=(PORTA|0X09)&0XF9;                                                                        //<uuuu,1001>译码后选择第1片LCD.
        else
                PORTA=(PORTA|0X0A)&0XFA;                                                                        //<uuuu,1010>译码后选择第2片LCD.
        PORTD=WORDS;                                                                                                                                //将数据赋给PORTD端口.
        DELAY(0);
        PORTB=(PORTB|0X50)&0XDF;                                                                                //<u101,uuuu>控制信号:可读-写-命令.
        PORTB=PORTB&0X8F;                                                                                                                //<u000,uuuu>控制信号:锁存数据.
}
/* ************************************************************************
** 函 数 名:int LCDIN(int CLMD,int PAGE,int E)
** 功能描述:读取第E片LCD的第CLMD列,第PAGE页的数据.
*************************************************************************** */
int LCDIN(int CLMD,int PAGE,int E)
{
        int WORDS;                                                                                                                                        //定义数据入口参数.
        LCDTRA(CLMD,E);                                                                                                                        //设置列地址.
        LCDTRA(PAGE,E);                                                                                                                        //设置页地址.
        TRISD=0XFF;                                                                                                                                        //<1111,1111>设置PORTD为输入.
        if(E==1)                                                                                                                                                //选择第E片LCD.
                PORTA=(PORTA|0X09)&0XF9;                                                                        //<uuuu,1001>译码后选择第1片LCD.
        else
                PORTA=(PORTA|0X0A)&0XFA;                                                                        //<uuuu,1010>译码后选择第2片LCD.
        PORTB=PORTB|0X70;                                                                                                                //<u111,uuuu>控制信号:可读-读-数据.
        WORDS=PORTD;                                                                                                                                //空读操作.
        WORDS=PORTD;                                                                                                                                //读取PORTD端口数据.
        PORTB=PORTB&0X8F;                                                                                                                //<u000,uuuu>控制信号:锁存数据.
        return WORDS;                                                                                                                                //将读取的数据作为返回值.
}

/* ************************************************************************
** 函 数 名:void LCDON(int E)
** 功能描述:打开显示,并检查液晶显示器是否被打开.
*************************************************************************** */
void LCDON(int E)
{
        int STA;                                                                                                                                                //定义数据入口参数.
        TRISD=0XFF;                                                                                                                                        //<1111,1111>设置PORTD为输入.
        while(1)                                                                                                                                                //循环,查询.
        {
                LCDTRA(0X3F,E);                                                                                                                //打开LCD显示器.
                LCDSTA(E);                                                                                                                                //查询LCD的状态.
                if(E==1)                                                                                                                                        //选择第E片LCD.
                        PORTA=(PORTA|0X09)&0XF9;                                                                //<uuuu,1001>译码后选择第1片LCD.
                else
                        PORTA=(PORTA|0X0A)&0XFA;                                                                //<uuuu,1010>译码后选择第2片LCD.
                PORTB=(PORTB|0X60)&0XEF;                                                                        //<u110,uuuu>控制信号:可读-读-命令.
                STA=PORTD&0X20;                                                                                                                //将数据赋给PORTD端口.
                PORTB=PORTB&0X8F;                                                                                                        //<u000,uuuu>控制信号:锁存数据.
                if(STA==0X00)                                                                                                                        //LCD显示器是否被打开.
                        break;                                                                                                                                        //打开,跳出循环.
        }
}

/* ************************************************************************
** 函 数 名: void LCDOFF(int E)
** 功能描述:关闭显示,并检查液晶显示器是否被关闭.
*************************************************************************** */
void LCDOFF(int E)
{
        int STA;                                                                                                                                                //定义数据入口参数.
        TRISD=0XFF;                                                                                                                                        //<1111,1111>设置PORTD为输入.
        while(1)                                                                                                                                                //循环,查询.
        {
                LCDTRA(0X3E,E);                                                                                                                //关闭LCD显示器.
                LCDSTA(E);                                                                                                                                //查询LCD的状态.
                if(E==1)                                                                                                                                        //选择第E片LCD.
                        PORTA=(PORTA|0X09)&0XF9;                                                                //<uuuu,1001>译码后选择第1片LCD.
                else
                        PORTA=(PORTA|0X0A)&0XFA;                                                                //<uuuu,1010>译码后选择第2片LCD.
                PORTB=(PORTB|0X60)&0XEF;                                                                        //<u110,uuuu>控制信号:可读-读-命令.
                STA=PORTD&0X20;                                                                                                                //将数据赋给PORTD端口.
                PORTB=PORTB&0XBF;                                                                                                        //<u000,uuuu>控制信号:锁存数据.
                if(STA==0X20)                                                                                                                        //LCD显示器是否被关闭.
                        break;                                                                                                                                        //关闭,跳出循环.
        }
}

/* ************************************************************************
** 函 数 名:void LCDCLEAR(int E)
** 功能描述:将液晶显示器清屏.
*************************************************************************** */
void LCDCLEAR(int E)
{
        int PAGE,NUM,CLMD;                                                                                                                //页地址-增量-列地址.
        for(NUM=0X08,PAGE=0XB8;NUM>0;NUM--,PAGE++)                //页基地址0X80循环累加1.
        {
                for(CLMD=0X40;CLMD<=0X7F;CLMD++)                                                //列基地址0X40循环累加1.
                {
                        LCDOUT(0X00,CLMD,PAGE,E);                                                                        //向当前地址输入0X00,清屏.
                }
        }
}

/* ************************************************************************
** 函 数 名:void LCDCLEARA(int CLMD,int PAGE,int CLMDN,int PAGEN,int E)
** 功能描述:选择性清屏,起始列(CLMD)起始页(PAGE)几列(CLMDN)几页(PAGEN).
*************************************************************************** */
LCDCLEAN(int CLMD,int PAGE,int CLMDN,int PAGEN)
{
        int C,P,CADD;
                                                                                                                                                                                                //计算实际的初始页地址.
        for(P=PAGE+0XB8;PAGEN>0;PAGEN--,P++)                                        //页基地址0X80循环累加1.
        {
                CADD=CLMDN;                                                                                                                                        //计算实际的初始列地址.
                for(C=CLMD+0x40        ;CADD>0;CADD--,C++)                                        //列基地址0X40循环累加1.
                {
                        if(C>0X7F)                                                                                                                                //列地址判断.
                                LCDOUT(0X00,C-64,P,2);                                                                        //向当前地址输入0X00,清屏.
                        else
                                LCDOUT(0X00,C,P,1);                                                                                        //向当前地址输入0X00,清屏.
                }
        }
}
/* ************************************************************************
** 函 数 名:LCDINITI(int E)
** 功能描述:LCD初始化程序
*************************************************************************** */
void LCDINITI(int E)
{
        LCDOFF(E);                                                                                                                                        //关闭LCD.
        LCDCLEAR(E);                                                                                                                                //清屏.
        LCDON(E);                                                                                                                                                //打开LCD.
}

/* ************************************************************************
** 函 数 名:void LCDCH(char *WORDS,int CLMD,int PAGE)
** 功能描述:向LCD输入汉字点阵(*WORDS)16*16,并以CLMD为初始列,PAGE为初始页.
*************************************************************************** */
void LCDCH(const char *WORDS,int CLMD,int PAGE)
{
        const char *ARW;                                                                                                                //定义汉字点阵入口数组.
        int P,C,NUM;                                                                                                                                //页址-列址-计数脚标.
        ARW=WORDS;                                                                                                                                        //数组首地址的传递.
        P=PAGE+0XB8;                                                                                                                                //计算初始页地址.
        C=CLMD+0X40;                                                                                                                                //计算初始列地址.
        for(NUM=0;NUM<16;NUM++,C++)                                                                        //列地址累加1,并记录累加次数.
        {
                if(C>0X7F)                                                                                                                                //根据C的值判断在哪片LCD显示.
                {
                        LCDOUT(ARW[NUM],C-64,P,2);                                                        //向第1页当前列输入数据.
                        LCDOUT(ARW[NUM+16],C-64,P+1,2);                                        //向第2页当前列输入数据.
                }
                else
                 {  LCDOUT(ARW[NUM],C,P,1);                                                                //向第1页当前列输入数据.
                   LCDOUT(ARW[NUM+16],C,P+1,1);                                                //向第2页当前列输入数据.
                 }
        }
}

/* ************************************************************************
** 函 数 名:void LCDNUM(char *WORDS,int CLMD,int PAGE)
** 功能描述:向LCD输入字符数字点阵(*WORDS)8*8,并以CLMD为初始列,PAGE为页地址.
*************************************************************************** */
void LCDNUM(const char *WORDS,int CLMD,int PAGE)
{
        const char *ARW;                                                                                                                //定义数字字符点阵入口数组.
        int P,C,NUM;                                                                                                                                //页址-列址-计数脚标.
        ARW=WORDS;                                                                                                                                        //数组首地址的传递.
        P=PAGE+0XB8;                                                                                                                                //计算初始页地址.
        C=CLMD+0X40;                                                                                                                                //计算初始列地址.
        for(NUM=0;NUM<8;NUM++,C++)                                                                        //列地址累加1,并记录累加次数.
        {
                if(C>0X7F)                                                                                                                                //根据C的值判断在哪片LCD显示
                        LCDOUT(ARW[NUM],C-64,P,2);                                                        //向当前列输入数据.
                else
                        LCDOUT(ARW[NUM],C,P,1);                                                                        //向当前列输入数据.
        }
}

/* ************************************************************************
** 函 数 名:void OUTNUM(long N,int D,int CLMD,int PAGE)
** 功能描述:根据参数输出任意数字.
*************************************************************************** */
void OUTNUM(long N,int D,int CLMD,int PAGE)
{
    int i;
    for(i=0;N>0||i<=D;i++)                                                                                //循环判断.
    {
      if(i==D)                                                                                                                                //个位?
              LCDNUM(NUM[N%10+10],CLMD,PAGE);                                //输出带点数.
      else
                   LCDNUM(NUM[N%10],CLMD,PAGE);                                                //输出无点数.
      CLMD=CLMD-6;                                                                                                                //数字的位置.
      N=N/10;                                                                                                                                 //取数据某位的数字.
    }
}
/* ************************************************************************
** 函 数 名:void LCDPIEX(int X,int Y)
** 功能描述:根抿坐标(X,Y)在LCD上画点.
*************************************************************************** */
void LCDPIEX(int X,int Y)
{
        int i;                                                                                                                                                        //定义循环计数的变量.
        int CLMD,PAGE,ROW,E,DATA;                                                                                //列-页-行-片-要写的数据-读出的数据.
        PAGE=0XB8;                                                                                                                                        //第0页的地址.
        DATA=0X01;                                                                                                                                        //参考数据上.
        ROW=Y;                                                                                                                                                        //取得行.
        for(i=0;i<8;i++)                                                                                                                //循环,多次判断,取得PAGE和数据.
        {
                if(ROW<8)                                                                                                                                        //行值小于8,执行if内语句.
                {
                        PAGE=0XB8+i;                                                                                                                //取得页值.
                        DATA=DATA<<ROW;                                                                                                        //取得数据.
                         break;                                                                                                                                        //跳出for循环.
                 }
                ROW=ROW-8;                                                                                                                                //行值减8.
        }
        if(X>63)                                                                                                                                                //当列值大于63时.
        {
                E=2;                                                                                                                                                        //选择第2片LCD.
                CLMD=(X-64)+64;                                                                                                                //取得列值.
        }
        else                                                                                                                                                                //否则.
        {
                E=1;                                                                                                                                                        //选择第2片LCD.
                CLMD=X+64;                                                                                                                                //取得列值.
        }
        DATA=DATA|LCDIN(CLMD,PAGE,E);                                                                //求或.
        LCDOUT(DATA,CLMD,PAGE,E);                                                                                //向当前地址输入数据.
}

/* ************************************************************************
** 函 数 名:void LCDXB(int XBCS,int WORDS)
** 功能描述:根据谐波次数(XBCS),幅度(WORDS)在LCD上自动选择位置显示频谱图.
*************************************************************************** */
void LCDXB(int XBCS,int WORDS)
{
        int CLMD,PAGE,i;                                                                                                                //列-页-计数参数.
        CLMD=0X40+XBCS*6;                                                                                                                //根据谐波次数计算列值.
        PAGE=0XB8;                                                                                                                                        //页的初地址.
        for(WORDS>7;WORDS>7;PAGE++)                                                                        //页地址累加1,至幅值小于8.
        {
                WORDS-8;                                                                                                                                        //幅值减8.
                for(i=0;i<3;i++)                                                                                                        //在相邻3列输出.
                        LCDOUT(0XFF,CLMD+i,PAGE,1);                                                        //输出数据.
        }
        for(i=0;i<3;i++)                                                                                                                //在相邻3列输出.
                LCDOUT(WORDS,CLMD+i,PAGE,1);                                                        //输出最后数据.
}

/* ************************************************************************
** 函 数 名:void OUTADC(int WOEDS)
** 功能描述:向MAX197输入控制字.
*************************************************************************** */
void OUTADC(int WORDS)
{
        TRISD=0X00;                                                                                                                                        //<0000,0000>设置PORTD为输出.
        PORTA=(PORTA|0X0E)&0XFE;                                                                                //<uuuu,1110>译码后实现地址选择.
        PORTB=(PORTB|0X10)&0XDF;                                                                                //<uu01,uuuu>控制信号:写.
        PORTD=WORDS;                                                                                                                                //将数据赋给PORTD端口.
        PORTB=PORTB|0X30;
        PORTA=PORTA&0XF0;                                                                                                                //屏蔽所有地址.
}

/* ************************************************************************
** 函 数 名:int INADC()
** 功能描述:读取MAX197高低12位的AD转换数据.
*************************************************************************** */
signed int INADC()
{
        signed int WORDS;                                                                                                                //定义数据入口参数.
        TRISD=0XFF;                                                                                                                                        //<1111,1111>设置PORTD为输入.
        PORTA=(PORTA|0X0E)&0XFE;                                                                                //<uuuu,1110>译码后实现地址选择.
        PORTB=(PORTB|0X60)&0XEF;                                                                                //<u110,uuuu>控制信号:读高4位数据.
        WORDS=PORTD&0X0F;                                                                                                                //读取PORTD端口数据.
        PORTB=(PORTB|0X20)&0XAF;                                                                                //<u010,uuuu>控制信号:读低8位数据.
        WORDS=PORTD+(WORDS<<8);                                                                                        //读取PORTD端口数据,并与低8位求和.
        PORTB=PORTB|0X30;                                                                                                                //屏蔽所有地址.
        PORTA=PORTA&0XF0;                                                                                                                //将读取的数据作为返回值.
        if(CHX==1)                                                                                                                                        //双极性?
        {
                WORDS=WORDS<<4;                                                                                                                //数据左对齐.
                WORDS=WORDS/16;                                                                                                                //得到最终数据.
        }
        return WORDS;                               //返回数据.
}
/* ************************************************************************
** 函 数 名:void ADCHX()
** 功能描述:根据参数进行双通道AD采样.
*************************************************************************** */
void ADCHX()
{
        for(ADD=0;ADD<64;ADD++)                                                                                //采样64点.
        {
                OUTADC(ADWORDS);                                                                                                //送第一路AD控制字.
                DELAY(0);                                                                                                                                //延时.
                DATA[CHAN*2][ADD]=INADC();                                                        //读取第一路AD转换数据.
                OUTADC(ADWORDS+1);                                                                                        //送第二路AD控制字.
                DELAY(0);                                                                                                                                //延时.
                DATA[1+CHAN*2][ADD]=INADC();                                                //读取第二路AD转换数据.
                DELAY(AD);                                                                                                                        //延时控制采样频率.
        }
}
/* ************************************************************************
** 函 数 名:void ADSHOW()
** 功能描述:数据处理后显示两路信号波形.
*************************************************************************** */
void ADSHOW()
{
        int CH1,CH2;
        signed int data;                                                                                                                        //取数据,显示位置.
        if(CHX==0)                                                                                                                                                //单极性采样.
        {
                CH1=40;                                                                                                                                                        //波形位置.
                CH2=60;                                                                                                                                                        //波形位置.
        }
        else
        {
                CH1=20;                                                                                                                                                        //波形位置.
                CH2=40;                                                                                                                                                        //波形位置.
        }
        LCDCLEAR(2);                                                                                                                                        //清屏.
        for(ADD=0;ADD<64;ADD++)                                                                                                //64点.
        {
                data=(signed int)(40.0*DATA[CHAN*2][ADD]/4096.0);                //数据处理.
           LCDPIEX(ADD+64,CH1-data);                                                                                                                //输出显示.
           data=(signed int)(40.0*DATA[1+CHAN*2][ADD]/4096.0);        //数据处理.
           LCDPIEX(ADD+64,CH2-data);                                                                                                                //输出显示.
        }
}
/* ************************************************************************
** 函 数 名:void ADCHD()
** 功能描述:单通道高频采样,数据处理,显示.
*************************************************************************** */
void ADCHD()
{
        long D,SHU;                                                                                                                                                //数据.
        int n_x,k_x,i;                                                                                                                                //循环参数.
        float Ur,Ui,Urn,Uin;                                                                                                        //数据处理中间变量.
        ADWORDS=ADCAN+7;                                                                                                                        //确定MAX197控制字.
        for(ADD=0;ADD<64;ADD++)                                                                                                //采样.
        {
                OUTADC(ADWORDS);                                                                                                                //送控制字.
                DELAY(0);                                                                                                                                                //延时.
                DATA[0][ADD]=INADC();                                                                                                //读取数据.
        }
        for(ADD=0;ADD<64;ADD++)                                                                                                //显示波形.
        {
                D=(int)(40.0*DATA[0][ADD]/4096.0);                                        //取数据.
           LCDPIEX(ADD+64,40-D);                                                                                                //显示.
   }
        for(n_x=0;n_x<5;n_x++)                                                                                                //计算.
        {
                Urn=0.0;                                                                                                                                                //实部.
                Uin=0.0;                                                                                                                                                //虚部.
                for(k_x=0;k_x<32;k_x++)                                                                                        //n_x次谐波.
                {
                        D=DATA[0][k_x];                                                                                                                //取数据计算.
                        Urn=Urn+D/409.6*cos((2*n_x+1)*(k_x+1)*0.196);
                        Uin=Uin+D/409.6*sin((2*n_x+1)*(k_x+1)*0.196);
                }
                Ur=Urn/16.0;                                                               //
                Ui=Uin/16.0;                                                                                                                                //
                SHU=(long)(100*sqrt(Ur*Ur+Ui*Ui));
                UI[0][n_x]=SHU;                                                                                                                        //第n_x次谐波幅值.
                UI[0][5]=SHU*SHU+UI[0][5];                                                                         //
        }
        UI[0][5]=(long)sqrt(UI[0][5]);                                                                //总幅值.
        for(i=0;i<5;i++)                                                                                                                        //
  {
          SHU=UI[0]*1000;                                                                                                        //
                 SHU=SHU/(UI[0][5]);                                                                                                        //
                 UP[0]=SHU;                                                                                                                                //第i次谐波占有率.
        }
        SHU=1000*(UI[0][5]-UI[0][0]);                                                                        //
        UP[0][5]=SHU/UI[0][5];                                                                                                 //畸变率.
        LCDCLEAN(12,2,126,7);                                                                                                        //清除数据显示区.
        for(i=0;i<6;i++)
        {
                OUTNUM(UI[0],1,28,2+i);                                                                        //显示幅值.
                OUTNUM(UP[0],3,56,2+i);                                                                        //显示占有率.
        }
        ADWORDS=ADCAN;                                                                                                                                //还原控制字.
}

/* ************************************************************************
** 函 数 名:void XBFX()
** 功能描述:全周波傅立叶积分计算各次谐波的幅值,并返回结果.
*************************************************************************** */
void XBFX()
{
        long D,SHU;                                                                                                                                                //数据.
        int n_x,k_x,i,n;                                                                                                                        //循环参数.
        float Ur,Ui,Urn,Uin,UIL[2];                                                                                //数据处理中间变量.
        for(n=0;n<2;n++)                                                                                                                        //两路信号.
        {
                for(n_x=0;n_x<5;n_x++)                                                                                        //计算.
                {
                        Urn=0.0;                                                                                                                                        //实部.
                        Uin=0.0;                                                                                                                                        //虚部.
                        for(k_x=0;k_x<32;k_x++)                                                                                //n_x次谐波.
                        {
                                D=DATA[CHAN*2+n][k_x];                                                                        //取数据计算.
                                Urn=Urn+D/409.6*cos((2*n_x+1)*(k_x+1)*0.196);
                                Uin=Uin+D/409.6*sin((2*n_x+1)*(k_x+1)*0.196);
                        }
                        Ur=Urn/16.0;                                                                         //
                        Ui=Uin/16.0;
                        SHU=(long)(760*sqrt(Ur*Ur+Ui*Ui));                                //
                        UI[n][n_x]=SHU;                                                                                                                //
                        UI[n][5]=SHU*SHU+UI[n][5];                                                                //第n_x次谐波幅值.
                        if(n_x==0)
                                UIL[n]=atan(Ui/Ur);                                                                           //相位.
                }
                UI[n][5]=(long)sqrt(UI[n][5]);                                                        //总幅值.
                for(i=0;i<5;i++)                                                                                                                //
          {
                  SHU=UI[n]*1000;                                                                                                //
                         SHU=SHU/(UI[n][5]);                                                                                                //
                         UP[n]=SHU;                                                                                                                        //第i次谐波占有率.
                }
                SHU=1000*(UI[n][5]-UI[n][0]);                                                                //
                UP[n][5]=SHU/UI[n][5];                                                                                         //畸变率.
        }
        L[CHAN]=abs((long)(1000*(UIL[0]-UIL[1])-40));        //功率因数角.
        S[CHAN]=(long)(UI[0][5]*UI[1][5]);                                                //S.
        P[CHAN]=(long)(S[CHAN]*cos(L[CHAN]/1000.0));        //P.
        Q[CHAN]=(long)(S[CHAN]*sin(L[CHAN]/1000.0));        //Q.
}
/* ***********************************************************************
** 函 数 名:void ABCSH()
** 功能描述:显示双通道数据处理结果.
************************************************************************** */
void ABCSH()
{
        LCDCLEAN(12,1,50,7);                                                                                                        //清除数据显示区.
        OUTNUM(UI[0][5],1,54,1);                                                                                        //显示U*值.
        OUTNUM(UI[1][5],1,54,2);                                                                                        //显示I*值.
        OUTNUM(P[CHAN],2,54,3);                                                                                                //显示P*值.
        OUTNUM(Q[CHAN],2,54,4);                                                                                                //显示Q*值.
        OUTNUM(S[CHAN],2,54,5);                                                                                                //显示S*值.
        OUTNUM(L[CHAN],3,54,6);                                                                                                //显示L*值.
        OUTNUM(F,2,54,7);                                                                                                                        //显示F*值.
}
/* ***********************************************************************
** 函 数 名:void XBSH()
** 功能描述:谐波分析结果显示.
************************************************************************** */
void XBSH()
{
        int n,i;                                                                                                                                                        //参数.
        LCDCLEAN(12,2,126,7);                                                                                                        //清除数据显示区.
        for(n=0;n<2;n++)                                                                                                                        //
        {
                for(i=0;i<6;i++)                                                                                                                //
                {
                        OUTNUM(UI[n],1,28+n*64,2+i);                                                //显示第i次谐波.
                        OUTNUM(UP[n],3,56+n*64,2+i);                                                //显示第i次谐波占有率.
                }
        }
}
/* ***********************************************************************
** 函 数 名:void ADALLSH()
** 功能描述:多通道数据处结果显示.
************************************************************************** */
void ADALLSH()
{
        OUTNUM(UI[0][5],1,40,(2+CHAN));                                                        //显示U*值.
        OUTNUM(UI[1][5],1,40,(5+CHAN));                                                        //显示I*值.
        OUTNUM(P[CHAN],2,114,(2+CHAN));                                                        //显示P*值.
        OUTNUM(Q[CHAN],2,114,(5+CHAN));                                                        //显示Q*值.
}
/* ***********************************************************************
** 函 数 名:void ADALL()
** 功能描述:多通道采样处理显示.
************************************************************************** */
void ADALL()
{
        LCDCLEAN(10,2,50,6);                                                                                                //清除数据显示区.
        LCDCLEAN(76,2,50,6);                                                                                                //清除数据显示区.
        for(CHAN=0;CHAN<3;CHAN++)                                                                                //
        {
                ADWORDS=ADCAN+CHAN*2;                                                                                        //确定控制字.
                ADALLSH();                                                                                                                                //显示.
                ADCHX();                                                                                                                                                //采样.
                XBFX();                                                                                                                                                //计算.
        }
        CHAN=0;                                                                                                                                                        //还原通道.
        ADWORDS=ADCAN;                                                                                                                        //还原控制字.
}
/* ***********************************************************************
** 函 数 名:void PLJS()
** 功能描述:计算频率.
************************************************************************** */
void PLJS()
{
        int i,QH,FF[5];                                                                                                                        //参数.
        QH=(CCP>9)?0:10;                                                                                                                //判断取数位置.
        for(i=0;i<5;i++)                                                                                                                //
        {
                FF=FT[i+QH];                                                                                                                //取数.
        }
        F=(FF[4]>FF[3])?(FF[4]-FF[3]):(FF[4]+65536-FF[3]);
        F=(long)(100000000/F);                                                                                        //判断,并计算频率.
}
/* ***********************************************************************
** 函 数 名:void CYTZ()
** 功能描述:零点检测法,采样频率调整.
************************************************************************** */
void CYTZ()
{
        int i,n,PL[2];                                                                                                                        //参数.
        while(1)
        {
                ADCHX();                                                                                                                                        //AD采样.
                for(i=0,n=0;n<2;i++)                                                                                        //零点判断.
                {
                        if(DATA[CHAN*2][i-1]<=DATA[CHAN*2]&&DATA[CHAN*2]>=DATA[CHAN*2][i+1])
                        {
                                PL[n]=i;                                                                                                                        //第n个零点.
                                n++;                                                                                                                                        //
                        }
                }
                if((PL[1]-PL[0])==32)                                                                                        //两个零点的间隔=32.
                {
                        break;                                                                                                                                        //退出.
                }
                if((PL[1]-PL[0])>32)                                                                                        //两个零点的间隔>32.
                        AD++;                                                                                                                                                //加大采样间隔.
                else
                        AD--;                                                                                                                                                //否则,减小采样间隔.
                if(BACK==1)                                                                                                                                //达不到要求.
                {
                        BACK=0;                                                                                                                                        //标志位清零.
                        AD=50;                                                                                                                                        //AD还原.
                        break;                                                                                                                                        //退出.
                }
                OUTNUM(AD,0,120,0);                                                                                                //显示调整结果.
        }
}
/* ***********************************************************************
** 函 数 名:void MUNS()
** 功能描述:按键功能设置.
************************************************************************** */
void MUNS()
{
        KEY=KEYIN();                                                                                                                                //读按键值.
        switch(KEY)                                                                                                                                        //
        {
                case 0XFE:                                                                                                                                //
                {
                        ADWORDS=ADCAN;                                                                                                        //MAX197控制字.
                        MAXD=1;                                                                                                                                        //置标志位.
                        MAXA=BACK=NEXT=SURE=GUID=0;                                                        //屏蔽其它标志位.
                        CHAN=0;                                                                                                                                        //确定通道.
                        break;                                                                                                                                        //退出.
                }
                case 0XFD:                                                                                                                                //
                {
                        ADWORDS=ADCAN+2;                                                                                                //MAX197控制字.
                        MAXD=1;                                                                                                                                        //置标志位.
                        MAXA=BACK=NEXT=SURE=GUID=0;                                                        //屏蔽其它标志位.
                        CHAN=1;                                                                                                                                        //确定通道.
                        break;                                                                                                                                        //退出.
                }
                case 0XFB:                                                                                                                                //
                {
                        ADWORDS=ADCAN+4;                                                                                                //MAX197控制字.
                        MAXD=1;                                                                                                                                        //置标志位.
                        MAXA=BACK=NEXT=SURE=GUID=0;                                                        //屏蔽其它标志位.
                        CHAN=2;                                                                                                                                        //确定通道.
                        break;                                                                                                                                        //退出.
                }
                case 0XF7:                                                                                                                                //
                {
                        MAXA=1;                                                                                                                                        //置标志位.
                        MAXD=BACK=NEXT=SURE=GUID=0;                                                        //屏蔽其它标志位.
                        break;                                                                                                                                        //退出.
                }
                case 0XEF:                                                                                                                                //
                {
                        BACK=1;                                                                                                                                        //置标志位.
                        MAXD=MAXA=NEXT=SURE=GUID=0;                                                        //屏蔽其它标志位.
                        break;                                                                                                                                        //退出.
                }
                case 0XDF:                                                                                                                                //
                {
                        NEXT=1;                                                                                                                                        //置标志位.
                        MAXD=MAXA=BACK=SURE=GUID=0;                                                        //屏蔽其它标志位.
                        break;                                                                                                                                        //退出.
                }
                case 0XBF:                                                                                                                                //
                {
                        SURE=1;                                                                                                                                        //置标志位.
                        MAXD=MAXA=BACK=NEXT=GUID=0;                                                        //屏蔽其它标志位.
                        break;                                                                                                                                        //退出.
                }
                case 0X7F:                                                                                                                                //
                {
                        GUID=1;                                                                                                                                        //置标志位.
                        MAXD=MAXA=BACK=NEXT=SURE=0;                                                        //屏蔽其它标志位.
                        break;                                                                                                                                        //退出.
                }
        }
}
/* ************************************************************************
** 函 数 名:interrupt HI_ISR()
** 功能描述:高优先级中断服务程序.
*************************************************************************** */
void interrupt HI_ISR()
{
  if(CCP1IF==1)                                                                                                                        //
  {
          CCP1IF=0;                                                                                                                                //清中断标志.
          FT[CCP]=CCPR1L+(CCPR1H<<8);                                                        //读计数器当前值.
          CCP++;                                                                                                                                        //增量加1.
           if(CCP==20)                                                                                                                        //超出.
                        CCP=0;                                                                                                                                //归零.
        }
}
/* ***********************************************************************
** 函 数 名:void interrupt low_priority LOW_ISR()
** 功能描述:按键功能设置.
************************************************************************** */
void interrupt low_priority LOW_ISR()
{
  if(TMR3IF==1)
  {
         ATRL=PORTA&0X0F;                                                                                                        //保存PORTA当前状态.
         BTRL=PORTB&0XF0;                                                                                                        //保存PORTB当前状态.
         PORTA=PORTA&0XF0;                                                                                                //屏蔽所有地址.
         PORTB=PORTB&0X8F;                                                                                                //屏蔽所有控制信号.
         TMR3IF=0;                                                                                                                                //清中断标志.
         TMR3L=0X9A;                                                                                                                        //计数初值.
         MUNS();                                                                                                                                        //读按键,置标志位.
         PORTA=(ATRL|0XF0)&PORTA;                                                                        //还原PORTA状态
         PORTB=(BTRL|0X0F)&PORTB;                                                                        //还原PORTB状态
        }
}

/* ***********************************************************************
** 函 数 名:void GUIDE()
** 功能描述:绘制系统操作指导界面.
************************************************************************** */
void GUIDE()
{
        int x,y;
        LCDCLEAR(1);                                                                                                                                //清屏.
        LCDCLEAR(2);                                                                                                                                //清屏.
        for(y=0;y<3;y++)                                                                                                                //界面占LCD屏6页.
        {
                for(x=0;x<32;x++)                                                                                                        //102列,前51列在第一片LCD上显示.
                {
                        LCDOUT(HELP[y][31-x],0X7F-x,y+0XBA,1);        //输出数据.
                }
                for(x=0;x<32;x++)                                                                                                        //102列,后51列在第一片LCD上显示.
                {
                        LCDOUT(HELP[y][x+32],x+0x40,y+0XBA,2);
                }                                                                                                                                                                        //输出数据.
        }
}
/* ***********************************************************************
** 函 数 名:void MUNM()
** 功能描述:按键功能设置.
************************************************************************** */
void MUNM()
{
        LCDCLEAR(1);                                                                                                                                //清屏.
        LCDCLEAR(2);                                                                                                                                //清屏.
        LCDNUM(ABC[0],48,1);                                                                                                //标题.
        LCDNUM(ABC[1],56,1);                                                                                                //标题.
        LCDNUM(ABC[2],64,1);                                                                                                //标题.
        LCDNUM(ABC[3],72,1);                                                                                                //标题.
        LCDNUM(NUM[10],28,3);                                                                                                //0.
        LCDNUM(ABC[4],36,3);                                                                                                //A相.
        LCDNUM(ABC[5],44,3);                                                                                                //
        LCDNUM(NUM[11],28,4);                                                                                                //1.
        LCDNUM(ABC[6],36,4);                                                                                                //B相.
        LCDNUM(ABC[7],44,4);                                                                                                //
        LCDNUM(NUM[12],28,5);                                                                                                //2.
        LCDNUM(ABC[8],36,5);                                                                                                //C相.
        LCDNUM(ABC[9],44,5);                                                                                                //
        LCDNUM(NUM[13],28,6);                                                                                                //3.
        LCDNUM(ABC[10],36,6);                                                                                                //三相.
        LCDNUM(ABC[11],44,6);                                                                                                //
        LCDNUM(NUM[14],74,3);                                                                                                //4.
        LCDNUM(ABC[12],82,3);                                                                                                //SET.
        LCDNUM(ABC[13],90,3);                                                                                                //
        LCDNUM(NUM[15],74,4);                                                                                                //5.
        LCDNUM(ABC[14],82,4);                                                                                                //HEI.
        LCDNUM(ABC[15],90,4);                                                                                                //
        LCDNUM(NUM[16],74,5);                                                                                                //6.
        LCDNUM(ABC[16],82,5);                                                                                                //YES.
        LCDNUM(ABC[17],90,5);                                                                                                //
        LCDNUM(NUM[17],74,6);                                                                                                //7.
        LCDNUM(ABC[18],82,6);                                                                                                //HELP.
        LCDNUM(ABC[19],90,6);                                                                                                //
        LCDNUM(NUM[ADMO],110,7);                                                                                //显示当前采样模式.
}
/* ***********************************************************************
** 函 数 名:void MUNMAX()
** 功能描述:采样模式界面.
************************************************************************** */
void MUNMAX()
{
        LCDCLEAR(1);                                                                                                                                //清屏.
        LCDCLEAR(2);                                                                                                                                //清屏.
        LCDNUM(ABC[12],56,1);                                                                                                //标题.
        LCDNUM(ABC[13],64,1);                                                                                                //标题.
        LCDNUM(NUM[10],30,3);                                                                                                //0.
        LCDNUM(NUM[0],48,3);                                                                                                //0
        LCDNUM(JS,80,3);                                                                                                                //+
        LCDNUM(NUM[5],88,3);                                                                                                //5
        LCDNUM(NUM[11],30,4);                                                                                                //1.
        LCDNUM(JC,40,4);                                                                                                                //-
        LCDNUM(NUM[5],48,4);                                                                                                //5
        LCDNUM(JS,80,4);                                                                                                                //+
        LCDNUM(NUM[5],88,4);                                                                                                //5
        LCDNUM(NUM[12],30,5);                                                                                                //2.
        LCDNUM(NUM[0],48,5);                                                                                                //0
        LCDNUM(JS,72,5);                                                                                                                //+
        LCDNUM(NUM[1],80,5);                                                                                                //1
        LCDNUM(NUM[0],88,5);                                                                                                //0
        LCDNUM(NUM[13],30,6);                                                                                                //3.
        LCDNUM(JC,40,6);                                                                                                                //-
        LCDNUM(NUM[1],48,6);                                                                                                //1
        LCDNUM(NUM[0],56,6);                                                                                                //0
        LCDNUM(JS,72,6);                                                                                                                //+
        LCDNUM(NUM[1],80,6);                                                                                                //1
        LCDNUM(NUM[0],88,6);                                                                                                //0
}
/* ***********************************************************************
** 函 数 名:void MUNABC()
** 功能描述:双通道显示界面.
************************************************************************** */
void MUNABC()
{
        LCDCLEAR(1);                                                                                                                                //清屏.
        LCDCLEAR(2);                                                                                                                                //清屏.
        LCDNUM(ABC[4+CHAN*2],24,0);                                                                        //标题.
        LCDNUM(ABC[5+CHAN*2],32,0);                                                                        //标题.
        LCDNUM(UB[CHAN],0,1);                                                                                                //U*.
        LCDNUM(IB[CHAN],0,2);                                                                                                //I*.
        LCDNUM(PB[CHAN],0,3);                                                                                                //P*.
        LCDNUM(QB[CHAN],0,4);                                                                                                //Q*.
        LCDNUM(SB[CHAN],0,5);                                                                                                //S*.
        LCDNUM(LB[CHAN],0,6);                                                                                                //L*.
        LCDNUM(FB[CHAN],0,7);                                                                                                //F*.
}
/* ***********************************************************************
** 函 数 名:void MUNXB()
** 功能描述:谐波显示界面.
************************************************************************** */
void MUNXB()
{
        LCDCLEAR(1);                                                                                                                                //清屏.
        LCDCLEAR(2);                                                                                                                                //清屏.
        LCDNUM(ABC[4+CHAN*2],24,0);                                                                        //标题.
        LCDNUM(ABC[5+CHAN*2],32,0);                                                                        //标题.
        LCDNUM(UB[CHAN],20,1);                                                                                        //U*.
        LCDNUM(IB[CHAN],80,1);                                                                                        //I*.
        LCDNUM(BH,40,1);                                                                                                                //符号.
        LCDNUM(BH,100,1);                                                                                                                //符号.
        LCDNUM(NUM[11],0,2);                                                                                                //1.
        LCDNUM(NUM[13],0,3);                                                                                                //3.
        LCDNUM(NUM[15],0,4);                                                                                                //5.
        LCDNUM(NUM[17],0,5);                                                                                                //7.
        LCDNUM(NUM[19],0,6);                                                                                                //9.
}
/* ***********************************************************************
** 函 数 名:void MUNALL()
** 功能描述:多通道界面.
************************************************************************** */
void MUNALL()
{
        LCDCLEAR(1);                                                                                                                                //清屏.
        LCDCLEAR(2);                                                                                                                                //清屏.
        LCDNUM(ABC[10],24,0);                                                                                                //标题.
        LCDNUM(ABC[11],32,0);                                                                                                //标题.
        LCDNUM(UB[0],0,2);                                                                                                        //U1.
        LCDNUM(IB[0],0,5);                                                                                                        //I1.
        LCDNUM(UB[1],0,3);                                                                                                        //U2
        LCDNUM(IB[1],0,6);                                                                                                        //I2.
        LCDNUM(UB[2],0,4);                                                                                                        //U3.
        LCDNUM(IB[2],0,7);                                                                                                        //I3.
        LCDNUM(PB[0],64,2);                                                                                                        //P1.
        LCDNUM(QB[0],64,5);                                                                                                        //Q1.
        LCDNUM(PB[1],64,3);                                                                                                        //P2.
        LCDNUM(QB[1],64,6);                                                                                                        //Q2.
        LCDNUM(PB[2],64,4);                                                                                                        //P3.
        LCDNUM(QB[2],64,7);                                                                                                        //Q3.
}
/* ***********************************************************************
** 函 数 名:void MUND()
** 功能描述:单通道界面.
************************************************************************** */
void MUND()
{
        LCDCLEAR(1);                                                                                                                                //清屏.
        LCDCLEAR(2);                                                                                                                                //清屏.
        LCDNUM(NUM[10],0,0);                                                                                                //标题.
        LCDNUM(JJ,24,0);                                                                                                                //符号.
        LCDNUM(BH,40,0);                                                                                                                //符号.
        LCDNUM(NUM[11],0,2);                                                                                                //1.
        LCDNUM(NUM[13],0,3);                                                                                                //3.
        LCDNUM(NUM[15],0,4);                                                                                                //5.
        LCDNUM(NUM[17],0,5);                                                                                                //7.
        LCDNUM(NUM[19],0,6);                                                                                                //9.
}

/* ************************************************************************
** 函 数 名: void main()
** 功能描述:主函数,实现各子程序调用和流程安排.
*************************************************************************** */
void main()
{
        INITIAL();                                                                                                                                //系统初始化.
        T3INIT();                                                                                                                                        //TMR3时钟初始化.
        LCDINITI(1);                                                                                                                        //初始化第一片LCD.
        LCDINITI(2);                                                                                                                        //初始化第二片LCD.
        IPEN=1;                                                                                                                                                //使能中断高低优先级.
        INTCON=INTCON|0xC0;                                                                                                //开总中断.
        TMR3ON=1;                                                                                                                                        //开定时器.
        MUNM();                                                                                                                                                //显示主菜单.
        while(1)                                                                                                                                        //一级while(1)
        {
                if(MAXD==1)                                                                                                                        //进入双通道数据处量.
                {
                        MAXD=0;                                                                                                                                //标志位清零.
                        MUNABC();                                                                                                                        //显示界面.
                        CCPINIT();                                                                                                                //启动获取频率数据.
                        while(1)                                                                                                                        //二级while(1)
                        {
                                ABCSH();                                                                                                                //数据显示.
                                ADSHOW();                                                                                                                //波形显示.
                                ADCHX();                                                                                                                //AD采样.
                                XBFX();                                                                                                                        //谐波分析.
                                PLJS();                                                                                                                        //频率计算.
                                if(MAXD==1)                                                                                                        //切换采样通道.
                                {
                                        MAXD=0;                                                                                                                //标志位清零.
                                        MUNABC();                                                                                                        //重新显示界面.
                                }
                                if(SURE==1)                                                                                                        //
                                {
                                        SURE=0;                                                                                                                //标志位清零.
                                        CYTZ();                                                                                                                //调整采样频率.
                                }
                                if(NEXT==1)                                                                                                        //进入显示谐波数据显示界面.
                                {
                                        NEXT=0;                                                                                                                //标志位清零.
                                        MUNXB();                                                                                                        //显示界面.
                                        while(1)                                                                                                        //三级while(1)
                                        {
                                                ADCHX();                                                                                                //AD采样.
                                                XBFX();                                                                                                        //谐波分析.
                                                XBSH();                                                                                                        //数据显示.
                                                if(NEXT==1)                                                                                        //
                                                {
                                                        NEXT=0;                                                                                                //标志位清零.
                                                        CYTZ();                                                                                                //调整采样频率.
                                                }
                                                if(MAXD==1)                                                                                        //切换采样通道.
                                                {
                                                        MAXD=0;                                                                                                //标志位清零.
                                                        MUNXB();                                                                                        //重新显示界面.
                                                }
                                                if(BACK==1)                                                                                        //
                                                {
                                                        BACK=0;                                                                                                //标志位清零.
                                                        MUNABC();                                                                                        //显示上级界面.
                                                        break;                                                                                                //退出本级.
                                                }
                                                if(GUID==1)                                                                                        //显示HELP.
                                                {
                                                        break;                                                                                                //退出本级.
                                                }
                                        }
                                }
                                if(MAXA==1)                                                                                                        //进入多通道数据处理.
                                {
                                        break;                                                                                                                //退出本级.
                                }
                                if(BACK==1)                                                                                                        //
                                {
                                        BACK=0;                                                                                                                //标志位清零.
                                        MUNM();                                                                                                                //显示上级界面.
                                        break;                                                                                                                //退出本级.
                                }
                                if(GUID==1)                                                                                                        //显示HELP.
                                {
                                        break;                                                                                                                //退出本级.
                                }
                        }
                        CCP1IE=0;                                                                                                                        //关闭频率采样中断.
                        TMR1ON=0;                                                                                                                        //关闭频率采样时钟
                }
                if(MAXA==1)                                                                                                                        //进入多通道数据处理.
                {
                        MAXA=0;                                                                                                                                //标志位清零.
                        MUNALL();                                                                                                                        //显示界面.
                        while(1)                                                                                                                        //二级while(1)
                        {
                                ADALL();                                                                                                                //多通道数据采样显示.
                                if(MAXD==1)                                                                                                        //切换到双通道采样.
                                {
                                        break;                                                                                                                //退出本级.
                                }
                                if(BACK==1)                                                                                                        //
                                {
                                        BACK=0;                                                                                                                //标志位清零.
                                        MUNM();                                                                                                                //显示上级界面.
                                        break;                                                                                                                //标志位清零.
                                }
                                if(GUID==1)                                                                                                        //显示HELP.
                                {
                                        break;                                                                                                                //退出本级.
                                }
                        }
                }
                if(BACK==1)                                                                                                                        //选择采样模式.
                {
                        BACK=0;                                                                                                                                //标志位清零.
                        MUNMAX();                                                                                                                        //显示界面.
                        while(1)                                                                                                                        //
                        {
                                if(MAXD==1&&CHAN==0)                                                                //模式0.
                                {
                                        MAXD=0;                                                                                                                //标志位清零.
                                        ADMO=0;                                                                                                                //模式0.
                                        CHX=0;                                                                                                                //单极性.
                                        LCDNUM(NUM[0],112,7);                                                        //显示当前采样模式.
                                        ADCAN=0X40;                                                                                                //基控制字.
                                }
                                if(MAXD==1&&CHAN==1)                                                                //模式1.
                                {
                                        MAXD=0;                                                                                                                //标志位清零.
                                        ADMO=1;                                                                                                                //模式1.
                                        CHX=1;                                                                                                                //双极性.
                                        LCDNUM(NUM[1],112,7);                                                        //显示当前采样模式.
                                        ADCAN=0X48;                                                                                                //基控制字.
                                }
                                if(MAXD==1&&CHAN==2)                                                                //模式2.
                                {
                                        MAXD=0;                                                                                                                //标志位清零.
                                        ADMO=2;                                                                                                                //模式2.
                                        CHX=0;                                                                                                                //单极性.
                                        LCDNUM(NUM[2],112,7);                                                        //显示当前采样模式.
                                        ADCAN=0X50;                                                                                                //基控制字.
                                }
                                if(MAXA==1)                                                                                                        //模式3.
                                {
                                        MAXA=0;                                                                                                                //标志位清零.
                                        ADMO=3;                                                                                                                //模式3.
                                        CHX=1;                                                                                                                //双极性.
                                        LCDNUM(NUM[3],112,7);                                                        //显示当前采样模式.
                                        ADCAN=0X58;                                                                                                //基控制字.
                                }
                                if(SURE==1)                                                                                                        //
                                {
                                        SURE=0;                                                                                                                //标志位清零.
                                        CHAN=0;                                                                                                                //标志位清零.
                                        MUNM();                                                                                                                //显示上级界面.
                                        break;                                                                                                                //退出本级.
                                }
                        }
                }
                if(NEXT==1)                                                                                                                        //进入单通道高速采样.
                {
                        NEXT=0;                                                                                                                                //标志位清零.
                        MUND();                                                                                                                                //显示界面.
                        while(1)                                                                                                                        //二级while(1).
                        {
                                ADCHD();                                                                                                                //数据采样处量显示.
                                if(BACK==1)                                                                                                        //
                                {
                                        BACK=0;                                                                                                                //标志位清零.
                                        MUNM();                                                                                                                //显示上级界面.
                                        break;                                                                                                                //退出本级.
                                }
                        }
                }
                if(SURE==1)                                                                                                                        //
                {
                        SURE=0;                                                                                                                                //标志位清零.
                        MUNM();                                                                                                                                //显示主界面.
                }
                if(GUID==1)                                                                                                                        //
                {
                        GUID=0;                                                                                                                                //标志位清零.
                        GUIDE();                                                                                                                        //显示HELP.
                }
        }
}

出0入0汤圆

发表于 2008-4-11 20:00:19 | 显示全部楼层
不太好看,上文件
点击此处下载 ourdev_249202.txt(文件大小:46K) (原文件名:Program.txt)

出0入0汤圆

发表于 2008-4-12 00:37:50 | 显示全部楼层
不错,几点建议
1、即使是电压电流同时采样,因前端互感器及滤波电路参数差异,还是要补偿相位差,否则会功率值引起较大的误差。
2、在有谐波时,P!=S*COS
3、没看懂怎么控制采样间隔。
4、10us定时中断对单片机来说负荷太重了吧。

出0入0汤圆

发表于 2008-4-12 00:39:03 | 显示全部楼层
丢数据你怎么处理?
丢数据的话,整个项目枪毙。

出0入0汤圆

发表于 2008-4-12 21:52:12 | 显示全部楼层
用硬件锁相环电路做N倍频处理,给CPU中断信号进行采样,可以避免输入信号频率变换带来的采样间隔误差,一般一个周波采样16点应该够用了,再做傅立叶

出0入0汤圆

发表于 2008-4-12 22:28:39 | 显示全部楼层
国标要求21次谐波

出10入95汤圆

发表于 2008-4-12 22:46:51 | 显示全部楼层
24楼很开放呀牛人,28楼正解,我们原来就是这么做的

出0入0汤圆

 楼主| 发表于 2008-4-14 08:47:34 | 显示全部楼层
21次谐波 最少要64个点,一般要128个点

出0入0汤圆

发表于 2009-3-17 13:45:18 | 显示全部楼层
讨论的好 做个标记

出0入0汤圆

发表于 2009-3-17 14:08:53 | 显示全部楼层
28楼的方法是通行的方法,如果你的硬件不具备频率跟踪的能力,仅靠软件(我个人的认识)是无法准确控制采样间隔的。

出0入162汤圆

发表于 2009-3-17 14:42:18 | 显示全部楼层
28楼的效果最好,跟踪频率变化的。

如果不具备硬件跟踪,那么就软件做了。

测周期,然后实时改变采样间隔。

电网频率不会变化很激烈和频繁的,还是比较稳定的

出0入0汤圆

发表于 2009-3-17 14:53:17 | 显示全部楼层
MARK

出0入0汤圆

发表于 2009-3-19 21:10:00 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-3-20 09:01:59 | 显示全部楼层
不错 不过我是通过AD采样做

出0入0汤圆

发表于 2009-4-28 19:31:06 | 显示全部楼层
记号!

出0入0汤圆

发表于 2009-8-31 13:25:11 | 显示全部楼层
我也在做交流采样,用的是ARM2138,现在也是想求助一个傅氏12点交流采样的算法。请问1楼的朋友如何联系?谢谢

出0入0汤圆

发表于 2009-8-31 13:27:35 | 显示全部楼层
关注中.............

出0入0汤圆

发表于 2009-8-31 13:33:31 | 显示全部楼层
记号

出0入0汤圆

发表于 2010-1-4 23:55:18 | 显示全部楼层
都是牛人啊!

学习中。。。

出0入0汤圆

发表于 2010-1-14 12:51:37 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-1-14 15:49:05 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-1-14 15:55:47 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-1-14 16:05:24 | 显示全部楼层
Mark

出0入0汤圆

发表于 2010-1-14 19:49:50 | 显示全部楼层
点数稍微多取一些,比如32点、64点每周期。采样率根据电网频率自动锁定(软件根据频率修改采样率)。这样即使不同步,也没有关系,只要是整数个周期,均方根值计算结果不会有大的跳动。如果用于计量的话还是需要用专用芯片有保障,如果纯粹测量显示的话单片机完全可以搞定,显示用滤波搞一下可以保证显示不乱跳。

出0入0汤圆

发表于 2011-2-24 21:46:36 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-2-24 21:54:22 | 显示全部楼层
关注

出0入0汤圆

发表于 2011-3-24 23:15:46 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-11 08:57:59 | 显示全部楼层
看了半天也不知道怎么弄

出0入0汤圆

发表于 2011-6-11 09:27:13 | 显示全部楼层
回复【25楼】xzyang
-----------------------------------------------------------------------

这个傅里叶变换算法直接就能带吗 能不能再细讲讲

出0入0汤圆

发表于 2011-6-11 14:00:41 | 显示全部楼层
楼主有具体要求么?

一直想做电力方面的东东,可是没机会。

出0入0汤圆

发表于 2011-6-12 17:32:58 | 显示全部楼层
路过

出0入0汤圆

发表于 2011-6-12 18:58:04 | 显示全部楼层
MARK一下

出0入0汤圆

发表于 2011-6-12 23:41:57 | 显示全部楼层
关注!

出0入0汤圆

发表于 2011-6-13 08:00:38 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-13 12:01:03 | 显示全部楼层
准同步采样法:ad采样数据-》fir滤波->测频率-》根据频率调整采样点(软件调整,硬件一直固定采样频率)做到跟随基频频率变化(即准同步)-》fft运算,平滑采样值,去掉量化噪声-》fft结果实部平方+虚部平方再开方

我这的做法,但细节不清楚!

出0入0汤圆

发表于 2011-6-14 22:29:26 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-19 09:25:22 | 显示全部楼层
回复【58楼】chinaye1  程序猿
-----------------------------------------------------------------------

这个方法是用来测谐波的吧!?

出0入0汤圆

发表于 2011-6-19 09:26:15 | 显示全部楼层
回复【楼主位】myworkmail  
-----------------------------------------------------------------------

请问楼主同步算法是用来做什么的?
测量高次谐波还是做什么用?

出0入0汤圆

发表于 2012-2-17 15:13:28 | 显示全部楼层
-----------------------------------------------------------------------

电力上的交流电流信号采样的话,当电网频率不是很稳定的时候,例如出现变频器,中频炉等大型功率设备器件时,就会出现多次谐波,时候交流电流处理就要做处理了

出0入0汤圆

发表于 2012-11-16 17:02:56 | 显示全部楼层
mark,在找合适的算法

出0入162汤圆

发表于 2012-11-16 20:11:00 来自手机 | 显示全部楼层
交流工频信号要求可以定时采样,对N个周期的采样绝对值求平均值即可,精度很好
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 07:13

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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