|
/*************************************
5位半ICL7135驱动程序
使用32MHz晶振,单片机STC12C5AS60
P1.0接7135的时钟脚
P1.1接7135的正负半断脚
p1.2接7135的溢出识别脚
P3.2接7135的BUSY脚
读数未减去零点值。约12字。
xjw01 于莆田 2011.6
**************************************/
//====================================
#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秒
/**********
字形编码图
32
-
64| | 128
- 16
1| | 8
_. 4
2
**********/
uchar code zk[20]={235,136,179,186,216,122,123,168,251,250}; //字库
uchar disp[6]={168,251,250,186,179,136};
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 ds0=P2^2; //数码管扫描口
sbit ds1=P2^3; //数码管扫描口
sbit ds2=P2^4; //数码管扫描口
sbit ds3=P2^5; //数码管扫描口
sbit ds4=P2^6; //数码管扫描口
sbit ds5=P2^7; //数码管扫描口
sbit plo=P1^1; //正负输入口
sbit ORg=P1^2; //溢出识别口
//功能程序开始
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; }
}
#define fso 32000000 // 时钟频率
#define bp 10 //倍频数
#define bk 320 //计数速度比(时钟速度比),需是2*bp的倍数
#define en 3 //电压加权平均个数
uchar tr0 = 256 - bk/2; //常速时钟的定时器初值
uchar tr1 = 256 - bk/(2*bp); //倍速时钟的定时器初值
sfr WAKE_CLKO = 0x8F;
sfr AUXR = 0x8E; //定时器1T模式设置相关的寄存器
sfr BRT = 0x9C;
long na=0,n0=1e9,pv=0;
void zd0(void) interrupt 0 {//int0中断(下降沿)
const long M0 = 10000L*bk; //7135反向积分开始点对应的单片机计数值
long v; //电压
uint x = 220; //倍频延迟(采用测量值减去2)
BRT = tr0; //降低频率
na += TH0*256+TL0; //积分计数数器的累计值
if(x){ //电压测量
//显示测量电压
v = 100000.0*(na-M0)/M0; //V值计算
if(abs(v-pv/en)>5) pv = v*en;
else pv = v + pv - pv/en;
v = pv/en;
if(v<0 ) v = 0;
if(v>10) v -= 10; //零点非线处理
showDig(v);
if(!plo) disp[5]+=16; //显示正负号
//预置下一次积分的倍频时间点
n0 = na - 5*bk; //设置在过零之前5字
if(n0<M0) n0 = M0; //确保倍频点设置在反积分期间
n0 -= x; //延迟量补偿,确保零点处也能正常倍频
//溢出处理
if(ORg){
cls(); disp[5]=zk[1]; //显示溢出标识
n0 = 3*M0;
}
}else{ //延迟量测量
showDig(na-n0 - (30002L*bk-na)/(bp-1));
n0 = M0;
}
//计数器初值设定
v = 65536 - n0%65536;
na=0, TH0 = v/256, TL0 = v%256;
}
void timerInter(void) interrupt 1 {//T0中断
if(na) na += 65536;
else na += n0%65536;
if(na==n0) BRT = tr1; //升高频率
}
main(){
uchar dispN=0; //显示扫描索引
TCON=0, TMOD=0x09; //将T0置为16位内部计数,并由外部启动计数。
IT0=1; //使int0下降沿中断有效。
TH0=0, TL0=0;
TR0=1; //T0启动计数
EX0=1; //开int0外部中断
ET0=1; //T0开中断
EA=1; //开总中断
PT0=1; //中断优先
//时钟输出
AUXR |= 0x80; //T0置为1T模式
AUXR |= 0x04; //独立波特率发生器工作在1T模式
BRT = tr0;
WAKE_CLKO |= 0x07;
AUXR |= 0x10; //启动波特率发生器开始计数
P2M0 = 0xFC; //P2.234567置为推勉输出
P1M0 = 0x01; //P1.0置为推勉输出
//P1M1 = 0x02; //P1.1置为高阻抗
//P3M0 = 0x0C; //P3.23置为推勉输出口
while(1){
//显示disp
dispN=(++dispN)%6; //扫描器移动
ds0=ds1=ds2=ds3=ds4=ds5=0;
if(dispN==0) ds0=1;
if(dispN==1) ds1=1;
if(dispN==2) ds2=1;
if(dispN==3) ds3=1;
if(dispN==4) ds4=1;
if(dispN==5) ds5=1;
P0=~disp[dispN]; //显示
delay(4000);
}//while end
} |
评分
-
5
查看全部评分
-
|