⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ad.c

📁 Universal cable, USB和RJ45头的Universal电缆的固件代码
💻 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 + -