AD电阻转换---那些年我们一起玩mini2440(arm9)裸机

28 篇文章 5 订阅

ADC驱动程序设计

ADC:模/数转换器。

一种将模拟信号转换成数字信号的装置;

DAC:/模转换器。

一种将数字信号转换成模拟信号的装置。

模拟信号转换为数值信号的步骤:

1.     取值;

2.     量化;

3.     编码;

S3C2440ADC

S3C2440芯片内部共8A/D转换通道AIN0~AIN7,但是转换器只有一个。

转换精度为10位,故转换后的值最小时会接近0,最大时会接近1024.

最大的转换率在2.5MHZ转换时钟下能达到500KSPS(每秒采样5000千次)

在常见的设计中,如mini2440开发板一般AIN4AIN5AIN6AIN7被用作了四线电阻触摸的YMYPXMXP通道;剩余的AIN0~3被引出,其中AIN0直接和一个可调电阻W1连接。

 

师:AIN4AIN5AIN6AIN7给触摸屏用的;

AIN0用于可调电阻

(这样电压就可以作为一路模拟信号进行转换)

ADC驱动流程:1.初始化à2.启动à3.转换结束à4.读取转换值;

 

一.ADC初始化

A.选择转换通道-     B.设置转换频率

 

怎么判断开始转换了?用一个whlie循环,查询ENABLE_START是否变成0

 

怎么判断转换完成了?不断查询ECFLG是否为1

 

读取转换值:

#define	GLOBAL_CLK		1
#include <stdlib.h>
#include <string.h>
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h"
#include "mmu.h"
#include "profile.h"
#include "memtest.h"


#define ADC_FREQ 2500000
//#define ADC_FREQ   1250000


volatile U32 preScaler;

void adc_init(void);
int ReadAdc(int channel);
static void cal_cpu_bus_clk(void);
void Set_Clk(void);
void beep_init(void);
void beep_run(void);
/*************************************************
Function name: delay
Parameter    : times
Description	 : 延时函数
Return		 : void
Argument     : void
Autor & date : Daniel
**************************************************/
void delay(int times)
{
    int i,j;
    for(i=0;i<times;i++)
       for(j=0;j<400;j++);
}
/*************************************************
Function name: Main
Parameter    : void
Description	 : 主功能函数
Return		 : void
Argument     : void
Autor & date : Daniel
**************************************************/
void Main(void)
{	
    int a0=0,tmp;
    int Scom=0;
    Set_Clk();
    Uart_Init(0,115200);
    Uart_Select(Scom);
      
    adc_init();
       while(1)
    {
        a0=ReadAdc(0);
        Uart_Printf( "AIN0: %04d\n", a0);
  		delay(1000) ;
	}

}	

/*************************************************
Function name: adc_init()
Parameter    : int channel
Description	 : adc初始化
Return		 : void
Argument     : void
Autor & date : Daniel
**************************************************/ 
void adc_init(void)
{
	int channel=0; //AIN0,对应开发板上W1可调电阻
	
	preScaler = ADC_FREQ;
	Uart_Printf("ADC conv,freq. = %dHz\n",preScaler);
	preScaler = 50000000/ADC_FREQ - 1; //PCLK=50M  我们要得到ADC_FREQ=2500000
	
	Uart_Printf("PRSCVL=PCLK/ADC_FREQ - 1=%d\n",preScaler);
	
	/*AD转换频率设置,最大频率为2.5MHz*/
	rADCCON = (1<<14)|(preScaler<<6)|(channel<<3);	//setup channel 1<<14使能预分频器 (preScaler<<6)预分频值  channel<<3模拟通道选择
	delay(1000);		

}
    
/*************************************************
Function name: ReadAdc(int channel)
Parameter    : int channel
Description	 : 获取AD 转换后的值
Return		 : int
Argument     : void
Autor & date : Daniel
**************************************************/    
int ReadAdc(int channel)
{

	/*开启AD转换*/
	rADCCON |= 0x01; //start ADC
	
	
	while(rADCCON & 0x1);	//check if Enable_start is low
	
    while(!(rADCCON & 0x8000));	//check if EC(End of Conversion) flag is high判断转换是否结束
	    
    return ( (int)rADCDAT0 & 0x3ff );//读取转换后的值
} 
/*************************************************
Function name: Set_Clk()
Parameter    : void
Description	 : 设置CPU的时钟频率
Return		 : void
Argument     : void
Autor & date : Daniel
**************************************************/
void Set_Clk(void)
{
	int i;
	U8 key;
	U32 mpll_val = 0 ;
	i = 2 ;	             //don't use 100M!
		                 //boot_params.cpu_clk.val = 3;
	switch ( i ) {
	case 0:	//200
		key = 12;
		mpll_val = (92<<12)|(4<<4)|(1);
		break;
	case 1:	//300
		key = 13;
		mpll_val = (67<<12)|(1<<4)|(1);
		break;
	case 2:	//400
		key = 14;
		mpll_val = (92<<12)|(1<<4)|(1);
		break;
	case 3:	//440!!!
		key = 14;
		mpll_val = (102<<12)|(1<<4)|(1);
		break;
	default:
		key = 14;
		mpll_val = (92<<12)|(1<<4)|(1);
		break;
	}
	
	//init FCLK=400M, so change MPLL first
	ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);   //set the register--rMPLLCON
	ChangeClockDivider(key, 12);    //the result of rCLKDIVN [0:1:0:1] 3-0 bit
	cal_cpu_bus_clk();    //HCLK=100M   PCLK=50M
}
/*************************************************
Function name: cal_cpu_bus_clk
Parameter    : void
Description	 : 设置PCLK\HCLK\FCLK的频率
Return		 : void
Argument     : void
Autor & date : Daniel
**************************************************/
static void cal_cpu_bus_clk(void)
{
	static U32 cpu_freq;
    static U32 UPLL;
	
	U32 val;
	U8 m, p, s;
	
	val = rMPLLCON;
	m = (val>>12)&0xff;
	p = (val>>4)&0x3f;
	s = val&3;

	//(m+8)*FIN*2 不要超出32位数!
	FCLK = ((m+8)*(FIN/100)*2)/((p+2)*(1<<s))*100;     //FCLK=400M  FIN=12000000
	
	val = rCLKDIVN;
	m = (val>>1)&3;
	p = val&1;	
	val = rCAMDIVN;
	s = val>>8;
	
	switch (m) {
	case 0:
		HCLK = FCLK;
		break;
	case 1:
		HCLK = FCLK>>1;
		break;
	case 2:
		if(s&2)
			HCLK = FCLK>>3;
		else
			HCLK = FCLK>>2;
		break;
	case 3:
		if(s&1)
			HCLK = FCLK/6;
		else
			HCLK = FCLK/3;
		break;
	}
	
	if(p)
		PCLK = HCLK>>1;
	else
		PCLK = HCLK;
	
	if(s&0x10)
		cpu_freq = HCLK;
	else
		cpu_freq = FCLK;
		
	val = rUPLLCON;
	m = (val>>12)&0xff;
	p = (val>>4)&0x3f;
	s = val&3;
	UPLL = ((m+8)*FIN)/((p+2)*(1<<s));
	UCLK = (rCLKDIVN&8)?(UPLL>>1):UPLL;
}



 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值