📄 简易谐波分析仪.c
字号:
/* ***********************************************************************
** 系统程序:多路信号实时采集和处理,并将处理后的数据以不同的
** 方式显示.同时可根据按键输入实现任务调度.
** 时 间:2005/08/05.
*************************************************************************** */
#include "pic18.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.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -