本节来叙述LPC1343内部ADC的运用。规划一个试验,运用ADC的0通道进行AD转化,而且将转化成果经过UART发送在PC端的串口终端软件调查。
这次依然以NXP供给的example作为比如,可是LPC1343内部ADC作业方法很多,所以该example用了许多的预编译结构,笔者在此将本次试验不会用到的句子悉数去掉,程序变得简练,也更易于了解。
相同的,在此节中将不再将所用到的寄存器逐个列出,而仅仅一个各个寄存器设置的“头绪”,由于至此各个读者必定现已具有了自己翻阅用户手册查看对应寄存器内容的才能。
从主函数咱们能够看出本次试验的发展进程:
int main (void)
{
uint32_t i,j;
UARTInit(115200);//初始化UART
ADCInit( ADC_CLK );//初始化ADC
while(1)
{
ADCRead( 0 );//读取0通道转化值
while ( !ADCIntDone );//等候读取完结
ADCIntDone = 0;//铲除读取完结标志
UARTBuffer[0]=(uint8_t)(*ADCValue>>8);//别离高2位数据
UARTBuffer[1]=(uint8_t)(*ADCValue);//别离低8位数据
UARTSend((uint8_t *)UARTBuffer, 2);//向UART发送数据
for(i=0;i<5000;i++)//延时
for(j=0;j<1000;j++);
}
}
咱们应该在几个8位单片机上都规划过这种ADC转化程序,信任咱们也必定经历过这个根底的进程。
UART的初始化在上一节现已胪陈了,咱们直接来看看ADC的初始化ADCInit():
void ADCInit( uint32_t ADC_Clk )
{
LPC_SYSCON->;PDRUNCFG &= ~(0x1<<4);//翻开ADC供电
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<13);//敞开ADC的AHB通道
LPC_IOCON->JTAG_TDI_PIO0_11 = 0x02;//挑选ADC0引脚功用
LPC_ADC->CR = ((SystemCoreClock/LPC_SYSCON->SYSAHBCLKDIV)/ADC_Clk-1)<<8;
#if ADC_INTERRUPT_FLAG//运用ADC中止功用
NVIC_EnableIRQ(ADC_IRQn);
LPC_ADC->INTEN = 0x1FF;
#endif
return;
}
1、该函数仅有的参数填入欲设置的ADC作业速率,单位是Hz,本次试验填入4500000,即4.5MHz;
2、ADC初始化不同于前面其他设备的一个当地,在于它的电源是默许封闭的,所以首要要翻开它的电源,显着是一个降低功耗的办法;
3、ADC的作业速率,从用户手册能够查看到如下描绘:
The APB clock (PCLK) is divided by CLKDIV +1 to produce the clock for the ADC, which should be less than or equal to 4.5 MHz.由此咱们知道该ADC的最大驱动时钟频率是4.5MHz。一起分频数是CLKDIV +1,所以程序中要“ADC_Clk-1”,至于为什么要左移8位呢?那是由于设置的分频数是存放于ADCCR(ADC操控寄存器)中的第8:15位。
4、假如运用中止功用,则除了要设置NVIC操控器之外,还需要在ADCINTEN中翻开各个通道的中止功用,当某通道转化完结时,会触发关于中止。
初始化完毕之后,就能够敞开ADC进行转化了。首要是ADCRead():
uint32_t ADCRead( uint8_t channelNum )
{
if ( channelNum >= ADC_NUM )//判别通道号是否过大
{
channelNum = 0;//复位通道号
}
LPC_ADC->CR &= 0xFFFFFF00; //铲除一切转化通道的上一次挑选状况
LPC_ADC->CR |= (1 << 24) | (1 << channelNum);//挑选通道,并敞开转化
return ( channelNum );//回来通道号
}
1、本函数要求填入的仅有参数是所期望进行ADC的通道号;
2、转化前应该铲除上一次通道被选状况;
3、在CR操控器中的26:24位操控着ADC的多种转化发动方法,本试验中运用最一般的一种:当即开端转化。
4、由于本试验运用了ADC的中止功用,转化成果在ADC中止中存储,所以此函数在运用ADC中止功用的情况下回来的是转化的通道号。
ADC中止功用的情况下回来的是转化的通道号。
所以当本函数运转完毕之后,ADC转化开端,等候进入中止服务函数:
void ADC_IRQHandler (void)
{
uint32_t regVal;
LPC_ADC->CR &= 0xF8FFFFFF;
regVal = LPC_ADC->STAT;
if ( regVal & 0x0000FF00 )
{
regVal = (regVal & 0x0000FF00) >> 0x08;//假如有,承认通道
switch ( regVal )//经过读取转化值来铲除ADC数据,留意这部分是过错数据,是丢掉的
{
case 0x01:regVal = LPC_ADC->DR0;break;
case 0x02:regVal = LPC_ADC->DR1;break;
case 0x04:regVal = LPC_ADC->DR2;break;
case 0x08:regVal = LPC_ADC->DR3;break;
case 0x10:regVal = LPC_ADC->DR4;break;
case 0x20:regVal = LPC_ADC->DR5;break;
case 0x40:regVal = LPC_ADC->DR6;break;
case 0x80:regVal = LPC_ADC->DR7;break;
default:break;
}
LPC_ADC->CR &= 0xF8FFFFFF;
ADCIntDone = 1;
return;
}
if ( regVal & ADC_ADINT )//判别是否有任何一个通道转化完毕
{
switch ( regVal & 0xFF )
{
case 0x01:ADCValue[0] = ( LPC_ADC->DR0 >> 6 ) & 0x3FF;break;
case 0x02:ADCValue[1] = ( LPC_ADC->DR1 >> 6 ) & 0x3FF;break;
case 0x04:ADCValue[2] = ( LPC_ADC->DR2 >> 6 ) & 0x3FF;break;
case 0x08:ADCValue[3] = ( LPC_ADC->DR3 >> 6 ) & 0x3FF;break;
case 0x10:ADCValue[4] = ( LPC_ADC->DR4 >> 6 ) & 0x3FF;break;
case 0x20:ADCValue[5] = ( LPC_ADC->DR5 >> 6 ) & 0x3FF;break;
case 0x40:ADCValue[6] = ( LPC_ADC->DR6 >> 6 ) & 0x3FF;break;
case 0x80:ADCValue[7] = ( LPC_ADC->DR7 >> 6 ) & 0x3FF;break;
default:break;
}
ADCIntDone = 1;//读取完毕标志
}
return;
}
1、进入中止服务程序之后,首要中止AD转化;
2、和UART相同,ADC中止标志也是经过读取来铲除的;
3、首要要查看溢出过错,假如有,则数据无效,要通道读取来铲除ADC转化数据寄存器(ADCDR);
4、ADC中止有两种,一种是任何一个通道完结转化都会触发,一种是某个中止完结转化就会触发,本试验中两种中止都翻开了,因而先判别是否有转化完结,再判别是哪个通道完结转化;
中止函数的完毕意味着读取完结,剩余的便是将读出数据发送到UART去显现了。但在这之前,由于LPC1343的ADC默许情况下是10位精度,而咱们的UART是以字符为数据长度发送的,所以笔者特意将转化成果转化成了16位长度,分两次发送。现将本次试验运转进程概略如下:
UART初始化——ADC初始化——开端转化——转化完毕触发中止——判别有无过错——有过错则抛弃无效数据,无过错则读出有用数据——数据处理——发至UART
附上运转成果jpg两张,第一张,0通道引脚接在GND:
第二张,0通道接在VCC 3.3:
理论上3.3V为满赋值,转化成果应该是是11 1111 1111=0x3ff,不过实践并非如此,阐明其实咱们板子上引出的电源仍是有必定动摇的。
声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/fangan/dianlu/261143.html