ARM学习之ADC实验

/***************************************************
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

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值