📄 ad.c
字号:
/*
The file is used to convert adc for uC pic16f688
There are two functions:
int ADC(void) :Convert adc and return a result
void Arith_AD(void) :Get atithmetic value each ad channel
*/
#include <htc.h>
#include <pic16f688.h>
#include "AD.H"
#include "IntServ.h"
#include "Type.h"
//extern ADCs adc[5];
extern int VP_I,VP_U,PMC_I,PMC_U;
char ADC_Chn[5]={2,4,5,6,7}; //Each channel AD locate register ADCON0
//unsigned int adc[5];
int adc[5]; //Store 5AD value
bit bShortCurrent; //set flag when short current
//bit bSC_first; //test delay time of short current
/*
void Switch_ADC_Ch(void)
{
//ADCON1=0x30; //x11 = FRC,system internal clock about 500khz
ADCON0 = (Num_ADC << 2) + 0x81; //AN4,RIGHT ALIGN; enable ADC, RC osc.
}
//INI AD2
*/
int ADC(void)
{ int data16=0;
GODONE = 1; //start convert
while(GODONE);
; // wait for conversion complete
ADIF=0;
data16=ADRESH&0x3; //high 2bit bin
data16=(data16<<8)|ADRESL; //low byte
return(data16);
}
void Arith_AD(void)
{
// int sum=0;
int sum[5];
unsigned char Num_ADC;
char i=0,j=0,k=0,m=0; //m: sample times to relative channel
int max1=0,max2=0,min1=1023,min2=1023,tmp=0,tmp1=0,tmp2=0;
// int n=0;
int n=3000;
while(n--){;} //must at least delay 3000*2us=6ms before sampling adc until power supply stable
// if(bSC_first)
// {
// n=30000;bSC_first=0;
// while(n--){;}
// }////test delay time of short current
for(i=0;i<5;i++)
{ sum[i]=0;
}
m=10; //10 times sample
for(j=0;j<m;j++)
{
for(i=0;i<5;i++)
{
Num_ADC=ADC_Chn[i];
//ADCON0 = (Num_ADC << 2) + 0x81; //Switch_ADC_Ch();
Num_ADC=Num_ADC << 2;
ADCON0 = Num_ADC + 0x81;
k=10; //must at least delay 10*2us=20us
while(k--){;}
if(i>1)
{
sum[i]=sum[i]+ADC();//Get adc value and sum if not AD1 AND AD2
}
else
{
if(!i)
{ tmp1=ADC(); // adc1 value
}
else if(i==1)
{
tmp2=ADC(); //adc2 value
tmp=tmp1-tmp2; //Diff=AD1-AD2
if(tmp<0) tmp=0;//Diff=0 if Diff<0;
if(tmp > max1)
{
max2 = max1;
max1 = tmp;
} else if (tmp > max2)
{
max2 = tmp;
} //Find out two max values
if(tmp < min1)
{
min2 = min1;
min1 = tmp;
} else if(tmp < min2)
{
min2 = tmp;
} //Find out two min values
sum[i]=sum[i]+tmp; //Sum all 10 Diffs
}
}
}
}
for(i=1;i<5;i++)//sum[0] is not available
{
if(i>1)
{ adc[i]=sum[i]/m; //Sum if not AD1 AND AD2
}
else
{
sum[i]=sum[i]-max2-max1-min2-min1; //SUM EXCEPT TWO MAX AND TWO MIN
adc[i]=sum[i]/(m-4); //AVERAGE
}
}
VP_I=adc[2-1];
if(VP_I<4) //See VP_I=0 WHEN VP_I<4; (4 means around AD1-AD2=40mV)
VP_I=0;
else if(VP_I>=150) //See VP_I TOO BIG AS SHORT CURRENT WHEN VP_I>=150;(150 means around AD1-AD2=1.5V)
bShortCurrent=1; //set short current flag
VP_U=adc[5-1];
if(VP_U<154) //See VP_U=0 when external device offers voltage smaller than 3.75V voltage(around 154*5mV*5=3.75V)
VP_U=0;
PMC_I=adc[3-1];
if(PMC_I<=8) //See PMC_I=0 when external device offers 40mV
PMC_I=0;
PMC_U=adc[4-1];
// if(PMC_U<50) PMC_U=0;
}
/*
void Arith_AD(void)
{
int sum=0;
char i=0,j=0,k=0,m=0; //m: sample times to relative channel
// int n=0;
char Num_ADC=0;
int n=50000;
while(n--){;} //delay several hundreds ms before sampling adc
for(i=0;i<5;i++) //may improve to swich channel after continue to sample 3times one channel
{
Num_ADC=ADC_Chn[i];
//ADCON0 = (Num_ADC << 2) + 0x81; //Switch_ADC_Ch();
Num_ADC=Num_ADC << 2;
ADCON0 = Num_ADC + 0x81;
if(i==0 || i==1)
m=10;
else m=5;
for(j=0;j<m;j++)
{
k=200; //200*2us=400us
while(k--){;}
sum=sum+ADC();//;//delay(50);ValAverage
// adc[i].ValAD[j]=ADC();
// sum=sum+adc[i].ValAD[j];
}
adc[i]=sum/m;
sum=0;
} //VP_I=0;VP_U=0;PMC_I=0;PMC_U=0;
VP_I=adc[1-1]-adc[2-1];
if(VP_I<4)
VP_I=0; //up limith??
VP_U=adc[5-1];
if(VP_U<154)
VP_U=0;
PMC_I=adc[3-1];
if(PMC_I<=8)
PMC_I=0;
PMC_U=adc[4-1];
// if(PMC_U<50) PMC_U=0;
}
// TO test short current :VP:I
void Arith_AD(void)
{
int sum=0;
char i=0,j=0,k=0,m=0; //m: sample times to relative channel
for(i=0;i<2;i++) //may improve to swich channel after continue to sample 3times one channel
{
Num_ADC=ADC_Chn[i];
//ADCON0 = (Num_ADC << 2) + 0x81; //Switch_ADC_Ch();
Num_ADC=Num_ADC << 2;
ADCON0 = Num_ADC + 0x81;
if(i==0 || i==1)
m=10;
else m=5;
for(j=0;j<m;j++)
{
// k=200; //200*2us=400us
// while(k--){;}
sum=sum+ADC();//;//delay(50);ValAverage
// adc[i].ValAD[j]=ADC();
// sum=sum+adc[i].ValAD[j];
}
adc[i]=sum/m;
sum=0;
} //2*10*400us=8ms each time
VP_I=adc[1-1]-adc[2-1];
if(VP_I<100)
VP_I=0; //up limith??
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -