Dateien hochladen nach „“
This commit is contained in:
parent
5cf9d87806
commit
4b217fb1ee
649
1602.c
Normal file
649
1602.c
Normal file
@ -0,0 +1,649 @@
|
||||
//==========================================================================
|
||||
// LCR表驱动程序 V1.0
|
||||
// xjw01 于莆田 2011.10
|
||||
//==========================================================================
|
||||
//==========================================================================
|
||||
#define uchar unsigned char
|
||||
#define uint unsigned int
|
||||
#define ulong unsigned long
|
||||
#include <reg52.h>
|
||||
#include <math.h>
|
||||
|
||||
//==========================================================================
|
||||
// 项目:LCD1602 四线驱动程序
|
||||
// 设计要点:
|
||||
// LCD1602 的运行速度慢,而单片机运行的速度快,因此容易因为速度不
|
||||
// 匹配造成调试失败。因此,调试之前应准确测试lcd_delay() 延时函数
|
||||
// 准确的延时量,如果不能满足注释中的要求,则应调整循次数。每步操
|
||||
// 作所需的延时量,按照数据手册指标指行,同时留下足够的时间余量。
|
||||
// 硬件连接:
|
||||
// 至少需要9条线,电源线2条,7条信号线。信号线详见程序中的接口定义。
|
||||
// 清注意对LCD1602比对的调节,否则无显示。
|
||||
// 设计:许剑伟,于莆田,2010.12
|
||||
//==========================================================================
|
||||
sbit lcd_RS = P0^6; //数据命令控制位,0命令1数据
|
||||
sbit lcd_RW = P0^5; //读写位,0写1读
|
||||
sbit lcd_EN = P0^4; //使能位,下降沿触发
|
||||
sbit lcd_D4 = P0^3; //数据端口D4
|
||||
sbit lcd_D5 = P0^2; //数据端口D5
|
||||
sbit lcd_D6 = P0^1; //数据端口D6
|
||||
sbit lcd_D7 = P0^0; //数据端口D7
|
||||
//==========================================================================
|
||||
void lcd_delay(int n){ //LCD专用延时函数
|
||||
//32MHz钟频下,约循环3000次延迟1毫秒
|
||||
int i,j;
|
||||
if(n<0) { for(i=0;i< 30;i++); return; } //10us
|
||||
if(n== 0) { for(i=0;i<150;i++); return; } //50us
|
||||
for(;n;n--){ for (j=0;j<3000;j++); } //n毫秒
|
||||
}
|
||||
//==========================================================================
|
||||
void lcd_B(char f, uchar c, char t){ //控制四线式接口LCD的7个脚
|
||||
//f=0写命令字, f=1写RAM数据, f=2读RAM数据, f=3读RAM数据
|
||||
lcd_EN = 0;
|
||||
lcd_RS = f%2;
|
||||
lcd_RW = f/2%2;
|
||||
//移入高四位
|
||||
lcd_D4 = c & 16;
|
||||
lcd_D5 = c & 32;
|
||||
lcd_D6 = c & 64;
|
||||
lcd_D7 = c & 128;
|
||||
lcd_EN = 1; lcd_delay(-1); lcd_EN = 0; //使能脉冲
|
||||
if(f==4) { lcd_delay(t); return; }
|
||||
//移入低四位
|
||||
lcd_D4 = c & 1;
|
||||
lcd_D5 = c & 2;
|
||||
lcd_D6 = c & 4;
|
||||
lcd_D7 = c & 8;
|
||||
lcd_EN = 1; lcd_delay(-1); lcd_EN = 0; //使能脉冲
|
||||
lcd_delay(t); //不同的命令,响应时间不同,清零命令需要2ms
|
||||
}
|
||||
//==========================================================================
|
||||
void lcd_init(){ //LCD1602 初始化
|
||||
//启动四线模式须势行9个步骤,初始化所须耗时较长,约65ms,时限不可减
|
||||
lcd_delay(20); //启动lcd之前须延时大于15ms,直到VDD大于4.5V
|
||||
lcd_B(4, 0x30, 9); //置8线模式,须延时大于4.1ms
|
||||
lcd_B(4, 0x30, 5); //置8线模式,须延时大于100us
|
||||
lcd_B(4, 0x30, 5); //置8线模式,手册中未指定延时
|
||||
lcd_B(4, 0x20, 5); //进入四线模式
|
||||
lcd_B(0, 0x28, 5); //四线模式双行显示
|
||||
lcd_B(0, 0x0C, 5); //打开显示器
|
||||
lcd_B(0, 0x80, 5); //RAM指针定位
|
||||
lcd_B(0, 0x01, 5); //启动清屏命初始化LCD
|
||||
}
|
||||
//==========================================================================
|
||||
//=========================几个功能常用函数=================================
|
||||
void lcd_cls() { lcd_B(0, 0x01+0, 2); } //清屏
|
||||
void lcd_cur0() { lcd_B(0, 0x0C+0, 0); } //隐藏光标
|
||||
void lcd_goto1(uchar x){ lcd_B(0, 0x80+x, 0); } //设置DDRAM地址,第1行x位
|
||||
void lcd_goto2(uchar x){ lcd_B(0, 0xC0+x, 0); } //设置DDRAM地址,第2行x位
|
||||
void lcd_putc(uchar d) { lcd_B(1, 0x00+d, 0); } //字符输出
|
||||
void lcd_puts(uchar *s){ for(; *s; s++) lcd_B(1,*s,0); } //字串输出
|
||||
|
||||
//==========================================================================
|
||||
//===============================延时函数===================================
|
||||
void delay(uint loop) { uint i; for(i=0;i<loop;i++); } //延时函数
|
||||
void delay2(uint k) { for(;k>0;k--) delay(10000); } //长延时,k=100大约对应1秒
|
||||
|
||||
//==========================================================================
|
||||
//=================================AD转换===================================
|
||||
sfr P1ASF = 0x9D; //将P1置为模拟口寄存器(使能),各位中为1的有效
|
||||
sfr ADC_CONTR = 0xBC; //A/D转换控制寄存器
|
||||
sfr ADC_res = 0xBD; //A/D转换结果寄存器
|
||||
sfr ADC_resl = 0xBE; //A/D转换结果寄存器
|
||||
|
||||
void set_channel(char channel){
|
||||
P1ASF = 1<<channel;
|
||||
ADC_CONTR = channel+128; //最高位是电源开关,低3位通道选择
|
||||
delay(1); //首次打开电源应延迟,使输入稳定
|
||||
}
|
||||
uint getAD2(){
|
||||
ADC_CONTR |= 0x08; //00001000,置ADC_START=1启动A/D 转换
|
||||
while ( !(ADC_CONTR & 0x10) ); //等待A/D转换结束(ADC_FLAG==0)
|
||||
ADC_CONTR &= 0xE7; //11100111,置ADC_FLAG=0清除结束标记, 置ADC_START=0关闭A/D 转换
|
||||
return ADC_res*4 + ADC_resl;
|
||||
}
|
||||
/*
|
||||
uchar get_AD(){
|
||||
ADC_CONTR |= 0x08; //00001000,置ADC_START=1启动A/D 转换
|
||||
while( !(ADC_CONTR & 0x10) ); //等待A/D转换结束(ADC_FLAG==0)
|
||||
ADC_CONTR &= 0xE7; //11100111,置ADC_FLAG=0清除结束标记, 置ADC_START=0关闭A/D 转换
|
||||
return ADC_res;
|
||||
}
|
||||
*/
|
||||
uint getAD10() reentrant { //10次采样
|
||||
char i;
|
||||
uint c = 0;
|
||||
for(i=0;i<10;i++) c += getAD2();
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//==================================EEPROW偏程==============================
|
||||
sfr IAP_data = 0xC2;
|
||||
sfr IAP_addrH = 0xC3;
|
||||
sfr IAP_addrL = 0xC4;
|
||||
sfr IAP_cmd = 0xC5;
|
||||
sfr IAP_trig = 0xC6;
|
||||
sfr IAP_contr = 0xC7;
|
||||
/********************
|
||||
写字节时,可以将原有数据中的1改为0,无法将0改为1,只能使用擦除命令将0改为1
|
||||
应注意,擦除命令会将整个扇区擦除
|
||||
*********************/
|
||||
void saEEP(){ //EEP保护
|
||||
IAP_cmd = 0; //关闭令,保护
|
||||
IAP_contr = 0; //关EEPROM,保护
|
||||
IAP_trig = 0;
|
||||
IAP_addrL = 255; //设置读取地址的低字节,地址改变才需要设置
|
||||
IAP_addrH = 255; //设置读取地址的高字节,地址改变才需要设置
|
||||
}
|
||||
uchar readEEP(uint k){ //读取
|
||||
IAP_addrL = k; //设置读取地址的低字节,地址改变才需要设置
|
||||
IAP_addrH = k>>8; //设置读取地址的高字节,地址改变才需要设置
|
||||
IAP_contr = 0x81; //设置等待时间,1MHz以下取7,2M以下取6,3M取5,6M取4,12M取3,20M取2,24M取1,30M取0,前导1表示许档IAP
|
||||
IAP_cmd = 1; //读取值1,写取2,擦除取3,擦除时按所在字节整个扇区撺除
|
||||
IAP_trig = 0x5A; //先送5A
|
||||
IAP_trig = 0xA5; //先送5A再送A5立即触发
|
||||
saEEP(); //保护
|
||||
return IAP_data;
|
||||
}
|
||||
void writeEEP(uint k, uchar da){ //写入
|
||||
IAP_data = da; //传入数据
|
||||
IAP_addrL = k; //设置读取地址的低字节,地址改变才需要设置
|
||||
IAP_addrH = k>>8; //设置读取地址的高字节,地址改变才需要设置
|
||||
IAP_contr = 0x81; //设置等待时间,1MHz以下取7,2M以下取6,3M取5,6M取4,12M取3,20M取2,24M取1,30M取0,前导1表示许档IAP
|
||||
IAP_cmd = 2; //读取值1,写取2,擦除取3,擦除时按所在字节整个扇区撺除
|
||||
IAP_trig = 0x5A; //先送5A
|
||||
IAP_trig = 0xA5; //先送5A再送A5立即触发
|
||||
saEEP(); //保护
|
||||
}
|
||||
void eraseEEP(uint k){ //擦除
|
||||
IAP_addrL = k; //设置读取地址的低字节,地址改变才需要设置
|
||||
IAP_addrH = k>>8; //设置读取地址的高字节,地址改变才需要设置
|
||||
IAP_contr = 0x81; //设置等待时间,1MHz以下取7,2M以下取6,3M取5,6M取4,12M取3,20M取2,24M取1,30M取0,前导1表示许档IAP
|
||||
IAP_cmd = 3; //读取值1,写取2,擦除取3,擦除时按所在字节整个扇区撺除
|
||||
IAP_trig = 0x5A; //先送5A
|
||||
IAP_trig = 0xA5; //先送5A再送A5立即触发
|
||||
saEEP(); //保护
|
||||
}
|
||||
|
||||
xdata struct Ida{
|
||||
char zo[3];//三个频率下的零点改正值
|
||||
char j1; //相位补偿(3倍档)
|
||||
char j2; //相位补偿(10倍档)
|
||||
char J[4]; //相位补偿(V/I变换器)
|
||||
char R[4]; //下臂电阻修正(20,1k,10k,100k)
|
||||
char g1; //增益修正(3倍档)
|
||||
char g2; //增益修正(10倍档)
|
||||
} cs;
|
||||
|
||||
void cs_RW(char rw){
|
||||
uchar i,*p = &cs;
|
||||
if(rw){
|
||||
eraseEEP(0);
|
||||
for(i=0;i<sizeof(cs);i++) writeEEP(i,p[i]);
|
||||
}else{
|
||||
for(i=0;i<sizeof(cs);i++) p[i]=readEEP(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//==================================LCR主程序===============================
|
||||
//==========================================================================
|
||||
sfr P1M1=0x91; //P1端口设置寄存器
|
||||
sfr P1M0=0x92; //P1端口设置寄存器
|
||||
sfr P0M1=0x93; //P0端口设置寄存器
|
||||
sfr P0M0=0x94; //P0端口设置寄存器
|
||||
sfr P2M1=0x95; //P2端口设置寄存器
|
||||
sfr P2M0=0x96; //P2端口设置寄存器
|
||||
sfr P3M1=0xB1; //P3端口设置寄存器
|
||||
sfr P3M0=0xB2; //P3端口设置寄存器
|
||||
|
||||
|
||||
sbit spk=P2^3; //蜂鸣器
|
||||
sbit Kb=P2^1; //量程开关B
|
||||
sbit Ka=P2^2; //量程开关A
|
||||
sbit DDS2=P1^2;//移相方波输出口
|
||||
sbit K3=P1^7;
|
||||
sbit K4=P1^6;
|
||||
sbit K5=P1^5; //7.8kHz滤波开关
|
||||
sbit K6=P1^4;
|
||||
sbit K8=P2^0; //100Hz滤波开关
|
||||
xdata uchar menu=1,menu2=0; //菜单变量
|
||||
|
||||
//==============字符显示函数====================
|
||||
#define digW 4 //数字显示位数宏
|
||||
void lcd_putp(float a,float b,char bo,char n, float qmin){ //带单位显示复数,n是单位下限,qmin是最小位权值(用于限定有效数字)
|
||||
code uchar dwB[] = {'p','n','u','m','o','k','M','G'}; //单位表
|
||||
char i,j, c=0, h=digW-1, fh[2]={' ','+'};
|
||||
long d,q,Q=1; //D最高位权
|
||||
float f,g=1;
|
||||
if(a<0) fh[0] = '-', a = -a;
|
||||
if(b<0) fh[1] = '-', b = -b;
|
||||
if(a>b) f = a; else f = b;
|
||||
if(qmin) {
|
||||
a += qmin/2, a -= fmod(a,qmin)-qmin/1000;
|
||||
b += qmin/2; b -= fmod(b,qmin)-qmin/1000;
|
||||
}
|
||||
for(i=1;i<digW;i++) Q *= 10;
|
||||
for(i=0;i<3;i++){ if(f*g >= 1000) g/=1000, c++; } //以3位为单位移动小数点,右移
|
||||
for(i=0;i<n;i++){ if(f*g < 1) g*=1000, c--; } //以3位为单位移动小数点,左移
|
||||
for(i=1;i<digW && f*g<Q;i++) g*=10,h--; //继续移动小数点,使之满字
|
||||
for(i=0;i<2;i++){
|
||||
if(i) d = b*g; //取出实部
|
||||
else d = a*g; //取出虚部
|
||||
q = Q;
|
||||
lcd_putc(fh[i]); //显示符号
|
||||
for(j=0; j<digW; j++){ //数字输出
|
||||
lcd_putc(d/q+48); //数字
|
||||
if(j==h) lcd_putc('.');//小数点
|
||||
d %= q, q /= 10;
|
||||
}
|
||||
if(!bo) break; //不显示虚部
|
||||
}
|
||||
lcd_putc(dwB[c+4]); //单位
|
||||
}
|
||||
void lcd_putf(float a, char n, float qmin) //带单位显示浮点数,n是单位下限
|
||||
{ lcd_putp(a,0,0,n,qmin); }
|
||||
void lcd_int(uint a,char w){ //定宽显示正整数
|
||||
char i=0, s[5] = {' ',' ',' ',' ',' '};
|
||||
for(;a;i++){ s[i] = a%10+48, a /= 10; }
|
||||
for(;w;w--) lcd_putc(s[w-1]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//==============低频信号DDS====================
|
||||
//PCA相关寄存器
|
||||
sfr CMOD = 0xD9; //钟源选择控制等
|
||||
sfr CH = 0xF9; //PCA的计数器
|
||||
sfr CL = 0xE9; //PCA的计数器
|
||||
sfr CCON = 0xD8; //PCA控制寄存器
|
||||
sfr CCPAM0 = 0xDA; //PCA模块0工作模式寄存器
|
||||
sfr CCPAM1 = 0xDB; //PCA模块1工作模式寄存器
|
||||
sfr CCAP0L = 0xEA; //模块0捕获寄存器低位
|
||||
sfr CCAP0H = 0xFA; //模块0捕获寄存器高位
|
||||
|
||||
sbit PPCA = IP^7; //PCA的中断优先级设置
|
||||
sbit CCF0 = CCON^0; //PCA的模块0中断标志
|
||||
sbit CCF1 = CCON^1; //PCA的模块1中断标志
|
||||
sbit CR = CCON^6; //PCA计数器使能
|
||||
|
||||
void PWM_init(){ //把PCA置为PWM
|
||||
CMOD = 2; //0000 0010 计数源选择,钟源取fosc/2
|
||||
CL = CH = 0;
|
||||
CCAP0L = CCAP0H = 192; //占空比为25%
|
||||
//CCPAM0=0x42;//0100 0010,PCA的模块0设置为PWM模式,无中断
|
||||
CCPAM0=0x53;//0101 0011,PCA的模块0设置为PWM模式,有中断,下降沿中断
|
||||
PPCA = 1; //优先中断
|
||||
//CR = 1; //开始计数
|
||||
EA = 1; //开总中断
|
||||
}
|
||||
|
||||
uint ph=0, phM=256, feq=1000; //相位,phM相位步进值
|
||||
xdata float feqX=1000; //实际输出频率
|
||||
uchar code sinB[256]={
|
||||
//查询表中不可装载零值,否则会造成无中断产生
|
||||
255,255,255,255,255,255,254,254,253,252,252,251,250,249,248,247,246,245,243,242,240,239,237,236,234,232,230,229,227,225,222,220,
|
||||
218,216,214,211,209,206,204,201,199,196,194,191,188,185,183,180,177,174,171,168,165,162,159,156,153,150,147,144,140,137,134,131,
|
||||
128,125,122,119,116,112,109,106,103,100, 97, 94, 91, 88, 85, 82, 79, 76, 73, 71, 68, 65, 62, 60, 57, 55, 52, 50, 47, 45, 42, 40,
|
||||
38, 36, 34, 31, 29, 27, 26, 24, 22, 20, 19, 17, 16, 14, 13, 11, 10, 9, 8, 7, 6, 5, 4, 4, 3, 2, 2, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 16, 17, 19, 20, 22, 24, 26, 27, 29, 31, 34, 36,
|
||||
38, 40, 42, 45, 47, 50, 52, 55, 57, 60, 62, 65, 68, 71, 73, 76, 79, 82, 85, 88, 91, 94, 97,100,103,106,109,112,116,119,122,125,
|
||||
128,131,134,137,140,144,147,150,153,156,159,162,165,168,171,174,177,180,183,185,188,191,194,196,199,201,204,206,209,211,214,216,
|
||||
218,220,222,225,227,229,230,232,234,236,237,239,240,242,243,245,246,247,248,249,250,251,252,252,253,254,254,255,255,255,255,255
|
||||
};
|
||||
uchar code fbB[256]={ //方波DDS查询表
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
|
||||
};
|
||||
uchar chuX=0; //方波DDS初相
|
||||
void PCAinter(void) interrupt 7 {//PCA中断
|
||||
uchar x,y;
|
||||
CCF0=0; //清除中断请求,以免反复中断
|
||||
x = ph >> 8; //截断正弦相位累加器,取高8位
|
||||
y = x + chuX; //方波相位
|
||||
CCAP0H = sinB[x];//正弦DDS输出
|
||||
DDS2 = fbB[y]; //方波DDS输出
|
||||
ph += phM; //相位累加
|
||||
}
|
||||
void setDDS(uint f){ //参考时钟是c=(fosc/2)/256=32000000/2/256=62500,频率f=c*phM/2^16
|
||||
feq = f;
|
||||
phM=f*65536.0/62500; //phM=f*2^16/62500
|
||||
feqX = 62500.0*phM/65536; //实际输出频率
|
||||
ph = 0; //高频时,使波形对称
|
||||
if(!f) CR=0; else CR=1;
|
||||
}
|
||||
|
||||
//相位控制函数
|
||||
xdata char xw=0; //相位
|
||||
void set90(char k){ //设置方波的相位差
|
||||
k %= 4;
|
||||
if(k<0) k += 4;
|
||||
if(k==0) chuX=0; //移相0度
|
||||
if(k==1) chuX=64; //移相90度
|
||||
if(k==2) chuX=128; //移相180度
|
||||
if(k==3) chuX=192; //移相270度
|
||||
xw = k;
|
||||
}
|
||||
void set902() { set90(xw+1); } //相位步进
|
||||
|
||||
//==============量程控制函数====================
|
||||
xdata char rng=1; //量程
|
||||
void setRng(char k){//切换量程
|
||||
if(k==0) Ka=0,Kb=0; //100欧
|
||||
if(k==1) Ka=0,Kb=1; //1k欧
|
||||
if(k==2) Ka=1,Kb=0; //10k欧
|
||||
if(k==3) Ka=1,Kb=1; //100k欧
|
||||
rng = k;
|
||||
}
|
||||
void setRng2(){ setRng( (rng+1)%4); } //量程步进
|
||||
|
||||
//==============增益控制函数====================
|
||||
char curGain=1; //当前增益索引号
|
||||
void setGain(char k){ //设置电路增益
|
||||
if(k>3) k=3;
|
||||
if(k<0) k=0;
|
||||
if(k==0) K4=0,K6=0; //1倍
|
||||
if(k==1) K4=0,K6=1; //3倍
|
||||
if(k==2) K4=1,K6=0; //10倍
|
||||
if(k==3) K4=1,K6=1; //30倍
|
||||
curGain = k;
|
||||
}
|
||||
void setGain2(){ setGain((curGain+1)%4); }
|
||||
|
||||
|
||||
//==============LCR测量====================
|
||||
xdata int Vxy[4]={0,0,0,0}; //Vxy[Vx1,Vy1,Vx2,Vy2]
|
||||
xdata char Sxw[4]={0,1,0,1}; //保存正确相位
|
||||
xdata char Vga[4]={1,1,1,1}; //上下臂增益记录表
|
||||
xdata uchar tim=0,tims=0;
|
||||
xdata char pau=0; //暂停坐标自动旋转
|
||||
#define Vfull 9600
|
||||
#define gad (9600/30)
|
||||
uchar mT = 6; //测量速度,mT取值为6或12或24时,可以消除数字噪声,尾数不动,但不利于于取平均
|
||||
//==============设置频率====================
|
||||
xdata char feqK=1; //频率索引号
|
||||
void setF(char k){
|
||||
if(k==-1){ //步进
|
||||
k = 0;
|
||||
if(feq==100) k=1;
|
||||
if(feq==1000) k=2;
|
||||
if(feq==7813) k=0;
|
||||
}
|
||||
feqK = k;
|
||||
if(k==0) { setDDS(100); K5=0; K8=1; mT=12; } //置为100Hz
|
||||
if(k==1) { setDDS(1000); K5=0; K8=0; mT=6; } //置为1kHz
|
||||
if(k==2) { setDDS(7813); K5=1; K8=0; mT=6; } //置为7.8125kHz
|
||||
TH1 = 47, TL1 = 171; //置为20ms
|
||||
tims = 0;
|
||||
tim = 0;
|
||||
ph = 0;
|
||||
}
|
||||
int absMax(int a,int b){ //取两个数绝对值最大者
|
||||
if(a<0) a = -a;
|
||||
if(b<0) b = -b;
|
||||
if(b>a) a = b;
|
||||
return a;
|
||||
}
|
||||
#define avn 4 //求平无个数
|
||||
xdata float vq[3][avn]; //数据缓存,用于求平均
|
||||
void LCRcalc(int *v,char *g){ //LCR计算
|
||||
code float ga[4] = { 1, 3, 9, 27 }; //增益表
|
||||
code float dwR[4] = { 20, 1e3, 1e4, 1e5 }; //各档电阻表
|
||||
xdata int g12 = (int)cs.g1+cs.g2; //增益最大补偿
|
||||
xdata int j12 = (int)cs.j1+cs.j2; //相位最大补偿
|
||||
xdata float JD = 0,cJD, G = 0; //补偿变量
|
||||
xdata float a,b,c,e;
|
||||
char i;
|
||||
a = +( 1.0*v[2]*v[2] + 1.0*v[3]*v[3] );
|
||||
b = -( 1.0*v[0]*v[2] + 1.0*v[1]*v[3] );
|
||||
c = -( 1.0*v[2]*v[1] - 1.0*v[0]*v[3] );
|
||||
a *= ga[g[0]] / ga[g[2]];
|
||||
a /= dwR[rng]*(1+cs.R[rng]/10000.0); //除以下臂电阻阻值
|
||||
|
||||
//可控增益单元的增益修正、相位补偿量
|
||||
if(g[0] == 1) JD += cs.j1, G += cs.g1;
|
||||
if(g[0] == 2) JD += cs.j2, G += cs.g2;
|
||||
if(g[0] == 3) JD += j12, G += g12;
|
||||
if(g[2] == 1) JD -= cs.j1, G -= cs.g1;
|
||||
if(g[2] == 2) JD -= cs.j2, G -= cs.g2;
|
||||
if(g[2] == 3) JD -= j12, G -= g12;
|
||||
JD -= cs.J[rng];
|
||||
JD *= feqX/7813/1000;
|
||||
cJD = 1 - JD*JD/2;
|
||||
a *= 1+G/10000; //增益补偿
|
||||
e = b*cJD - c*JD; //相位补偿
|
||||
c = b*JD + c*cJD; //相位补偿
|
||||
b = e;
|
||||
//入队
|
||||
for(i=1;i<avn;i++){
|
||||
vq[0][i] = vq[0][i-1];
|
||||
vq[1][i] = vq[1][i-1];
|
||||
vq[2][i] = vq[2][i-1];
|
||||
}
|
||||
vq[0][0]=a, vq[1][0]=b, vq[2][0]=c;
|
||||
}
|
||||
|
||||
void timerInter1(void) interrupt 3 {//T1中断,LCR数据采集
|
||||
char g; int c=0;
|
||||
tims++;
|
||||
if(tims>=mT) tims = 0, tim++, c = 1;
|
||||
if(tim>=4) tim=0;
|
||||
if(pau) return;
|
||||
if(c){ //tim进位触发
|
||||
c = getAD10(); //读取电压值
|
||||
c -= cs.zo[feqK];
|
||||
Vxy[tim] = xw<2 ? c : -c; //保存当前电压
|
||||
Vga[tim] = curGain; //保存当前增益
|
||||
Sxw[tim] += c<0 ? 2 : 0; //相位翻转(预测下次的相位采用值)
|
||||
Sxw[tim] %= 4;
|
||||
if(tim==1||tim==3){ //上下臂切换
|
||||
//电压模值才能反应运放的输出幅度,所以增益切换判断得用模值
|
||||
if(tim==1) K3=1, c = absMax(Vxy[2],Vxy[3]), g=Vga[2]; //切换到下臂
|
||||
if(tim==3) K3=0, c = absMax(Vxy[0],Vxy[1]), g=Vga[0]; //切换到上臂
|
||||
if(c>Vfull) g--;
|
||||
else if(c<gad*1 ) g += 3; //增加27倍
|
||||
else if(c<gad*3 ) g += 2; //增加9倍
|
||||
else if(c<gad*9) g++; //增加3倍
|
||||
setGain(g);
|
||||
}
|
||||
set90( Sxw[ (tim+1)%4 ] ); //相位旋转
|
||||
LCRcalc(Vxy,Vga);
|
||||
}
|
||||
}
|
||||
|
||||
void showR(char binLian){ //显示LCR
|
||||
char i;
|
||||
xdata float a=0,b=0,c=0,e,w;
|
||||
for(i=0;i<avn;i++)
|
||||
a += vq[0][i]/avn,
|
||||
b += vq[1][i]/avn,
|
||||
c += vq[2][i]/avn;
|
||||
|
||||
//电学量显示 if(!a) { lcd_cls(); lcd_puts("DIV 0"); return; }
|
||||
w = 2*3.1415926*feqX;
|
||||
lcd_goto2(0); //显示频率
|
||||
if(feq==100) lcd_putc('A');
|
||||
if(feq==1000) lcd_putc('B');
|
||||
if(feq==7813) lcd_putc('C');
|
||||
lcd_putc(rng+49); //显示量程
|
||||
if(binLian){ //并联
|
||||
e = (b*b+c*c)/a;
|
||||
lcd_goto1(0);
|
||||
lcd_puts("Zp");
|
||||
lcd_putf(e/b, 1, 1e-4); //显示并联复阻抗,显示到毫欧
|
||||
lcd_putf(e/c, 1, 1e-4); //显示并联复阻抗,显示到毫欧
|
||||
lcd_goto2(2);
|
||||
if(c<0) { lcd_putf(-c/e/w, 4, 1e-14); lcd_putc('F'); } //显示并联C值,显示到pF
|
||||
else { lcd_putf(+e/c/w, 2, 1e-8 ); lcd_putc('H'); } //显示并联L值,显示到uH
|
||||
}else{ //串联
|
||||
e = a;
|
||||
lcd_goto1(0);
|
||||
lcd_puts("Zs");
|
||||
lcd_putp(b/e, c/e, 1, 1, 1e-4); lcd_putc(244); //显示串联复阻抗,显示到毫欧
|
||||
lcd_goto2(2);
|
||||
if(c<0) { lcd_putf(-e/c/w, 4, 1e-14); lcd_putc('F'); } //显示C值,显示到pF
|
||||
else { lcd_putf(+c/e/w, 2, 1e-8 ); lcd_putc('H'); } //显示L值,显示到uH
|
||||
}
|
||||
if(b){ c = fabs(c/b); if(c>999) c=999; } //计算Q
|
||||
else c = 999;
|
||||
lcd_putf(c,0,0); //显示Q
|
||||
}
|
||||
//void timerInter(void) interrupt 1 {}//T0中断
|
||||
|
||||
main(){
|
||||
uchar i=0,kn=0,key=0;
|
||||
uchar dispN=0; //显示扫描索引
|
||||
uchar spkN=0; //蜂鸣器发声时长
|
||||
uint nn=0;
|
||||
uchar binLian=0;
|
||||
|
||||
lcd_init(); //初始化LCD
|
||||
lcd_cur0(); //隐藏光标
|
||||
lcd_puts("LCR 2.0");
|
||||
lcd_goto2(0);
|
||||
lcd_puts("XJW Putian,2011");
|
||||
delay2(80); //启动延时
|
||||
cs_RW(0); //读EEPROM
|
||||
|
||||
TCON=0, TMOD=0x12; //将T0置为自动重装定时器,T1置为定时器
|
||||
TH1 = 0, TL1 = 0;
|
||||
TR1=1; //T1开始计数
|
||||
TR0=0; //T0暂停计数
|
||||
ET1=1; //T1开中断
|
||||
ET0=1; //T1开中断
|
||||
EA=1; //开总中断
|
||||
PT0=1; //设置优先级
|
||||
|
||||
|
||||
set_channel(0); //设置AD转换通道
|
||||
P2M0 = 0xFF; //P2.01234567置为推勉输出
|
||||
P1M0 = 0xFC; //P1.234567置为推换口
|
||||
P1M1 = 0x03; //P1.0置为高阻抗
|
||||
P2 = 0x0F;
|
||||
|
||||
|
||||
|
||||
PWM_init();//DDS初始化
|
||||
set90(2); //初始设置相位
|
||||
setRng(1); //初始设置量程
|
||||
setGain(1); //初始设置增益
|
||||
setF(1); //DDS初始设置为1kHz
|
||||
|
||||
while(1){
|
||||
//显示disp
|
||||
nn++;
|
||||
//扫描键盘
|
||||
key = ~P3;
|
||||
if(key&&kn<255) kn++; else kn=0;
|
||||
for(i=0;key;i++) key/=2; key=i;
|
||||
if(kn==4) spkN=10; else key=0; //当按下一定时间后key才有效。spkN发声时长设置
|
||||
if(spkN) spkN--, spk=0; else spk=1; //键盘发声
|
||||
//菜单系统
|
||||
if(key==8){//菜单键
|
||||
lcd_cls(); lcd_puts("Menu: 1 LCR");
|
||||
lcd_goto2(0); lcd_puts("3 Test,7 Set");
|
||||
menu=0; key=0;
|
||||
}
|
||||
if(menu>=1 && menu<=4){
|
||||
if(key==7) setRng2(); //量程步进
|
||||
if(key==6) setF(-1); //设置频率
|
||||
}
|
||||
if(menu==0){ //显示量程和菜单
|
||||
if(key) lcd_cls();
|
||||
if(key>=1 && key<=7) menu = key, menu2 = 0;
|
||||
key = 0;
|
||||
}
|
||||
if(menu==1){ //LCR测量(串联)
|
||||
pau = 0;
|
||||
if(key==1) binLian = (binLian+1)%2; //串并联切换
|
||||
showR(binLian);
|
||||
}
|
||||
if(menu==2){
|
||||
lcd_goto1(0);
|
||||
lcd_puts("up:"); lcd_putc(Vga[0]+48);
|
||||
lcd_puts(" dw:"); lcd_putc(Vga[2]+48);
|
||||
}
|
||||
if(menu==3){ //手动调试
|
||||
pau = 1;
|
||||
if(key==1) setGain2();//增益控制
|
||||
if(key==2) { };
|
||||
if(key==3) K3=~K3; //切换上下臂
|
||||
if(key==4) set902(); //相位旋转
|
||||
lcd_goto1(0);
|
||||
lcd_puts(" xw="); lcd_putc(xw+48); //相位索引号
|
||||
lcd_puts(" K3="); lcd_putc(K3?49:48); //K3状态
|
||||
lcd_puts(" Ga="); lcd_putc(curGain+48); //增益索引号
|
||||
lcd_goto2(0);
|
||||
if(nn%32==0) lcd_int(getAD10(),5);
|
||||
}
|
||||
if(menu==7){ //设置零点偏移数
|
||||
code char *csR[15] = {
|
||||
"Z0 : 20", "Z1 : 20","Z2 : 20",
|
||||
"R1X: 20", "R2X: 1k", "R3X:10k", "R4X:.1M", "G1X:3k3", "G2X:10k",
|
||||
"R1 : 20", "R2 : 1k", "R3 :10k", "R4 :.1M", "G1 :3k3", "G2 :10k"};
|
||||
char *p,bc=1, feqD=1,rngD=1;
|
||||
static char kc=0, mo=0;
|
||||
if(menu2==0) p = cs.zo+0, feqD=0, rngD=2; //100Hz零点校准,接入10欧电阻
|
||||
if(menu2==1) p = cs.zo+1, feqD=1, rngD=2; //1kHz零点校准,接入10欧电阻
|
||||
if(menu2==2) p = cs.zo+2, feqD=2, rngD=2; //7.8kHz零点校准,接入10欧电阻
|
||||
if(menu2==3) p = cs.J+0, feqD=2, rngD=0; //VI变换器相位校准,接入20电阻
|
||||
if(menu2==4) p = cs.J+1, feqD=2, rngD=1; //VI变换器相位校准,接入1k电阻
|
||||
if(menu2==5) p = cs.J+2, feqD=2, rngD=2; //VI变换器相位校准,接入10k电阻
|
||||
if(menu2==6) p = cs.J+3, feqD=2, rngD=3; //VI变换器相位校准,接入100k电阻
|
||||
if(menu2==7) p = &cs.j1, feqD=2, rngD=1; //运放3倍档相位校准,接入3.3k欧电阻
|
||||
if(menu2==8) p = &cs.j2, feqD=2, rngD=1; //运放10倍档相位校准,接入10k欧电阻
|
||||
if(menu2==9) p = cs.R+0, bc=2, feqD=1, rngD=0; //VI变换器模值校准,接入20欧
|
||||
if(menu2==10) p = cs.R+1, bc=2, feqD=1, rngD=1; //VI变换器模值校准,接入1k欧
|
||||
if(menu2==11) p = cs.R+2, bc=2, feqD=1, rngD=2; //VI变换器模值校准,接入10k欧
|
||||
if(menu2==12) p = cs.R+3, bc=2, feqD=1, rngD=3; //VI变换器模值校准,接入100k欧
|
||||
if(menu2==13) p = &cs.g1, bc=2, feqD=1, rngD=1; //运放3倍增益校准,接入2k欧电阻
|
||||
if(menu2==14) p = &cs.g2, bc=2, feqD=1, rngD=1; //运放10倍增益校准,接入10k欧电阻
|
||||
if(key==1) *p += bc; //X键增
|
||||
if(key==2) *p -= bc; //R键减
|
||||
if(key==3) { cs_RW(1); setF(feqK); } //L键保存
|
||||
if(key==4) *p = 0; //C键清除
|
||||
if(key==5) { if(menu2==0) menu2=14; else menu2--; mo=0; }
|
||||
if(key==6) { if(menu2==14)menu2=0; else menu2++; mo=0; }
|
||||
if(key==7) mo = (mo+1)%2;
|
||||
if(key==4){ //恢复到默认值
|
||||
if(++kc==5){
|
||||
kc = 0;
|
||||
cs.j1 = 16, cs.j2 = 18;
|
||||
cs.g1 = 0, cs.g2 = 0;
|
||||
cs.zo[0] = 20;
|
||||
cs.zo[1] = 19;
|
||||
cs.zo[2] = 14;
|
||||
cs.J[0] = cs.J[1] = cs.J[2] = 0, cs.J[3] = 20;
|
||||
cs.R[0] = cs.R[1] = cs.R[2] = cs.R[3] = 0;
|
||||
}
|
||||
}
|
||||
else { if(key) kc=0; }
|
||||
//显示
|
||||
if(mo){
|
||||
if(feqD!=feqK) setF(feqD);
|
||||
if(rngD!=rng) setRng(rngD);
|
||||
showR(1);
|
||||
}else{
|
||||
lcd_cls();
|
||||
lcd_goto1(0);
|
||||
lcd_puts(csR[menu2]); //输出参数名称
|
||||
lcd_goto2(0);
|
||||
lcd_putf(*p,0,0);
|
||||
lcd_puts("X:+ R:-");
|
||||
}
|
||||
}
|
||||
delay(20000);
|
||||
}//while end
|
||||
}
|
||||
//==========================================================================
|
||||
|
576
led.c
Normal file
576
led.c
Normal file
@ -0,0 +1,576 @@
|
||||
/*************************************
|
||||
LCR表驱动程序 V1.0
|
||||
xjw01 于莆田 2011.10
|
||||
**************************************/
|
||||
//====================================
|
||||
#define uchar unsigned char
|
||||
#define uint unsigned int
|
||||
#define ulong unsigned long
|
||||
#include <reg52.h>
|
||||
#include <math.h>
|
||||
|
||||
void delay(uint loop) { uint i; for(i=0;i<loop;i++); } //延时函数
|
||||
void delay2(uint k){ for(;k>0;k--) delay(10000); } //长延时,k=100大约对应1秒
|
||||
|
||||
//========================AD转换=============================
|
||||
sfr P1ASF = 0x9D; //将P1置为模拟口寄存器(使能),各位中为1的有效
|
||||
sfr ADC_CONTR = 0xBC; //A/D转换控制寄存器
|
||||
sfr ADC_res = 0xBD; //A/D转换结果寄存器
|
||||
sfr ADC_resl = 0xBE; //A/D转换结果寄存器
|
||||
|
||||
void set_channel(char channel){
|
||||
P1ASF = 1<<channel;
|
||||
ADC_CONTR = channel+128; //最高位是电源开关,低3位通道选择
|
||||
delay(1); //首次打开电源应延迟,使输入稳定
|
||||
}
|
||||
uint getAD2(){
|
||||
ADC_CONTR |= 0x08; //00001000,置ADC_START=1启动A/D 转换
|
||||
while ( !(ADC_CONTR & 0x10) ); //等待A/D转换结束(ADC_FLAG==0)
|
||||
ADC_CONTR &= 0xE7; //11100111,置ADC_FLAG=0清除结束标记, 置ADC_START=0关闭A/D 转换
|
||||
return ADC_res*4 + ADC_resl;
|
||||
}
|
||||
/*
|
||||
uchar get_AD(){
|
||||
ADC_CONTR |= 0x08; //00001000,置ADC_START=1启动A/D 转换
|
||||
while( !(ADC_CONTR & 0x10) ); //等待A/D转换结束(ADC_FLAG==0)
|
||||
ADC_CONTR &= 0xE7; //11100111,置ADC_FLAG=0清除结束标记, 置ADC_START=0关闭A/D 转换
|
||||
return ADC_res;
|
||||
}
|
||||
*/
|
||||
uint getAD10() reentrant { //10次采样
|
||||
char i;
|
||||
uint c = 0;
|
||||
for(i=0;i<10;i++) c += getAD2();
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
//============================EEPROW偏程=========================
|
||||
sfr IAP_data = 0xC2;
|
||||
sfr IAP_addrH = 0xC3;
|
||||
sfr IAP_addrL = 0xC4;
|
||||
sfr IAP_cmd = 0xC5;
|
||||
sfr IAP_trig = 0xC6;
|
||||
sfr IAP_contr = 0xC7;
|
||||
/********************
|
||||
写字节时,可以将原有数据中的1改为0,无法将0改为1,只能使用擦除命令将0改为1
|
||||
应注意,擦除命令会将整个扇区擦除
|
||||
*********************/
|
||||
void saEEP(){ //EEP保护
|
||||
IAP_cmd = 0; //关闭令,保护
|
||||
IAP_contr = 0; //关EEPROM,保护
|
||||
IAP_trig = 0;
|
||||
IAP_addrL = 255; //设置读取地址的低字节,地址改变才需要设置
|
||||
IAP_addrH = 255; //设置读取地址的高字节,地址改变才需要设置
|
||||
}
|
||||
uchar readEEP(uint k){ //读取
|
||||
IAP_addrL = k; //设置读取地址的低字节,地址改变才需要设置
|
||||
IAP_addrH = k>>8; //设置读取地址的高字节,地址改变才需要设置
|
||||
IAP_contr = 0x81; //设置等待时间,1MHz以下取7,2M以下取6,3M取5,6M取4,12M取3,20M取2,24M取1,30M取0,前导1表示许档IAP
|
||||
IAP_cmd = 1; //读取值1,写取2,擦除取3,擦除时按所在字节整个扇区撺除
|
||||
IAP_trig = 0x5A; //先送5A
|
||||
IAP_trig = 0xA5; //先送5A再送A5立即触发
|
||||
saEEP(); //保护
|
||||
return IAP_data;
|
||||
}
|
||||
void writeEEP(uint k, uchar da){ //写入
|
||||
IAP_data = da; //传入数据
|
||||
IAP_addrL = k; //设置读取地址的低字节,地址改变才需要设置
|
||||
IAP_addrH = k>>8; //设置读取地址的高字节,地址改变才需要设置
|
||||
IAP_contr = 0x81; //设置等待时间,1MHz以下取7,2M以下取6,3M取5,6M取4,12M取3,20M取2,24M取1,30M取0,前导1表示许档IAP
|
||||
IAP_cmd = 2; //读取值1,写取2,擦除取3,擦除时按所在字节整个扇区撺除
|
||||
IAP_trig = 0x5A; //先送5A
|
||||
IAP_trig = 0xA5; //先送5A再送A5立即触发
|
||||
saEEP(); //保护
|
||||
}
|
||||
void eraseEEP(uint k){ //擦除
|
||||
IAP_addrL = k; //设置读取地址的低字节,地址改变才需要设置
|
||||
IAP_addrH = k>>8; //设置读取地址的高字节,地址改变才需要设置
|
||||
IAP_contr = 0x81; //设置等待时间,1MHz以下取7,2M以下取6,3M取5,6M取4,12M取3,20M取2,24M取1,30M取0,前导1表示许档IAP
|
||||
IAP_cmd = 3; //读取值1,写取2,擦除取3,擦除时按所在字节整个扇区撺除
|
||||
IAP_trig = 0x5A; //先送5A
|
||||
IAP_trig = 0xA5; //先送5A再送A5立即触发
|
||||
saEEP(); //保护
|
||||
}
|
||||
|
||||
xdata struct Ida{
|
||||
char zo[3];//三个频率下的零点改正值
|
||||
char j1; //相位补偿(3倍档)
|
||||
char j2; //相位补偿(10倍档)
|
||||
char J[4]; //相位补偿(V/I变换器)
|
||||
char R[4]; //下臂电阻修正(20,1k,10k,100k)
|
||||
char g1; //增益修正(3倍档)
|
||||
char g2; //增益修正(10倍档)
|
||||
} cs;
|
||||
|
||||
void cs_RW(char rw){
|
||||
uchar i,*p = &cs;
|
||||
if(rw){
|
||||
eraseEEP(0);
|
||||
for(i=0;i<sizeof(cs);i++) writeEEP(i,p[i]);
|
||||
}else{
|
||||
for(i=0;i<sizeof(cs);i++) p[i]=readEEP(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**********
|
||||
字形编码图
|
||||
32
|
||||
-
|
||||
64| | 128
|
||||
- 16
|
||||
1| | 8
|
||||
_. 4
|
||||
2
|
||||
**********/
|
||||
uchar code zk[20]={235,136,179,186,216,122,123,168,251,250, 59,201,2,18,50}; //字库,0-9,10,11,12,13,14
|
||||
uchar code zk2[8]={241,25,11,233,27,50,155,107};//p,n,u,m,0,k,M,G
|
||||
|
||||
uchar disp[6]={168,251,250}; char cx=-1; //显示缓存,cx光标位置
|
||||
sfr P1M1=0x91; //P1端口设置寄存器
|
||||
sfr P1M0=0x92; //P1端口设置寄存器
|
||||
sfr P0M1=0x93; //P0端口设置寄存器
|
||||
sfr P0M0=0x94; //P0端口设置寄存器
|
||||
sfr P2M1=0x95; //P2端口设置寄存器
|
||||
sfr P2M0=0x96; //P2端口设置寄存器
|
||||
sfr P3M1=0xB1; //P3端口设置寄存器
|
||||
sfr P3M0=0xB2; //P3端口设置寄存器
|
||||
|
||||
sbit ds3=P2^4; //数码管扫描口
|
||||
sbit ds2=P2^5; //数码管扫描口
|
||||
sbit ds1=P2^6; //数码管扫描口
|
||||
sbit ds0=P2^7; //数码管扫描口
|
||||
|
||||
sbit spk=P2^3; //蜂鸣器
|
||||
sbit Kb=P2^1; //量程开关B
|
||||
sbit Ka=P2^2; //量程开关A
|
||||
|
||||
sbit DDS2=P1^2;//移相方波输出口
|
||||
sbit K3=P1^7;
|
||||
sbit K4=P1^6;
|
||||
sbit K5=P1^5; //7.8kHz滤波开关
|
||||
sbit K6=P1^4;
|
||||
sbit K8=P2^0; //100Hz滤波开关
|
||||
|
||||
|
||||
|
||||
//==============字符显示函数====================
|
||||
xdata uchar menu=1,menu2=0;
|
||||
void cls(){ char i; for(i=0;i<6;i++) disp[i]=0; } //清屏
|
||||
void showDig(long f){ //显示数字
|
||||
uchar i;
|
||||
cls();
|
||||
for(i=0;i<6;i++) { disp[i]=zk[f%10], f/=10; if(!f) break; }
|
||||
}
|
||||
void showDig2(float f,char n,char dw){ //显示浮点数,nL是单位下限控制,如n=2时最小显示到u单位
|
||||
char i,b=0,b2=0,fh=0;
|
||||
if(f<0) fh=1,f=-f;
|
||||
for(i=0;i<3;i++){ if(f>=1000) f/=1000, b++; } //以3位为单位移动小数点,把大数转粉0至999,小数点在末字
|
||||
for(i=0;i<n;i++){ if(f<1) f*=1000, b--; } //以3位为单位移动小数点,把小数转粉0至999,小数点在末字
|
||||
for(i=0;i<3;i++){ if(f<1000) f*=10, b2++; } //对小于1000结果,连同小数点整体移位,使首位移到最左边
|
||||
showDig(f+10000); //加10000是为了补零
|
||||
disp[b2] += 4; //小数点
|
||||
if(!dw) return;
|
||||
disp[0] = zk2[b+4]; //显示单位
|
||||
if(fh) disp[0] += 4; //显示符号
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==============低频信号DDS====================
|
||||
//PCA相关寄存器
|
||||
sfr CMOD = 0xD9; //钟源选择控制等
|
||||
sfr CH = 0xF9; //PCA的计数器
|
||||
sfr CL = 0xE9; //PCA的计数器
|
||||
sfr CCON = 0xD8; //PCA控制寄存器
|
||||
sfr CCPAM0 = 0xDA; //PCA模块0工作模式寄存器
|
||||
sfr CCPAM1 = 0xDB; //PCA模块1工作模式寄存器
|
||||
sfr CCAP0L = 0xEA; //模块0捕获寄存器低位
|
||||
sfr CCAP0H = 0xFA; //模块0捕获寄存器高位
|
||||
|
||||
sbit PPCA = IP^7; //PCA的中断优先级设置
|
||||
sbit CCF0 = CCON^0; //PCA的模块0中断标志
|
||||
sbit CCF1 = CCON^1; //PCA的模块1中断标志
|
||||
sbit CR = CCON^6; //PCA计数器使能
|
||||
|
||||
void PWM_init(){ //把PCA置为PWM
|
||||
CMOD = 2; //0000 0010 计数源选择,钟源取fosc/2
|
||||
CL = CH = 0;
|
||||
CCAP0L = CCAP0H = 192; //占空比为25%
|
||||
//CCPAM0=0x42;//0100 0010,PCA的模块0设置为PWM模式,无中断
|
||||
CCPAM0=0x53;//0101 0011,PCA的模块0设置为PWM模式,有中断,下降沿中断
|
||||
PPCA = 1; //优先中断
|
||||
//CR = 1; //开始计数
|
||||
EA = 1; //开总中断
|
||||
}
|
||||
|
||||
uint ph=0, phM=256, feq=1000; //相位,phM相位步进值
|
||||
xdata float feqX=1000; //实际输出频率
|
||||
uchar code sinB[256]={
|
||||
//查询表中不可装载零值,否则会造成无中断产生
|
||||
255,255,255,255,255,255,254,254,253,252,252,251,250,249,248,247,246,245,243,242,240,239,237,236,234,232,230,229,227,225,222,220,
|
||||
218,216,214,211,209,206,204,201,199,196,194,191,188,185,183,180,177,174,171,168,165,162,159,156,153,150,147,144,140,137,134,131,
|
||||
128,125,122,119,116,112,109,106,103,100, 97, 94, 91, 88, 85, 82, 79, 76, 73, 71, 68, 65, 62, 60, 57, 55, 52, 50, 47, 45, 42, 40,
|
||||
38, 36, 34, 31, 29, 27, 26, 24, 22, 20, 19, 17, 16, 14, 13, 11, 10, 9, 8, 7, 6, 5, 4, 4, 3, 2, 2, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 16, 17, 19, 20, 22, 24, 26, 27, 29, 31, 34, 36,
|
||||
38, 40, 42, 45, 47, 50, 52, 55, 57, 60, 62, 65, 68, 71, 73, 76, 79, 82, 85, 88, 91, 94, 97,100,103,106,109,112,116,119,122,125,
|
||||
128,131,134,137,140,144,147,150,153,156,159,162,165,168,171,174,177,180,183,185,188,191,194,196,199,201,204,206,209,211,214,216,
|
||||
218,220,222,225,227,229,230,232,234,236,237,239,240,242,243,245,246,247,248,249,250,251,252,252,253,254,254,255,255,255,255,255
|
||||
};
|
||||
uchar code fbB[256]={ //方波DDS查询表
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
|
||||
};
|
||||
uchar chuX=0; //方波DDS初相
|
||||
void PCAinter(void) interrupt 7 {//PCA中断
|
||||
uchar x,y;
|
||||
CCF0=0; //清除中断请求,以免反复中断
|
||||
x = ph >> 8; //截断正弦相位累加器,取高8位
|
||||
y = x + chuX; //方波相位
|
||||
CCAP0H = sinB[x];//正弦DDS输出
|
||||
DDS2 = fbB[y]; //方波DDS输出
|
||||
ph += phM; //相位累加
|
||||
}
|
||||
void setDDS(uint f){ //参考时钟是c=(fosc/2)/256=32000000/2/256=62500,频率f=c*phM/2^16
|
||||
feq = f;
|
||||
phM=f*65536.0/62500; //phM=f*2^16/62500
|
||||
feqX = 62500.0*phM/65536; //实际输出频率
|
||||
ph = 0; //高频时,使波形对称
|
||||
if(!f) CR=0; else CR=1;
|
||||
}
|
||||
|
||||
//相位控制函数
|
||||
xdata char xw=0; //相位
|
||||
void set90(char k){ //设置方波的相位差
|
||||
k %= 4;
|
||||
if(k<0) k += 4;
|
||||
if(k==0) chuX=0; //移相0度
|
||||
if(k==1) chuX=64; //移相90度
|
||||
if(k==2) chuX=128; //移相180度
|
||||
if(k==3) chuX=192; //移相270度
|
||||
xw = k;
|
||||
}
|
||||
void set902() { set90(xw+1); } //相位步进
|
||||
|
||||
//==============量程控制函数====================
|
||||
xdata char rng=1; //量程
|
||||
void setRng(char k){//切换量程
|
||||
if(k==0) Ka=0,Kb=0; //100欧
|
||||
if(k==1) Ka=0,Kb=1; //1k欧
|
||||
if(k==2) Ka=1,Kb=0; //10k欧
|
||||
if(k==3) Ka=1,Kb=1; //100k欧
|
||||
rng = k;
|
||||
}
|
||||
void setRng2(){ setRng( (rng+1)%4); } //量程步进
|
||||
|
||||
//==============增益控制函数====================
|
||||
char curGain=1; //当前增益索引号
|
||||
void setGain(char k){ //设置电路增益
|
||||
if(k>3) k=3;
|
||||
if(k<0) k=0;
|
||||
if(k==0) K4=0,K6=0; //1倍
|
||||
if(k==1) K4=0,K6=1; //3倍
|
||||
if(k==2) K4=1,K6=0; //10倍
|
||||
if(k==3) K4=1,K6=1; //30倍
|
||||
curGain = k;
|
||||
}
|
||||
void setGain2(){ setGain((curGain+1)%4); }
|
||||
|
||||
|
||||
//==============LCR测量====================
|
||||
xdata int Vxy[4]={0,0,0,0}; //Vxy[Vx1,Vy1,Vx2,Vy2]
|
||||
xdata char Sxw[4]={0,1,0,1}; //保存正确相位
|
||||
xdata char Vga[4]={1,1,1,1}; //上下臂增益记录表
|
||||
xdata uchar tim=0,tims=0;
|
||||
xdata char pau=0; //暂停坐标自动旋转
|
||||
#define Vfull 9600
|
||||
#define gad (9600/30)
|
||||
uchar mT = 6; //测量速度
|
||||
//==============设置频率====================
|
||||
xdata char feqK=1; //频率索引号
|
||||
void setF(char k){
|
||||
if(k==-1){ //步进
|
||||
k = 0;
|
||||
if(feq==100) k=1;
|
||||
if(feq==1000) k=2;
|
||||
if(feq==7813) k=0;
|
||||
}
|
||||
if(k==0) { setDDS(100); K5=0; K8=1; mT=15; } //置为100Hz
|
||||
if(k==1) { setDDS(1000); K5=0; K8=0; mT=6; } //置为1kHz
|
||||
if(k==2) { setDDS(7813); K5=1; K8=0; mT=6; } //置为7.8125kHz
|
||||
feqK=k;
|
||||
TH1 = 47, TL1 = 171; //置为20ms
|
||||
tims = 0;
|
||||
tim = 0;
|
||||
ph = 0;
|
||||
}
|
||||
int absMax(int a,int b){ //取两个数绝对值最大者
|
||||
if(a<0) a = -a;
|
||||
if(b<0) b = -b;
|
||||
if(b>a) a = b;
|
||||
return a;
|
||||
}
|
||||
#define avn 4 //求平无个数
|
||||
xdata float vq[3][avn]; //数据缓存,用于求平均
|
||||
void LCRcalc(int *v,char *g){ //LCR计算
|
||||
code float ga[4] = { 1, 3, 9, 27 }; //增益表
|
||||
code float dwR[4] = { 20, 1e3, 1e4, 1e5 }; //各档电阻表
|
||||
xdata int g12 = (int)cs.g1+cs.g2; //增益最大补偿
|
||||
xdata int j12 = (int)cs.j1+cs.j2; //相位最大补偿
|
||||
xdata float JD = 0,cJD, G = 0; //补偿变量
|
||||
xdata float a,b,c,e;
|
||||
char i;
|
||||
a = +( 1.0*v[2]*v[2] + 1.0*v[3]*v[3] );
|
||||
b = -( 1.0*v[0]*v[2] + 1.0*v[1]*v[3] );
|
||||
c = -( 1.0*v[2]*v[1] - 1.0*v[0]*v[3] );
|
||||
a *= ga[g[0]] / ga[g[2]];
|
||||
a /= dwR[rng]*(1+cs.R[rng]/10000.0); //除以下臂电阻阻值
|
||||
|
||||
//可控增益单元的增益修正、相位补偿量
|
||||
if(g[0] == 1) JD += cs.j1, G += cs.g1;
|
||||
if(g[0] == 2) JD += cs.j2, G += cs.g2;
|
||||
if(g[0] == 3) JD += j12, G += g12;
|
||||
if(g[2] == 1) JD -= cs.j1, G -= cs.g1;
|
||||
if(g[2] == 2) JD -= cs.j2, G -= cs.g2;
|
||||
if(g[2] == 3) JD -= j12, G -= g12;
|
||||
JD -= cs.J[rng];
|
||||
JD *= feqX/7813/1000;
|
||||
cJD = 1 - JD*JD/2;
|
||||
a *= 1+G/10000; //增益补偿
|
||||
e = b*cJD - c*JD; //相位补偿
|
||||
c = b*JD + c*cJD; //相位补偿
|
||||
b = e;
|
||||
//入队
|
||||
for(i=1;i<avn;i++){
|
||||
vq[0][i] = vq[0][i-1];
|
||||
vq[1][i] = vq[1][i-1];
|
||||
vq[2][i] = vq[2][i-1];
|
||||
}
|
||||
vq[0][0]=a, vq[1][0]=b, vq[2][0]=c;
|
||||
}
|
||||
|
||||
void timerInter1(void) interrupt 3 {//T1中断
|
||||
char g; int c;
|
||||
if(pau) return;
|
||||
tims++;
|
||||
if(tims>=mT){ //tim进位触发
|
||||
tims = 0, tim++;
|
||||
if(tim>=4) tim=0;
|
||||
c = getAD10(); //读取电压值
|
||||
c -= cs.zo[feqK];
|
||||
Vxy[tim] = xw<2 ? c : -c; //保存当前电压
|
||||
Vga[tim] = curGain; //保存当前增益
|
||||
Sxw[tim] += c<0 ? 2 : 0; //相位翻转(预测下次的相位采用值)
|
||||
Sxw[tim] %= 4;
|
||||
if(tim==1||tim==3){ //上下臂切换
|
||||
//电压模值才能反应运放的输出幅度,所以增益切换判断得用模值
|
||||
if(tim==1) K3=1, c = absMax(Vxy[2],Vxy[3]), g=Vga[2]; //切换到下臂
|
||||
if(tim==3) K3=0, c = absMax(Vxy[0],Vxy[1]), g=Vga[0]; //切换到上臂
|
||||
if(c>Vfull) g--;
|
||||
else if(c<gad*1 ) g += 3; //增加27倍
|
||||
else if(c<gad*3 ) g += 2; //增加9倍
|
||||
else if(c<gad*9) g++; //增加3倍
|
||||
setGain(g);
|
||||
}
|
||||
set90( Sxw[ (tim+1)%4 ] ); //相位旋转
|
||||
LCRcalc(Vxy,Vga);
|
||||
}
|
||||
}
|
||||
|
||||
char sfdw=1; //是否显示单位
|
||||
void showR(char xm, char binLian){ //显示LCR
|
||||
char i;
|
||||
xdata float a=0,b=0,c=0,e,w;
|
||||
for(i=0;i<avn;i++)
|
||||
a += vq[0][i]/avn,
|
||||
b += vq[1][i]/avn,
|
||||
c += vq[2][i]/avn;
|
||||
|
||||
//电学量显示
|
||||
if(!a) { cls(); disp[3]=115;disp[2]=disp[1]=97; return; }
|
||||
w = 2*3.1415926*feqX;
|
||||
if(!binLian){ //串联
|
||||
e = a;
|
||||
if(xm==0){ showDig2(c/e,1, sfdw); }//显示X值,显示到毫欧
|
||||
if(xm==1){ showDig2(b/e,1, sfdw); }//显示R值,显示到毫欧
|
||||
if(xm==2){
|
||||
if(c<0) showDig2(e/c/w,4, sfdw); //显示C值,显示到pF
|
||||
else showDig2(c/e/w,2, sfdw); //显示L值,显示到uH
|
||||
}
|
||||
}else{ //并联
|
||||
e = (b*b+c*c)/a;
|
||||
if(xm==0){ showDig2(e/c,1, sfdw); }//显示并联X值,显示到毫欧
|
||||
if(xm==1){ showDig2(e/b,1, sfdw); }//显示并联R值,显示到毫欧
|
||||
if(xm==2){
|
||||
if(c<0) showDig2(c/e/w,4, sfdw);//显示并联C值,显示到pF
|
||||
else showDig2(e/c/w,2, sfdw);//显示并联L值,显示到uH
|
||||
}
|
||||
}
|
||||
if(xm==3){ //显示Q值
|
||||
if(!b) { showDig(9999); return; }
|
||||
c = fabs(c/b);
|
||||
if (c>=1000) { showDig(999 ); }
|
||||
else if(c>=100 ) { showDig(c ); }
|
||||
else if(c>=10 ) { showDig(c*10 ); disp[1] += 4; }
|
||||
else if(c>=1 ) { showDig(c*100 ); disp[2] += 4; }
|
||||
else { showDig(c*1000); disp[3] += 4; }
|
||||
}
|
||||
}
|
||||
//void timerInter(void) interrupt 1 {}//T0中断
|
||||
|
||||
void showMsg(uchar a){ //临时跳出信息
|
||||
P0 = ~a;
|
||||
ds0=1, ds1=ds2=ds3=0;
|
||||
delay2(50);
|
||||
}
|
||||
main(){
|
||||
uchar i=0,kn=0,key=0;
|
||||
uchar dispN=0; //显示扫描索引
|
||||
uchar spkN=0; //蜂鸣器发声时长
|
||||
uint nn=0;
|
||||
uchar XRQ=1;
|
||||
char binLian=0; //并联1,串联0
|
||||
|
||||
delay2(80); //启动延时
|
||||
cs_RW(0); //读EEPROM
|
||||
|
||||
TCON=0, TMOD=0x12; //将T0置为自动重装定时器,T1置为定时器
|
||||
TH1 = 0, TL1 = 0;
|
||||
TR1=1; //T1开始计数
|
||||
TR0=0; //T0暂停计数
|
||||
ET1=1; //T1开中断
|
||||
ET0=1; //T1开中断
|
||||
EA=1; //开总中断
|
||||
PT0=1; //设置优先级
|
||||
|
||||
|
||||
set_channel(0); //设置AD转换通道
|
||||
P2M0 = 0xFF; //P2.01234567置为推勉输出
|
||||
P1M0 = 0xFC; //P1.234567置为推换口
|
||||
P1M1 = 0x03; //P1.0置为高阻抗
|
||||
|
||||
//请注意启动延时0.5秒方可读取cs_RW
|
||||
//cs_RW(0); //读取比值基数(调零时已做开机延时,确保电压上升到可读取EEPROW)
|
||||
|
||||
PWM_init();//DDS初始化
|
||||
set90(2); //初始设置相位
|
||||
setRng(1); //初始设置量程
|
||||
setGain(1); //初始设置增益
|
||||
setF(1); //DDS初始设置为1kHz
|
||||
|
||||
while(1){
|
||||
//显示disp
|
||||
nn++;
|
||||
dispN=(++dispN)%4; //扫描器移动
|
||||
ds0=ds1=ds2=ds3=0;
|
||||
if(dispN==0) ds0=1;
|
||||
if(dispN==1) ds1=1;
|
||||
if(dispN==2) ds2=1;
|
||||
if(dispN==3) ds3=1;
|
||||
P0=~disp[dispN]; //显示
|
||||
//扫描键盘
|
||||
//键盘响应
|
||||
//key = (~P3)&0xfc;
|
||||
key = ~P3;
|
||||
if(key&&kn<255) kn++; else kn=0;
|
||||
for(i=0;key;i++) key/=2; key=i;
|
||||
if(kn==20) spkN=50; else key=0; //当按下一定时间后,key才有效,否则无效。spkN发声时长设置
|
||||
if(spkN) spkN--, spk=0; else spk=1; //键盘发声
|
||||
//菜单系统
|
||||
if(key==8) { menu=0; key=0; XRQ=-1;} //菜单键
|
||||
if(menu>=1&&menu<=4){
|
||||
if(key==7) setRng2(); //量程步进
|
||||
if(key==6) setF(-1); //设置频率
|
||||
}
|
||||
if(menu==0){ //显示量程和菜单
|
||||
showDig(10000);
|
||||
if(key>=1 && key<=7) menu = key, menu2 = 0;
|
||||
key = 0;
|
||||
}
|
||||
if(menu==1){ //自动LCR测量(串联)
|
||||
pau = 0;
|
||||
if(XRQ==-1) XRQ=1, sfdw=1;
|
||||
if(key==4) { //串并联切换
|
||||
if(binLian) { binLian=0; showMsg(122); } //转为串联
|
||||
else { binLian=1; showMsg(241); } //转为并联
|
||||
}
|
||||
if(key==1) { if(XRQ==0) sfdw++; else sfdw=1; XRQ = 0; }
|
||||
if(key==2) { if(XRQ==1) sfdw++; else sfdw=1; XRQ = 1; }
|
||||
if(key==3) { if(XRQ==2) sfdw++; else sfdw=1; XRQ = 2; }
|
||||
if(key==5) XRQ = 3;
|
||||
sfdw %= 2;
|
||||
showR(XRQ,binLian);
|
||||
if(binLian && nn%512<50) { for(i=0;i<4;i++) disp[i] |= 4; }
|
||||
}
|
||||
if(menu==2){ //显示增益档位
|
||||
showDig(Vga[0]*100+Vga[2]+10000);
|
||||
disp[1]=disp[3]=0;
|
||||
}
|
||||
if(menu==3){ //手动调试
|
||||
pau = 1;
|
||||
if(key==1) { setGain2(); showMsg( zk[curGain] );} //增益控制
|
||||
if(key==2) { };
|
||||
if(key==3) { K3=~K3; showMsg(zk[K3]); } //切换上下臂
|
||||
if(key==4) { set902(); showMsg(zk[xw]); } //相位旋转
|
||||
if(nn%64==0) { showDig( getAD10()); disp[1]+=4; }
|
||||
}
|
||||
if(menu==7){ //设置零点偏移数
|
||||
char *p,bc=1, feqD=1,rngD=1;
|
||||
static char kc=0, mo=0;
|
||||
if(menu2==0) p = cs.zo+0, feqD=0, rngD=2; //100Hz零点校准,接入10欧电阻
|
||||
if(menu2==1) p = cs.zo+1, feqD=1, rngD=2; //1kHz零点校准,接入10欧电阻
|
||||
if(menu2==2) p = cs.zo+2, feqD=2, rngD=2; //7.8kHz零点校准,接入10欧电阻
|
||||
if(menu2==3) p = cs.J+0, feqD=2, rngD=0; //VI变换器相位校准,接入20电阻
|
||||
if(menu2==4) p = cs.J+1, feqD=2, rngD=1; //VI变换器相位校准,接入1k电阻
|
||||
if(menu2==5) p = cs.J+2, feqD=2, rngD=2; //VI变换器相位校准,接入10k电阻
|
||||
if(menu2==6) p = cs.J+3, feqD=2, rngD=3; //VI变换器相位校准,接入100k电阻
|
||||
if(menu2==7) p = &cs.j1, feqD=2, rngD=1; //运放3倍档相位校准,接入3.3k电阻
|
||||
if(menu2==8) p = &cs.j2, feqD=2, rngD=1; //运放10倍档相位校准,接入10k电阻
|
||||
if(menu2==9) p = cs.R+0, bc=2, feqD=1, rngD=0; //VI变换器模值校准,接入20欧
|
||||
if(menu2==10) p = cs.R+1, bc=2, feqD=1, rngD=1; //VI变换器模值校准,接入1k欧
|
||||
if(menu2==11) p = cs.R+2, bc=2, feqD=1, rngD=2; //VI变换器模值校准,接入10k欧
|
||||
if(menu2==12) p = cs.R+3, bc=2, feqD=1, rngD=3; //VI变换器模值校准,接入100k欧
|
||||
if(menu2==13) p = &cs.g1, bc=2, feqD=1, rngD=1; //运放3倍增益校准,接入2k欧电阻
|
||||
if(menu2==14) p = &cs.g2, bc=2, feqD=1, rngD=1; //运放10倍增益校准,接入10k欧电阻
|
||||
if(key==1) *p += bc; //X键增
|
||||
if(key==2) *p -= bc; //R键减
|
||||
if(key==3) { cs_RW(1); setF(feqK); } //L键保存
|
||||
if(key==4) *p = 0; //C键清除
|
||||
if(key==5) { if(menu2==0) menu2=14; else menu2--; mo=0; showMsg(menu2<9?zk[menu2]:zk[menu2-6]+4); }
|
||||
if(key==6) { if(menu2==14)menu2=0; else menu2++; mo=0; showMsg(menu2<9?zk[menu2]:zk[menu2-6]+4); }
|
||||
if(key==7) mo = (mo+1)%2;
|
||||
if(key==4){ //恢复到默认值
|
||||
if(++kc==5){
|
||||
kc = 0;
|
||||
cs.j1 = 16, cs.j2 = 18;
|
||||
cs.g1 = 0, cs.g2 = 0;
|
||||
cs.zo[0] = 15;
|
||||
cs.zo[1] = 17;
|
||||
cs.zo[2] = 15;
|
||||
cs.J[0] = cs.J[1] = cs.J[2] = 0, cs.J[3] = 20;
|
||||
cs.R[0] = cs.R[1] = cs.R[2] = cs.R[3] = 0;
|
||||
}
|
||||
}
|
||||
else { if(key) kc=0; }
|
||||
if(mo){
|
||||
if(feqD!=feqK) setF(feqD);
|
||||
if(rngD!=rng) setRng(rngD);
|
||||
if(menu2>=3 && menu2<=8) showR(3,1); //显示Q
|
||||
else showR(1,1); //显示电阻
|
||||
}else{
|
||||
sfdw = 0;
|
||||
showDig(abs(*p));
|
||||
if(*p<0) disp[3] = 16;
|
||||
}
|
||||
}
|
||||
delay(4000);
|
||||
}//while end
|
||||
}
|
||||
|
||||
|
781
uu1602.hex
Normal file
781
uu1602.hex
Normal file
@ -0,0 +1,781 @@
|
||||
:102050005A70005A73004C435220322E3000584AB6
|
||||
:10206000572050757469616E2C32303131004D65E6
|
||||
:102070006E753A202031204C435200332054657352
|
||||
:10208000742C37205365740075703A002064773AD9
|
||||
:10209000002078773D00204B333D002047613D0014
|
||||
:1020A0005A30203A203230005A31203A2032300063
|
||||
:1020B0005A32203A203230005231583A2032300021
|
||||
:1020C0005232583A20316B005233583A31306B005B
|
||||
:1020D0005234583A2E314D004731583A336B330061
|
||||
:1020E0004732583A31306B005231203A20323000BA
|
||||
:1020F0005232203A20316B005233203A31306B009B
|
||||
:102100005234203A2E314D004731203A336B3300A0
|
||||
:102110004732203A31306B00583A2B20523A2D008A
|
||||
:10212000706E756D6F6B4D47202B2020202020FF97
|
||||
:10213000FFFFFFFFFFFEFEFDFCFCFBFAF9F8F7F6E0
|
||||
:10214000F5F3F2F0EFEDECEAE8E6E5E3E1DEDCDA08
|
||||
:10215000D8D6D3D1CECCC9C7C4C2BFBCB9B7B4B12D
|
||||
:10216000AEABA8A5A29F9C999693908C89868380FC
|
||||
:102170007D7A7774706D6A6764615E5B5855524F03
|
||||
:102180004C494744413E3C393734322F2D2A2826CA
|
||||
:1021900024221F1D1B1A1816141311100E0D0B0AE2
|
||||
:1021A00009080706050404030202010101010101F7
|
||||
:1021B0000101010101020203040405060708090ADE
|
||||
:1021C0000B0D0E1011131416181A1B1D1F22242696
|
||||
:1021D000282A2D2F323437393C3E414447494C4F51
|
||||
:1021E0005255585B5E6164676A6D7074777A7D8062
|
||||
:1021F0008386898C909396999C9FA2A5A8ABAEB13B
|
||||
:10220000B4B7B9BCBFC2C4C7C9CCCED1D3D6D8DA53
|
||||
:10221000DCDEE1E3E5E6E8EAECEDEFF0F2F3F5F61B
|
||||
:10222000F7F8F9FAFBFCFCFDFEFEFFFFFFFFFF00E5
|
||||
:10223000000000000000000000000000000000009E
|
||||
:10224000000000000000000000000000000000008E
|
||||
:10225000000000000000000000000000000000007E
|
||||
:10226000000000000000000000000000000000006E
|
||||
:10227000000000000000000000000000000000005E
|
||||
:10228000000000000000000000000000000000004E
|
||||