www.pudn.com > dsPIC33_CDROM.rar > AD1.c, change:2013-10-22,size:3181b


//例10.1 
/*采用手动方式时行ADC转换,12位,通过定时器每隔100us做一次ADC转换 
一个输入模拟通道为AN8,做6次转换后中断,去掉最高和最小值,剩下的4个采样值平均 
直接在接于RB中的数码管上显示出来 
*/ 
#include "P33FJ32GP204.H" 
//禁止时钟切换,禁止引脚多次配置,振荡引脚,主振荡器为XT 
_FOSC(FCKSM_CSDCMD & IOL1WAY_ON & OSCIOFNC_OFF & POSCMD_XT) 
//使用用户设定的振荡器启动,初始振荡器为带PLL的主(XT,HS或EC)振荡器 
_FOSCSEL(IESO_OFF & FNOSC_PRIPLL); 
_FICD(JTAGEN_OFF & ICS_PGD1); 
#define P1 _LATC0 
#define P2 _LATC1 
void __attribute__((__interrupt__, auto_psv)) _T1Interrupt(void); 
void __attribute__((__interrupt__, auto_psv)) _ADC1Interrupt(void); 
 
int main(void) 
{	//外接4MHz晶振,通过PLL得到总振荡频率80MHz,Fcy=40MHz,Tcy=25ns 
	CLKDIVbits.PLLPRE=0;	// N1=2,此输出为4/2=2MHz,符合0.8MHz~8.0MHz的要求  
	PLLFBDbits.PLLDIV=78; 	// M=80,此输出为2×80≈160MHz,符合100MHz~200MHz的要求 
	CLKDIVbits.PLLPOST=0;	// N2=2,此输出为160/2=80MHz,符合12.5MHz~80MHz的要求 
	while(OSCCONbits.COSC != 0b011);	//等待时钟稳定 
	RCONbits.SWDTEN=0;	//禁止WDT 
	 
	TRISB=0;			//RB口全为输出 
	_PCFG8=0;			//RC2/AN8为模拟输入 
	_TRISC2=1;			//RC2/AN8为输入脚 
	_PCFG6=1;			//RC0/AN6为数字输出 
	_TRISC0=0;			//RC0/AN6为输出脚	 
	_PCFG7=1;			//RC1/AN7为数字输出 
	_TRISC1=0;			//RC1/AN7为输出脚		 
  //AD1CON1设置,未设置位按默认值,下同	 
	_AD12B=1;		//12位 
	_FORM=0b00;		//整数格式 
	_SSRC=0b000;	//手动方式启动ADC转换 
	_ASAM=0;		//对SAMP位置1结束开始采样 
  //AD1CON2设置 
  	_VCFG=0b000;	//ADC参考电压为AVDD和AVSS即电源电压 
  	_CSCNA=0;		//不扫描 
  	_SMPI=5;		//6次AD转换产生一次中断 
  	_BUFM=1;		//第一次从0开始填充缓冲器,第2次从8开始填充缓冲器 
  	_ALTS=0;		//只用A开关 
   //AD1CON3设置 
   	_ADRC=0;		//系统时钟作为ADC时钟 
   	_ADCS=4;		//TAD=5×TCY=125ns>117.6ns 
   //AD1CHS0设置 
   	_CH0NA=0;		//模拟电压负端输入接VRFEF-即地 
   	_CH0SA=8;		//模拟电压正端输入接AN8 
  //TMR1设置 
  	T1CON=0x0000;	//1:1分频 
  	PR1=3999;		//延时100us 
  	TMR1=0; 
  	_T1IF=0; 
  	_T1IE=1; 
  	_T1IP=7; 
  	_AD1IF=0; 
  	_AD1IE=1; 
  	_AD1IP=6; 
  	 
  	_IPL=4;		//CPU中断优先级为4 
	_IPL3=0;		//CPU中断优先级≤7 
	_NSTDIS=1;		//禁止嵌套中断 
	_ALTIVT=0;		//使用标准中断向量 
  	T1CONbits.TON=1;	//启动定时器 
  	AD1CON1bits.ADON=1;//启动ADC模块 
  	PORTB=0; 
  	P1=1; 
  	P2=1; 
  	 
	while(1); 
	return(0);	 
} 
 
void __attribute__((__interrupt__, auto_psv)) _T1Interrupt(void) 
{	_T1IF=0; 
	P1=~P1; 
	_SAMP=1;		//采样开始 
	Nop();Nop();Nop();Nop();Nop();	//等待>3TAD的采样时间 
	Nop();Nop();Nop();Nop();Nop(); 
	Nop();Nop();Nop();Nop();Nop(); 
	_SAMP=0;		//结束采样,开始ADC转换,理论上为14TAD=1.75us转换结束 
} 
 
void __attribute__((__interrupt__, auto_psv)) _ADC1Interrupt(void) 
{	unsigned int AD_MAX,AD_MIN,AD[6],AD1; 
	unsigned long AD_SUM; 
	unsigned char i; 
	volatile unsigned int *P; 
	P2=~P2; 
	_AD1IF=0; 
	if (_BUFS==0)		 
		P=&ADC1BUF8;		//当前缓冲器在0-7,故要从AD1BUF8开始读 
	else 
		P=&ADC1BUF0;		//当前缓冲器在8-F,故要从AD1BUF0开始读 
	AD_SUM=0;AD_MAX=0;AD_MIN=0xFFFF; 
	for (i=0;i<6;i++) 
	{	AD[i]=*P;		//读AD缓冲区的内容 
		AD_SUM+=AD[i]; 
		if (AD[i]>AD_MAX) AD_MAX=AD[i]; 
		if (AD[i]<AD_MIN) AD_MIN=AD[i]; 
		P++;		 
	} 
	AD_SUM-=AD_MAX; 
	AD_SUM-=AD_MIN; 
	AD1=AD_SUM>>2; 
	PORTB=AD1; 
}