个通道,它的基本时钟由APB时钟提供,它还包含一个可编程的分频器,可以将APB时钟调整为主次逼近转换所需的时钟(最大可达13MHz)。与ADC相关的引脚配置包括功能配置也即配置引脚功能选择寄存器PINSEL,一般ADC是第二功能,这次实验的电路连接的是ADC0.2通道所以要把P0.25配置成ADC功能,即PINCON->PINSEL1 |= (1<18);。还要把电源参考引脚连接上参考电源一般是接3V或与VCC电压相等。与ADC相关的寄存器包括:
1、外围器接口电源管理寄存器PCONP,要把这个寄存器的第12位即PCADC位置位,这一位是ADC的电源控制与时钟控制位。
2、A/D控制寄存器ADCR,主要是控制ADC转换的一些操作如通道选择,工作模式选择等等,AD转换开始前,必须设置ADCR寄存器来选择工作模式。
3、A/D全局数据寄存器ADGDR,它包含最近一次A/D转换的结果。
4、A/D中断使能寄存器ADINTEN,如果使用转换完中断时,需要配置此寄存器,它包含的使能位控制每一个A/D通道的DONE标记是否用来产生中断。
5、A/D通道n数据寄存器ADDRn,共有8个,它包含在通道n上完成的最近一次转换结果。
6、A/D状态寄存器AD0STAT,它包含所有A/D通道的DONE标志和OVERRUN标志,以及A/D中断标志。
关于这几个寄存器的各位代表是什么意思,如何设置,这里就不总结了,芯片的数据手册上写的很清楚,如果你觉得看英文不舒服可以参考一下周公那公司翻译的中文版,应该对初学者有所帮助。下面说一下这次实验的电路图:
图1-1电位器分压电路图
实验电路很简单,就是一个电位器来分压,然后由AD转换器的通道2来采样电压,然后再把采集到的电压通过串口0发送的到串口以便观察采样的电压值,好了,电路这块就不多费口舌了,留点笔墨说一下程序吧,下面先贴出ADC的源代码:
一、AdcFunc.c源代码(主要就是与ADC相关的一些函数)
#include"adc.h"
void AdcInit(void)
{
SC->PCONP |= (1 < 12);
PINCON->PINSEL1 |= (1<18);
ADC -> ADCR |= ( 1 < 2 )
|( ( 18000000 / ADC_CLK - 1 ) < 8 )
|( 0 < 16 )
|( 1 < 21 )
|( 1 < 24)
|( 0 < 27) ;
}
unsigned int AdcConver(void)
{
unsigned int i = 0;
unsigned long ulADCbuf = 0;
unsigned intulADCData = 0;
for(i=0;i
{
ADC -> ADCR |= 1 < 24;
while (!(ADC ->ADSTAT & (1 < 2)));
ADC -> ADCR |= (1 <24);
while ((ADC ->ADSTAT & (1 < 2)) == 0);
ulADCbuf= ADC ->ADDR2;
ulADCbuf= (ulADCbuf >> 4) & 0xfff;
ulADCData += (unsigned int)ulADCbuf;
}
//ADC -> ADCR &= ~(1<21)&(~(1<24));
ulADCData = (ulADCData/ADC_CNT);
ulADCData = (ulADCData*3300)/4096;
returnulADCData;
}
这个源代码,主要就是ADC初始化与ADC采样程序,程序中我已将用到的寄存器都注释了,对于初学者来说应该不是太难了,下面贴出主程序的部分代码:
二、mian.c(主要调度函数及应用函数)
void AdcDisVal(void)
{
unsigned int adcval = 0;
unsigned int hh = 0;
unsigned int hi = 0;
unsigned int ll = 0;
unsigned int lo = 0;
adcval = AdcConver();
if(adcval != AdcValOld)
{
if(((adcval+1)!=AdcValOld)&&((adcval+2)!=AdcValOld)&&((adcval+3)!=AdcValOld))
{
if(((adcval-1)!=AdcValOld)&&((adcval-2)!=AdcValOld)&&((adcval-3)!=AdcValOld))
{
hh = adcval/1000;
hi = adcval00/100;
ll = adcval0/10;
lo = adcval;
AdcVal[38] = (unsigned char)hh + 0x30;
AdcVal[40] = (unsigned char)hi + 0x30;
AdcVal[41] = (unsigned char)ll + 0x30;
AdcVal[42] = (unsigned char)lo + 0x30;
UARTSend(0,AdcVal,50);
AdcValOld =adcval;
}
}
}
}
下面是程序执行结果:
图1-2程序执行结果
这只是部分代码,详细的源代码请参考附件。这段代码是将采集到的数据转换成字符发送到串口显示,里面没有什么复杂的计算,都是烂大街的程序,因为懒猫也不是什么高手,也说不出什么高深的理论,只能总结点简单的东西,希望这些简单的实验能起到抛砖引玉的作用,让初学者尽快能迈入单片机这扇门,万事开头难,徘徊在门口的感觉最不好爱,懒猫也曾彷徨过,也曾无奈过,也曾痛苦过,也曾抱怨过,但道路虽然崎岖,只要你坚持就能爬到山顶。懒猫深知很多人面对电子有着莫大的兴趣,但却无从下手,没有高手指导,没有教材参考,这种感觉实在不好爱,所以懒猫有空便会写下自己的学习日志,尽量简单,尽量详细,俗话说师傅引进门,修行靠个人,当你熬过阵痛,跨进电子这扇门之后,剩下的事就是发挥你的聪明才智,努力的创造奇妙的未来!还是那句老话,学无难易,贵在坚持!
好了,今天先总结到这吧,最近手头上的事有点多,所以自学的时间有点紧