您的位置:首页 > 其它

ARM学习之ADC实验

2011-10-19 14:06 246 查看
/***************************************************

Project: ADC实验

Writer: SHOW

Time:
2011/10/18

Hareware: 硬件平台:mini2440 , J-link.

Function: 通过调节mini2440的滑动变阻器W1 在SecureCRT终端看到电压从0V到3.299V的的连续变化。

Direction: 1.今天调了一上午都没出效果,调试发现一直停留在while(rADCCON & ADC_START);总是出不来。

开始以为是ADC_Convert转换函数不对,仔细检查没发现问题,再考虑可能是初始化函数不对,

所以AD转换不能真正开始,但是自己核对和别人可行的代码,查书,也没有发现有什么错误,

无奈之下,只能把别人可行的代码一段一段替代我的代码,再运行看效果,把JustDo的初始化函数

替代我的初始化函数Init_ADC,发现效果出来了,太Happy了,锁定问题就一定出在Init_ADC函数啦。

但是还有一个问题就是我的几乎和他的一模一样啊,怎么他的能出来,我的出不来了?再仔细分析

代码我的是rADCCON = (PRESCALE_EN | PRSCVL49 | CHANNEL0) ; 他的是rADCCON = (channel<<3) | (preScaler<<6) | (1<<14);

看了又看只有他的值直接赋给ADCCON寄存器,而我是或给它的。此刻!我完全清晰啦,肯定是ADCCON

上电初始value不是0。如果是或的话保留了其他值的其他位,这样肯定和你想要的设置不同啦。

查手册发现初始值真的不是0,而是0x3fc4。犯这个错误根本原因就是自己想当然了,没有仔细看手册,

并不是所有的寄存器初始value就是0。

参考书籍:韦东山《嵌入式linux应用完全开发手册》



***************************************************/

#include "2440addr.h"

#include "def.h"

#include "uart.h" //uart.c by xgc

#define PRESCALE_EN (1<<14)

#define PRSCVL49 (49<<6)

#define CHANNEL0 (0<<3)

#define ADC_START (1<<0)

#define ADC_END_FLAG (1<<15)

#define MPLL_200MHZ ((0x5c<<12) | (0x01<<4) | (0x02))

void Set_PCLK_50M(void);

U16 ADC_Convert(void);

void Init_ADC(void);

void Init_UART(void);

//========================================================================

// 函数名称: 延时1ms子函数

// 功能描述: 延时

// 参数: times为延时的ms数。

// 返回值: void

//========================================================================

void Delay1ms(int times)

{

int i;

for( ; times > 0; times-- )

for(i=400; i>0 ; i--);

}

//========================================================================

// 函数名称: 主函数

// 功能描述: 函数入口

// 参数: void

// 返回值: void

//========================================================================

void Main(void)

{

U16 voltage = 0; // voltage 为小数点后的值

float f_voltage; // f_voltage 是将转换都的值转算成实际电压的值

Set_PCLK_50M(); // 设置PCLK为50M

Init_UART();


Init_ADC();


Uart_Printf("\n ---UART程序BY SHOW---\n"); // UART_Printf 函数来源xgc的库uart.c

while(1)

{



f_voltage = ((float)ADC_Convert() * 3.3) / 1023.0;

voltage = (f_voltage - (int)f_voltage) * 1000;

Uart_Printf("\n Voltage is %d.%dV \n",(int)f_voltage,voltage);

rADCCON |= ADC_START;
//转换完毕后,再次启动,以完成连续检测电压,这句很重要,不要因为启动一次就够了。

}



}

//========================================================================

// 函数名称: ADC初始化函数

// 功能描述 初始化ADC,使能预分频功能,分频比设置为49+1=50,选择通道0,启动ADC转换。


// 参数: void

// 返回值: void

//========================================================================

void Init_ADC(void)

{

rADCCON = (PRESCALE_EN | PRSCVL49 | CHANNEL0) ; // 使能预分频功能。分频比设为(49+1),选择模拟通道0。

rADCCON |= ADC_START;
// 启动转换

rADCTSC &= ~(1<<2);
// 普通转换模式

}

//========================================================================

// 函数名称: ADC转换函数

// 功能描述 开始ADC转换,并且返回转换后的值。


// 参数: void

// 返回值: 转换后的值

//========================================================================

U16 ADC_Convert(void)

{

while(rADCCON & ADC_START);
// 当转换真正开始后[0]会自动清0

while(!(rADCCON & ADC_END_FLAG));
// 判断是否转换结束,[15]为1则转换结束

return(rADCDAT0 & 0x3ff);
// 转换结束后返回数字量,注意是ADCDAT0的后10位数据。

}

//========================================================================

// 函数名称: PCLK大小设置函数

// 功能描述 设置FCLK=200M,PCLk=50M


// 参数: void

// 返回值: void

//========================================================================

void Set_PCLK_50M(void)

{

rMPLLCON = 0;

rMPLLCON |= MPLL_200MHZ; // MPLL = FCLK

rCLKDIVN = 0x03; // FCLK:HCLK:PCLK = 1:2:4 => PCLK = 50MHz.

}

//========================================================================

// 函数名称: UART初始化子函数

// 功能描述: 设置UATR0的基本信息

// 参数: void

// 返回值: void

//========================================================================

void Init_UART(void)

{

rGPHCON |= ((1 << 7) | (1 << 5)); //设置 GPH2,GPH3 为TXD0,RXD0 口。

rGPHUP |= ((1 << 3) | (1 << 2));

rULCON0 = 0x03;
// 无红外模式,数据位为8位。

rUCON0 = 0x05;
// UART时钟源为PCLK。Transmit与Receive都为查询或者中断模式

rUFCON0 = 0x00;
// 不使用FIFO

rUMCON0 = 0x00;
// 不使用流控

rUBRDIV0 = (50000000 / (115200 * 16)) - 1; // 波特率为115200

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: