Chinaunix首页 | 论坛 | 博客
  • 博客访问: 456816
  • 博文数量: 362
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2015-07-26 17:08
文章分类

全部博文(362)

文章存档

2015年(362)

我的朋友

分类: 嵌入式

2015-12-10 23:56:21

原文地址:mini2440裸机之ADC 作者:

1AD转化简单介绍

1ARM内置的ADC转换是8通道的10位的模数转化器;

2)本程序可以实现通道0和1(AIN0和AIN1)的模数转化;

3)使用查询的方式来访为转换后的数据。具体实现是查看ADCCON[15](转换标志结束位)是否为1

4ADC转化需要确定两个参数:1、模拟输入通道 2AD转换频率。由于AD转换频率至少小于PCLK1/5(10.14Mhz)   ,所以设置了转换频率为2.5MHZ.通过转换频率可以求出预分频值,预分频值=(50MhzPCLK/AD转换频率)-1.

2AD转化的实现步骤:

1)通过转化频率计算预分频值

2)写预分频值和模拟通道到ADCCON

3)通过设置ADCCON的第0位为1,启动ADC

4)确定转换开始后,通过查询ADCCON[15](转换标志结束位)是否为1判断是否转换结束

5)如果转换结束,读取ADCDATO[0-9],即转换后的数据

3volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。

//====================================================================
// File Name : Adc.c
// Function  : S3C2410 ADC Test
// Program   : Kang, Weon Tark
// Date      : May 22, 2002
// Version   : 0.0
// History
//   0.0 : Programming start (March 29,2002) -> KWT
//         ADC Test                          -> May 15, 2002 SOP
//====================================================================

#include "def.h"

#include "option.h"

#include "2440addr.h"

#include "2440lib.h"

#include "2440slib.h" 

 

#define REQCNT 100    

#define ADC_FREQ 2500000   //设定AD的转换频率,应该至少小于PCLK的1/5(10.14Mhz)  2.5MHz

#define LOOP 10000              //延迟的循环次数

volatile U32 preScaler;       //通道设置存

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

int ReadAdc(int ch)          //ADC函数,ch决定那个通道被选择,通道数(ch0-7

{

int i;

static int prevCh=-1;       //定义静态整形变量prevCh存储AD转换通道

 //ADC设置使能端、设置预分频值为49、选择通道位,选中的通道上的电压被连接到AD

rADCCON = (1<<14)|(preScaler<<6)|(ch<<3);    //setup channel

if(prevCh!=ch)                              //如果通道改变了

  //setup channel

rADCCON = (1<<14)|(preScaler<<6)|(ch<<3);   //重新设置设置通道ch和预分频值preScaler

for(i=0;i            //delay to set up the next channel

prevCh=ch;

}

rADCCON|=0x1;                //start ADC:使能ADC

while(rADCCON & 0x1);  //check if Enable_start is low //检查 Enable_start 是否为低电平

 while(!(rADCCON & 0x8000));          //check if EC(End of Conversion) flag is high

//检查EC(End of Conversion) 位是否为高电平

 

   //判断转换是否完成,如果完成跳到下一个语句,否则死循环,直到完成为止。

   //ADCCON[15]位:转换结果标志位,是只读位,如果值为0则表示在模数转换过程中,如果//1则表示模数转换已完成。

return ( (int)rADCDAT0 & 0x3ff );       //返回的数ADCDAT0[0-9]即为ADC转换的数字量。

}

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

void Test_Adc(void) 

{

int a2=0;                          //初始化变量

U32 rADCCON_save = rADCCON;  //用rADCCON_save 存储初始的ADCCON,以备恢复用

Uart_Printf( "\nADC INPUT Test, press ESC key to exit !\n" ) ; //终端的显示, 打印AD的转换频率

preScaler = ADC_FREQ;

Uart_Printf("ADC conv. freq. = %dHz\n",preScaler); //PCLK:50.7MHz 。通过转化频率计算预分频值

//FCLK=400M  HCLK=100M  PCLK=50M   //AD转换器频率=PCLK/(preScaler+1)

preScaler = 50000000/ADC_FREQ -1;       

Uart_Printf("PCLK/ADC_FREQ - 1 = %d\n",preScaler);     //串口输出预分频值

while( Uart_GetKey() != ESC_KEY )         //如果不按ESC按键

{

  a0=ReadAdc(0);          //对应开发板上W1可调电阻
  a1=ReadAdc(1);         //对应开发板上W2可调电阻

 

  Uart_Printf( "AIN0: %04d, AIN1: %04d\n", a0, a1 );
  Delay( 500 ) ;

}    

//rADCCON=(0<<14)|(19<<6)|(7<<3)|(1<<2);  //stand by mode to reduce power consumption

rADCCON = rADCCON_save;   //恢复现场

Uart_Printf("\nrADCCON = 0x%x\n", rADCCON);  //输出ADC控制器内容

}

阅读(429) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~