ADC的初始化如果没设置好,对于整个系统是有很大的影响的,首先就是拖慢采集速度。
再有就是没打开通道没有检测。那直接看710的ADC初始化代码来理解吧
还有一个ADC一直没去关注的问题,就是转换时钟,可能这就是我们有时候采不准的问题吧。
A/D在10位模式下需要12个时钟周期(12TAD),在12位模式下需要14个时钟周期(14TAD)
A/D共有256个可能的TAD选项,由ADC转换时钟位ADCS<7:0>(ADxCON3<7:0>)指定。下面是TAD值与ADCS控制位以及器件指令周期Tcy之间的关系。
TAD = Tcy(ADCS + 1)
ADCS = TAD/Tcy - 1
为了获得正确的A/D转换结果,必须选择A/D转换时钟,以确保75ns的最小TAD时间。ADC有一个专用内部RC时钟源。
主要就是选择了内部时钟(ADRC=1),就不需要选择ADCS位。如果选择了指令时钟那TAD = Tcy,详细配置在下图了,也没有说明这个,就这样认为了。
- 要用的引脚需要先设置为输入。
- 27 AD1PCFGH=0XFFFF; //选择AN0引脚作为模拟输入
28 AD1PCFGL=0XFFF0; 这两个寄存器设置需要注意,0为模拟输入,所以你要多个采集的话就要把那几位置零了 - AD1CSSL=0X0001; //对AN0进行扫描, 还有就是这个寄存器的设置了。对哪几个扫描
- 其他的不用纠结,就那样没问题
1 /************************************************************ 2 **FileName: ADC.c 3 **Author: cm Version : V1.0 Date: 2017-4-16 4 **Chip: dsPIC33FJ256GP710 5 **Description: ADC 6 ** 工作频率FCY=40M 7 ** 使用外部XT 应定义XT_PLL 8 **Function List: 9 ** 10 ***********************************************************/ 11 #include "ADC.h" 12 #include "Delay.h" 13 #define N 7 14 void Init_ADC() 15 { 16 _TRISB0=1; //端口引脚定义 17 _TRISB1=1; 18 _TRISB2=1; 19 _TRISB3=1; 20 _TRISA9=1; 21 _TRISA10=1; 22 AD1CON1bits.ADON=0; //禁止ADC 23 AD1CON1bits.AD12B=0; //选择10位模式 24 AD1CON2bits.VCFG=0B011; //参考电压选择外部Vref+和外部Vref- 25 AD1CON3bits.ADCS=0X02; //选择了内部时钟后来设置转换时间的,见上面贴的图片 26 AD1CON3bits.ADRC=0; //1为选择内部时钟,0为系统时钟 27 AD1PCFGH=0XFFFF; //选择AN0引脚作为模拟输入 28 AD1PCFGL=0XFFF0; 29 AD1CHS0=0X0000; //确定如何将输入分配给采样保持通道 30 AD1CON2bits.CHPS=0B00; //使用的通道为CH0 31 AD1CON1bits.SIMSAM=0; //按顺序依次单独采样多个通道中每个通道 32 AD1CSSL=0X0003; //对AN0进行扫描 33 AD1CON1bits.SAMP=0; //手动采样 34 AD1CON1bits.FORM=0B00; //缓冲区的存储方式输出格式为整数 35 AD1CON4=0X0004; //给每个模拟输入分配16字的缓冲区 36 AD1CON1bits.ADON=1; //开启ADC 37 } 38 39 unsigned int ADC(unsigned int input) 40 { 41 static unsigned int AD=0; 42 AD1CHS0=input; 43 AD1CON1bits.SAMP=1; //收到采样 44 DelayUs(1); //延时等待 45 AD1CON1bits.SAMP=0; //开始装换 46 while(!AD1CON1bits.DONE); 47 AD=ADC1BUF0; //取值 48 return AD; 49 } 50 51 unsigned int filter(unsigned int ANx) 52 { 53 unsigned int sum,AD_value,i; 54 for(i=0;i<20;i++) 55 { 56 sum=ADC(ANx)+sum; 57 } 58 AD_value=sum/20; 59 sum=0; 60 return AD_value; 61 } 62 63 unsigned int filter1(unsigned int ANx) 64 { 65 66 unsigned int AD_temp; 67 unsigned int value_buf[N]; 68 unsigned char count,i,j; 69 for ( count=0;count<N;count++) 70 { 71 value_buf[count]=ADC(ANx); 72 DelayMs(1); 73 } 74 for (j=0;j<N-1;j++) 75 { 76 for (i=0;i<N-j;i++) 77 { 78 if ( value_buf[i]>value_buf[i+1] ) 79 { 80 AD_temp = value_buf[i]; 81 value_buf[i]= value_buf[i+1]; 82 value_buf[i+1] = AD_temp; 83 } 84 } 85 } 86 return value_buf[(N-1)/2]; 87 } 88 unsigned int filter2(unsigned int ANx) 89 { 90 unsigned int sum,AD_value,i; 91 for(i=0;i<5;i++) 92 { 93 sum=filter1(ANx)+sum; 94 } 95 AD_value=sum/5; 96 sum=0; 97 return AD_value; 98 }