?? 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 + -