A/D转换器采用10 位逐次逼近的A/D转换方式,由电容耦合放大器构成。
模拟输入管脚和P1_0~ P1_3 管脚共用。【4个通道】
在使用这些输入管脚时,必须将对应的端口方向位置“0”(输入模式)。
另外,在不使用A/D 转换器时,如果将ADCON1 寄存器的VCUT 位置“0”(不连接Vref),从VREF 管脚到梯形电阻就没有电流通过,能降低功耗。
A/D 转换的结果被保存到AD 寄存器。
· 无采样保持功能
在分辨率为8 位时,为49 个fAD 周期;在分辨率为10 位时,为59 个fAD 周期
· 有采样保持功能
在分辨率为8 位时,为28 个fAD 周期;在分辨率为10 位时,为33 个fAD 周期
A/D 转换方式逐次逼近方式(电容耦合放大器)
模拟输入电压(注1) 0V ~ AVCC
运行时钟fAD (注2) 在4.2V ≤ AVCC ≤ 5.5V 时, f1、f2、f4
在2.7V ≤ AVCC < 4.2V 时, f2、f4
分辨率能选择8 位或者10 位
绝对精度在AVCC=Vref=5V 时
· 在分辨率为8 位时, ±2LSB
· 在分辨率为10 位时, ±3LSB
在AVCC=Vref=3.3V 时
· 在分辨率为8 位时, ±2LSB
· 在分辨率为10 位时, ±5LSB
运行模式单次模式、重复模式
模拟输入管脚4 个(AN8 ~ AN11)
A/D 转换开始条件· 软件触发
将ADCON0 寄存器的ADST 位置“1”(开始A/D 转换)
· 捕捉
在ADST 位为“1”的状态下发生定时器Z 中断请求
【A/D 转换器的使用注意事项】
· 对ADCON0 寄存器的各位(bit6 除外)、ADCON1 寄存器的各位以及ADCON2 寄存器的SMP 位的
写操作,必须在A/D 转换停止时(发生触发前)进行。
尤其在将VCUT 位从“0”(未连接VREF)置为“1”(连接VREF)时,必须在至少经过1μs 后开
始A/D 转换。
· 在改变A/D 运行模式后,必须重新选择模拟输入管脚。
· 在单次模式使用时
必须在确认A/D 转换结束后,读AD 寄存器(能通过ADIC 寄存器的IR 位或者ADCON0 寄存器的
ADST 位判断A/D 转换的结束)。
· 在重复模式使用时
对于CPU 时钟,不能分频主时钟。
· 在A/D 转换运行期间,当通过程序将ADCON0 寄存器的ADST 位置“0”(停止A/D 转换)来强制
结束时, A/D 转换器的转换结果不定。在通过程序将ADST 位置“0”的情况下,不能使用AD 寄存
器的值。
针对学习板的例程:
/************************************************************************
*函数原型: Read_Self_AD
*功能 : 读AD,输入通道号,输出AD值
************************************************************************/
unsigned int Read_Self_AD(unsigned char ANx)
{
unsigned int i;
switch(ANx)
{
case 8: {pd1_0=0;adcon0=0b10010100;break;}
case 9: {pd1_1=0;adcon0=0b10010101;break;}
case 10:{pd1_2=0;adcon0=0b10010110;break;}
case 11:{pd1_3=0;adcon0=0b10010111;break;}
default:break;
}
adcon1 = 0x00;
bits=0; //8位模式
adcon2 = 0; //无采样保持
vcut = 1; //Vref连接
adst = 1; //开始转换
while(adst);
i = ad;
vcut = 0; //断开Vref
return(i);
}
附带程序:滤波程序,采集N次,去极值,平均
/************************************************************************
*函数原型: Get_AD_Filter
*功能 : AD滤波
*输入:AD通道编号
*输出:滤波后AD值
*调用函数:unsigned int Read_Self_AD(unsigned char ANx)
************************************************************************/
#define FILTERDEEP 10
unsigned int Get_AD_Filter(unsigned char anx)
{
unsigned int value_buf[FILTERDEEP],temp;
unsigned char count,i,j;
unsigned long sum;
for (count=0;count<FILTERDEEP;count++)
{
value_buf[count]=Read_Self_AD(anx); //获取采样值
}
for (j=0;j<FILTERDEEP-1;j++) //采样值由小到大排列,排序采用冒泡法
{
for (i=0;i<FILTERDEEP-j;i++)
{
if(value_buf>value_buf[i+1])
{
temp=value_buf;
value_buf=value_buf[i+1];
value_buf[i+1]=temp;
}
}
}
sum=0;
for(count=1;count<(FILTERDEEP-1);count++) //去掉第一个和末一个数
{
sum=sum+value_buf[count];
}
sum=sum/(FILTERDEEP-2);
return((unsigned int)sum);
}
文章评论(0条评论)
登录后参与讨论