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

📄 ad.c

📁 用PIC18F2580完成A/D采集,CAN总线数据读取
💻 C
字号:
#include"includes.h"

unsigned int Adresult = 0;
unsigned int Ad_Sample_result = 0;
/**
******************************************************************************************

***名  称: void delaynms(unsigned int n)
***功  能:ms延时函数
***版  本: V0.1
***作  者: LiWei
***日  期:2008年06月25日
------------------------------------------------------------------------------------------
---修改人:
---日  期:
---功  能:

******************************************************************************************
**/
void delaynms(unsigned int n)                           //延时1mS
{
    unsigned int i;
    while(n>0)
    {
        for(i=0;i<112;i++)
        {}
        n--;
    }
}
/**
******************************************************************************************

***名  称: unsigned int AD_Deal(void)
***功  能:A/D处理函数
***版  本: V0.1
***作  者: LiWei
***日  期:2008年06月25日
------------------------------------------------------------------------------------------
---修改人:
---日  期:
---功  能:

******************************************************************************************
**/
unsigned int AD_Deal(void)
{
	unsigned int temp,vol;
    unsigned int ADH,ADL;
    ADH = ADRESH;
    ADL = ADRESL;
	Ad_Sample_result = (ADH<<8)|ADL;
   
    //Adresult = (Ad_Sample_result*50)>>10;

    //temp = Adresult;

	//Adresult = (((Adresult%10)<<4))|(((temp/10)<<8)&0xF00);
	//vol = Adresult;
    //return vol;
	return Ad_Sample_result; 
}
/**
******************************************************************************************

***名  称: unsigned int AD_Colect(void)
***功  能:A/D函数
***版  本: V0.1
***作  者: LiWei
***日  期:2008年06月25日
------------------------------------------------------------------------------------------
---修改人:
---日  期:
---功  能:

******************************************************************************************
**/
unsigned int AD_Colect(unsigned char ChannelSet)
{
    unsigned char Channel;
    unsigned int ADRES;   
    unsigned int ADH,ADL; 
    Channel = ChannelSet; 
	//ADCON1 = 0x0E;                         
    ADCON1bits.VCFG0 = 0;				   /*参考电压Vss  Vdd                */
    ADCON1bits.VCFG1 = 0;
    if(Channel == 0)                       //TEMPERATURE0
	{
	    ADCON1bits.PCFG0 = 0;			   /*把RA0设置为模拟量输入           */
		ADCON1bits.PCFG1 = 1;
		ADCON1bits.PCFG2 = 1;
		ADCON1bits.PCFG3 = 1;
		ADCON0 = 0x00;                     /*选择通道为 AN0                  */
	}
    if(Channel == 1)                       //TEMPERATURE1
	{
	    ADCON1bits.PCFG0 = 1;			   /*把RA1设置为模拟量输入           */
		ADCON1bits.PCFG1 = 0;
		ADCON1bits.PCFG2 = 1;
		ADCON1bits.PCFG3 = 1;
		ADCON0 = 0x04;                     /*选择通道为 AN1                  */
	}
    if(Channel == 2)                       //TEMPERATURE2
	{
	    ADCON1bits.PCFG0 = 0;			   /*把RA2设置为模拟量输入           */
		ADCON1bits.PCFG1 = 0;
		ADCON1bits.PCFG2 = 1;
		ADCON1bits.PCFG3 = 1;
		ADCON0 = 0x08;                     /*选择通道为 AN2                  */
	}
    if(Channel == 4)
	{
	    ADCON1bits.PCFG0 = 0;			   /*把RA4设置为模拟量输入           */
		ADCON1bits.PCFG1 = 1;
		ADCON1bits.PCFG2 = 0;
		ADCON1bits.PCFG3 = 1;
		ADCON0 = 0x10;                     /*选择通道为 AN4                  */
	}
	//ADCON2 = 0xA0; 
	//Delay100TCYx(10);                        
    ADCON2bits.ADFM  = 1;				   /*转换结果右对齐                  */
    ADCON2bits.ADCS0 = 0;				   /*转换时钟为32Tosc                */
	ADCON2bits.ADCS1 = 1;
	ADCON2bits.ADCS2 = 0;
    ADCON2bits.ACQT2 = 1;				   /*A/D采集时间8Tad                 */
	ADCON0bits.ADON  = 1;				   /*使能A/D                         */ 
    Delay100TCYx(20);                      /*等待采集所需时间                */
	ADCON0bits.GO_DONE = 1;				   /*启动A/D                         */
    while(ADCON0bits.GO_DONE);             /*等待A/D空闲                     */
    //ADRES = AD_Deal();
    ADH = ADRESH;
    ADL = ADRESL;
	ADRES = (ADH<<8)|ADL; 
    return ADRES; 
}
/**
******************************************************************************************

***名  称: void SetChannel(unsigned char chnum)
***功  能:电压采集通道选择
***版  本: V0.1
***作  者: LiWei
***日  期:2008年07月15日
------------------------------------------------------------------------------------------
---修改人:
---日  期:
---功  能:

******************************************************************************************
**/
void SetChannel(unsigned char chnum)      //chnum:channel number
{
    switch (chnum)
    {
        case 0 :
        {
            A12 = 0;                  //选通U9-138译码器
            A11 = 0;				  //E1
            A10 = 0;				  //选中第1路电池 A10
            A9  = 0;				  //A9
		    A8  = 0;				  //A8
            //delaynms(1000);         //从第一通U9道切换时间比其他通道切换时间长1S
        }break;
        case 1:
        {
            A12 = 0;                  //选通U9-138译码器
            A11 = 0;				  //E1
            A10 = 0;				  //选中第2路电池 A10
            A9 = 0;				      //A9
		    A8 = 1;				      //A8
        }break;
        case 2:
        {
            A12 = 0;                  //选通U9-138译码器
            A11 = 0;				  //E1
            A10 = 0;				  //选中第3路电池 A10
            A9  = 1;				  //A9
		    A8  = 0;				  //A8
        }break;
        case 3 :
        {
            A12 = 0;                  //选通U9-138译码器
            A11 = 0;				  //E1
            A10 = 0;				  //选中第4路电池 A10
            A9  = 1;				  //A9
		    A8  = 1;				  //A8
        }break;
        case 4:
        {
            A12 = 0;                  //选通U9-138译码器
            A11 = 0;				  //E1
            A10 = 1;				  //选中第5路电池 A10
            A9 = 0;				      //A9
		    A8 = 0;				      //A8
        }break;
        case 5:
        {
            A12 = 0;                  //选通U9-138译码器
            A11 = 0;				  //E1
            A10 = 1;				  //选中第6路电池 A10
            A8 = 0;				      //A9
		    A9 = 1;				      //A8
        }break;
        case 6 :
        {
            A12 = 0;                  //选通U9-138译码器
            A11 = 0;				  //E1
            A10 = 1;				  //选中第7路电池 A10
            A9 = 1;				      //A9
		    A8 = 0;				      //A8
        }break;
        case 7:
        {
            A12 = 0;                  //选通U9-138译码器
            A11 = 0;				  //E1
            A10 = 1;				  //选中第8路电池 A10
            A9 = 1;				      //A9
		    A8 = 1;				      //A8
        }break;
        case 8:                       //选通U10-138译码器
        {
            A12 = 0;                  //选通U10-138译码器
            A11 = 1;				  //E3
            A10 = 0;				  //选中第1路电池
            A9 = 0;				      //A9
		    A8 = 0;				      //A8
        }break;
        case 9 :
        {
            A12 = 0;                  //选通U10-138译码器
            A11 = 1;				  //E3
            A10 = 0;				  //选中第2路电池
            A9 = 0;				      //A9
		    A8 = 1;				      //A8
        }break;
        case 10:
        {
            A12 = 0;               	  //选通U10-138译码器
            A11 = 1;				  //E3
            A10 = 0;				  //选中第3路电池
            A9 = 1;				  	  //A9
		    A8 = 0;				  	  //A8
        }break;
        case 11:
        {
            A12 = 0;                  //选通U10-138译码器
            A11 = 1;				  //E3
            A10 = 0;				  //选中第4路电池
            A9 = 1;				      //A9
		    A8 = 1;				      //A8
        }break;
        case 12 :
        {
            A12 = 0;                  //选通U10-138译码器
            A11 = 1;				  //E3
            A10 = 1;				  //选中第5路电池
            A9 = 0;				      //A9
		    A8 = 0;				      //A8
        }break;
        case 13:
        {
            A12 = 0;                  //选通U10-138译码器
            A11 = 1;				  //E3
            A10 = 1;				  //选中第6路电池
            A9 = 0;				      //A9
		    A8 = 1;				  	  //A8
        }break;
        case 14:
        {
            A12 = 0;                  //选通U10-138译码器
            A11 = 1;				  //E3
            A10 = 1;				  //选中第7路电池
            A9 = 1;				      //A9
		    A8 = 0;				      //A8
        }break;
        case 15 :
        {
            A12 = 0;                  //选通U10-138译码器
            A11 = 1;				  //E3
            A10 = 1;				  //选中第8路电池
            A9 = 1;				      //A9
		    A8 = 1;				      //A8
        }break;
        default: break;
    }//end switch
}
/**
******************************************************************************************

***名  称: unsigned int ADUser(void)
***功  能:A/D函数
***版  本: V0.1
***作  者: LiWei
***日  期:2008年06月25日
------------------------------------------------------------------------------------------
---修改人:
---日  期:
---功  能:

******************************************************************************************
**/
unsigned int ADUserV(unsigned char ChannelSet)
{
	unsigned char i,j,k;
	unsigned long AD_result;
	unsigned int Vtemp[8],t;
    for(i=0;i<15;i++)
	{
    	SetChannel(i);
        if(i == 0)Delay1KTCYx(2400);
        else Delay1KTCYx(150);
        for(j=0;j<8;j++)
        {
		   AD_result = AD_Colect(ChannelSet);
		   Vtemp[j]  = (unsigned int)(AD_result);
		}
		for(j = 0;j < 7;j++)
		{
			for(k = 0;k < 6-j;k++)
			{
	            if(Vtemp[k] > Vtemp[k+1])
	            {
	                t = Vtemp[k]; Vtemp[k] = Vtemp[k+1];Vtemp[k+1] = t;
	            }
	        }
		}
		AD_result = 0;
		for(j = 3;j < 7;j++)
		{
			AD_result += Vtemp[j]; 	
		}
	    AD_result/= 4;	
		AD_result = AD_result*5000;
		AD_result = AD_result/1024; 
		AD_result = AD_result*2;
		//AD_result*= C_K_VOL;        //单支电池电压系数
		AD_result*= 9457;
		AD_result/= 10000; 
	    Cell[i]   = (unsigned int)(AD_result);
		Delay1KTCYx(10);
	}
}
/**
******************************************************************************************

***名  称: unsigned int ADUserT(void)
***功  能:A/D函数
***版  本: V0.1
***作  者: LiWei
***日  期:2008年06月25日
------------------------------------------------------------------------------------------
---修改人:
---日  期:
---功  能:

******************************************************************************************
**/
unsigned int ADUserT(unsigned char ChannelSet)
{
	unsigned char i,j;//,CH;
    unsigned int  t,Current;
    signed int TEMPT;
    unsigned long R,Yout,ADResult_T,Temperature;
    //float Yout,R,T;
    signed long T;
    //CH = ChannelSet;
    for(i = 0;i < 8;i++)
	{
		ADResult_T = AD_Colect(ChannelSet);
        Temp[i]    = (unsigned int)(ADResult_T);
    }
	for(i = 0;i < 7;i++)
	{
		for(j = 0;j < 6-i;j++)
		{
            if(Temp[j] > Temp[j+1])
            {
                t = Temp[j]; Temp[j] = Temp[j+1];Temp[j+1] = t;
            }
        }
	}
    ADResult_T = 0;
    for(i = 3; i < 7;i++)
    {
		ADResult_T += Temp[i];
    }
    ADResult_T  /= 4;
	ADResult_T  *= 5000;
    ADResult_T  /= 1024;
    if(ChannelSet == 0)
    {	
		ADResult_T    *= T_K_VO1;                  //1点温度系数
		ADResult_T    /= 10000;
    	Tempervoltage0 = (unsigned int)(ADResult_T);
    }
    if(ChannelSet == 1)
    {
		ADResult_T    *= T_K_VO2;                  //2点温度系数
		ADResult_T    /= 10000;	    
    	Tempervoltage1 = (unsigned int)(ADResult_T);
    }
    Temperature  = ADResult_T;
    //Temperature *= 11366;                              //较准系数
    //Temperature /= 10000;
    ADResult_T   = 5000 - Temperature;
    Current      = (unsigned int)(ADResult_T*10/100);  //扩大10倍计算出电流值 100表示100K电阻
    R            = Temperature*10000;
    R            = R/Current;                          //R/Current/1000;
    if(R > 181385) //小于-30度    
    {
		T = -30;    
    }
	else if(R > 32851)   //小于零度 0 ~ -30
		 {
		     Yout         = 1000000000/(1000+0.0169*R);        //将结果扩大到小数点后六位
		     T            = Yout - 647275;                       
		     T            = T/1344;                            //温度取三位整数 		
		 }
		 else if(R > 8052)           //小于30度 0 ~ +30
		      {
			 	  Yout = 1000000000/(1000+0.082*R);      //将结果扩大到小数点后六位
				  T    = Yout - 268487;                  
				  T    = T/1120;                                
		      }
		      else if(R > 2488)      //小于60度  +30 ~ +60
		           {
				 	   Yout = 1000000000/(1000+0.305*R); //将结果扩大到小数点后六位
					   T    = Yout - 9671;                
					   T    = T/940;                     //温度取三位整数  		          
		           }
		           else if(R > 920)  //小于90度    +60 ~ +90
		                {
					 	    Yout = 1000000000/(1000+0.928*R); 
						    T    = Yout + 176081;                
						    T    = T/796;                     //温度取三位整数 		                
		                }
		                else T = 90;                   //高于100度
//    Yout         = 1000000000/(1000+0.082*R);        //将结果扩大到小数点后六位
//    T            = Yout;
//    T            = T - 268487;                       //T - 0.268487;
//    T            = T/112;                            //T/0.00011207;温度取四位整数按此屏蔽计算 
    TEMPT  = (signed int)(T);
    return TEMPT;
}
/******************************************************************************
										End
******************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -