📄 5ptwendu1.c
字号:
/****************************************************************************************************************************
FILE NAME: THREEVOLTAGE.C
AUTHOR: HU HONG BO
DATE: 2008.3.6
FUNCTION: 将AD7708配置成5个差分通道,用前5个通道,测量五路电压-20~100度,并在LED上显示
*****************************************************************************************************************************/
#include<reg52.h>
#include<math.h>
#define LED_SEG P2 //段码控制
#define LED_BIT P0 //位控制
unsigned char code table[13]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6,0x9e,0x02,0x00};//字形表0~9,E,- ,灭
idata unsigned int time=0;//软件计时
idata unsigned int period=1000;//1秒计时
data unsigned char CHnum=1;//通道号
data unsigned char Vcode[7]={0,0,0,0,0,0,0};//待显示的数字存储数组,第一个和第二个是通道号或函数标志,第三个空,后4个是电压量的有效数字
data unsigned char Dis_dat[7]={0x00,0x00,0x00,0x00,0x00,0x00,0x00};//待显示的数字的字形,初值全灭
bit EA_f;//用以保存EA状态
bit nopt;//空操作位
bit T2ms=1;//2毫秒计时
bit opAD_flag=1;//是否操作AD7708标志
bit rdAD=0;//是否读取AD转换结果标志
bit v2c_flag=0;//是否需要刷新换显示内容
bit disp_flag=0;//0为循环显示,1为单通道显示
sbit CS=P1^3;//cs of AD7708
sbit DIN=P1^1;//data in of AD7708
sbit DOUT=P1^2;//data out of AD7708
sbit DRDY=P3^2;//ready of AD7708
sbit SCLOCK=P3^3;//clock of AD7708
void delay(unsigned int );//延时函数
void writetoreg(unsigned char);//写AD7708寄存器函数
float readAD(void);//读AD7708转换结果函数
void opAD(void);//操作AD7708函数
void disbyte(void);//显示函数
void single_disp(void);//单通道显示
void circle_disp(void);//循环显示
float AD2V(float);//AD值转换为浮点数电压量
void V2CODE(float);//浮点数转换到显示缓存数组
void clock0_init() reentrant using 0//计时器0初始化函数
{
TCON=0x00;
TR0=0;
TH0=0xFC;
TL0=0x18;//1ms作为基准定时,用模式1,这样1s需要1000个定时过程
TR0=1;
}
void main() //主函数
{
data float ADresult=0.0;
data float Voltage=0.0;
TMOD=0x01; //定时器0模式1,
TH0=0xFC; //T0定时1ms初始值
TL0=0x18;
ET0=1;//打开定时器0中断允许
EA=1;//开总中断
TR0=1;//开定时器0
while(1)
{
if(opAD_flag){EA_f=EA;EA=0;opAD_flag=0;opAD();EA=EA_f;}//如果操作AD标志为1则去处理AD
if(rdAD){
EA_f=EA;
EA=0;
ADresult=readAD(); //读取AD转换结果
EA=EA_f;
rdAD=0;
v2c_flag=1; //刷新显示标志置位
}
if(v2c_flag){
EA_f=EA;
EA=0;
Voltage=AD2V(ADresult);
V2CODE(Voltage);
EA=EA_f;
v2c_flag=0;
}
}
}
/*操作AD7708函数*/
void opAD()
{
data int tim;
data unsigned char adcon; //adcon配置AD7708的ADCON寄存器
tim=1000;
/* PRECONFIGURE...*/
DRDY=1;
while(tim--);
SCLOCK=1;
DIN=1;
DOUT=1;
CS=1;
writetoreg(0x03); //write to communication register. The next step is writing to FILTER REGISTER
writetoreg(0x45); //set the FILTER register
switch(CHnum)//根据通道号,计算ADCON的CH5 CH4 CH3 CH2 CH1 CH0值,
{ case 1: adcon=0x87; break;
case 2: adcon=0x97; break;
case 3: adcon=0xa7; break;
case 4: adcon=0xb7; break;
case 5: adcon=0xc7; break;
} //确保1~5通道的adcon分别为0x8f,0x9f,0xaf,0xbf,0xcf输入范围为0~+2.56
writetoreg(0x02); //write to communication register. The next step is writing to ADC CONTROLO register
writetoreg(adcon); //Unipolar,
writetoreg(0x01);//writing to communication register, the next step is write to MODE register
writetoreg(0x13);//chopping,REFIN1,10 pseudo-differential input,continuous conversion mode
while(DRDY);
rdAD=1;
}
/*写AD7708寄存器*/
void writetoreg(unsigned char byteword) //The subroutine write byteword to the corresponding registers of AD7708
{
data unsigned char temp,i;
CS=0;
temp=0x80;
for(i=0;i<8;i++)
{
if((temp&byteword)==0)
DIN=0;
else DIN=1;
SCLOCK=0;
SCLOCK=1;
temp=temp>>1;
}
CS=1;
}
/*读AD7708转换结果*/
float readAD()
{
data unsigned char j;
data float temp=0.0;
//while(DRDY);//wating for finishing converting
writetoreg(0x44);//write to communication register.The next step is reading data from ADC Data register
CS=0;
for(j=0;j<16;j++)
{
SCLOCK=0;
SCLOCK=1;
if(DOUT==1) temp+=pow(2,15-j);
}
CS=1;
return(temp);
}
/*根据转换公式把AD转换结果转换为电压量*/
float AD2V(float ADresult)
{
ADresult=ADresult/32768-1;
ADresult=ADresult*2.56;
return(ADresult); //输入范围配置成0~+2.56时候,增益为1
}
/*显示*/
void disbyte()
{
data unsigned char i;
for(i=0;i<7;i++)
{
LED_BIT=(0x40>>i); //P0位选,选通第N个数码管7654321的顺序,P0.6~P0.0
LED_SEG=Dis_dat[i];//从P2口输出字形码
delay(5);
}
LED_SEG=0x00;//全灭
}
/*循环显示控制*/
void circle_disp()
{
CHnum++;
if(CHnum>5) CHnum=1;
opAD_flag=1;
}
/*单通道显示控制*/
void single_disp()
{
}
/*浮点数转换到显示缓存数组*/
void V2CODE(float value)
{
data int Vtemp;
data unsigned int i;
data unsigned char DotId;//DotId记录小数点位置
//EA=0;
Vcode[0]=CHnum;//通道号
if(value<0) {Vcode[1]=11;value=-1*value;}//加负号“ -”并取其绝对值
else Vcode[1]=12;//正数,符号位灭
if(value<1.0) {DotId=3; Vtemp=(int)(value*1000);}
else {
for(i=1;i<3;i++)
if(value<pow(10,i))
{
Vtemp=(int)(value*pow(10,4-i));
DotId=i+2;
break;
}
}
for(i=6;i>2;i--)
{
Vcode[i]=Vtemp%10;
Vtemp=Vtemp/10;
}
for(i=0;i<7;i++)
{
Dis_dat[i]=table[Vcode[i]]; //转换成字形并放入DiCATDAT[]数组
if(i==DotId) {Dis_dat[i]|=0xFD;}//加小数点
}
//EA=1;
}
/*延时*/
void delay(unsigned int time)
{
data unsigned char i;
EA_f=EA;//保存当前EA状态
EA=0; //软件延时的时候关中断
while(time--)
{
for(i=0;i<20;i++) {;}
}
EA=EA_f;
}
/*定时器0中断处理*/
void clk0_int(void) interrupt 1 using 0
{
T2ms=!T2ms;
if(T2ms) disbyte();//2ms显示一次
if(++time==period) //1秒时间到
{
if(disp_flag) single_disp();
else circle_disp();
time=0;//重新开始计数
}
clock0_init();//初始化定时器
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -