mini2440裸机试炼之--A/D模拟信号转换

mini2440裸机试炼之--ADC_W1_LED

 

实现功能

        通过开发板上的滑动变阻器控制的模拟信号经过A/D转换器
        转换为数字信号用uart_printf()打印在串口上。 并且滑动
        变阻器同时控制指示灯led的闪烁速度(时长)。

 

S3C2440ADC的主要特性如下:

    ●分辨率:10位

    ●最大转换速率:500KSPS

    ●微分线性度误差:±1.0 LSB

    ●积分线性度误差:±2.0 LSB

    ●供电电压:3.3V

    ●模拟输入电压范围:0~3.3V

    ●模拟输出数值范围:0~1023

ADC原理

ADC是一种将模拟信号转化为数字信号的方法,一般要经过采样、保持、量化、编码4个步骤。在实际电路中,有些过程是合并进行的,如采样和保持,量化和编码在转换过程中时同时实现的。由奈奎特采样定理可知,当采样频率大于模拟信号中最高频率的2倍时,采样值才能不失真地反映原来模拟信号


                                                   

从图1可以看出,ADC共有8路模拟输入,其中XP、XM、YP和YM是触摸屏使用的4路,剩下的4路模拟输入A[3:0]可以用于一般的ADC输入通道(AIN0、AIN1、AIN2和AIN3)。当触摸屏引脚(YM、YP、XM和XP)为禁止时,这些端口可以被用于ADC的模拟输入端口(AIN4、AIN5、AIN6和AIN7)

对于S3C2440处理器,ADC输入时钟是由PCLK分频得到的,如图2所示

                                              

ADC寄存器

ADCCON部分

                                          
                                            
                                          

                                                                                                                      图3

根据图3,ADCCON控制寄存器

ECFLG 是转换结束标志位,当转换结束时,ECFLG值为1,进入转换状态为0;

PRSCEN是使能预分频控制位 ;

PRSCVL 是预分频值放置位;0~255

■当PRSCEN为1时,设置PRSCVL的值将会决定AD转换的时间。ADC使用的时钟是系统的PCLK,由于main函数设置mpll为400MHZ,所以PCLK = 50MHz,设置PRSCVL的值为49,那么:

A/D 转换的频率 = 50MHz / (49+1) = 1 MHz

A/D 转换的时间 = 1 /(1MHz / 5cycles)=5 uS

由此可知当PRSCVL的值越小,A/D 转换的时间越短,A/D 转换的频率也就越大。

注意:当从待机模式中变换到正常工作模式时,ADC的预分频器必须在最后的3ADC时钟前使能????

 

SEL_MUX是模拟输入通道选择控制器

READ_START要使能A/D转换启动,就必须禁止READ_ START

ENABLE_START 使能A/D转换控制位

ADCDAT0

由于只是通过AIN0模拟信号输入。并没使用触摸屏功能,所以,ADCDAT0只考虑普通ADC转换数值(模拟信号转换的数字数值存于XPDATA)

 

W1可调电位器

mini2440上有一个可调电位器,如下图所示。电位器的中间抽头部分接在ADC输入通道AIN0上,当电位器滑动头位于最下端时,AIN0引脚电压为0V;当电位器滑动头位于最上端时,AIN0引脚电压为3.3V;当电位器上、下滑动时,AIN0引脚的电压值会在0~3.3V之间变换。由此可知,W1是通过AIN0模拟输入通道间模拟信号传给ADC,再进行转换的。

 

代码部分

#include"2440addr.h"     //引脚宏定义
#include"def.h"          // U8 U32宏定义
#include"2440lib.h"      //使用Uart_Printf,Dalay声明,Uart_Printf定义在2440lib.c文件
 
/*
当PRSCEN为1时,设置PRSCVL的值将会决定AD转换的时间。ADC使用的时钟是系统的PCLK
,由于main函数设置mpll为400MHZ,所以PCLK = 50MHz,设置PRSCVL的值为49,那么:
 
A/D 转换的频率 = 50MHz / (49+1) = 1 MHz
 
A/D 转换的时间 = 1 /(1MHz / 5cycles)=5 uS
*/
/********ADC********/
#definePRSC_EN     0x1           //允许预分频
#define PRSCVL      0x19          //预分频值
#defineSEL_MUX     ~0x7          //模拟通道选择AIN0通道
#define STDBM       0x0           //正常工作模式
#defineREAD_START  0x0           //读数时不进行A/D转换
#defineADC_STAR    0x1           //ADC开启
 
/********LED*********/
#defineLED1_out  (1<<(5*2))
#defineLED2_out  (1<<(6*2))
#defineLED3_out  (1<<(7*2))
#defineLED4_out  (1<<(8*2))
#defineLED4_ON   (0x0E<<8)       //LED1+LED2+LED3+LED4 ON
#defineLED_OFF   (0x0F<<5)
 
void ADC_display(){
    Uart_Printf("\n");
    Uart_Printf("\n");
    Uart_Printf("\n");
              Uart_Printf("---------HELLOADC\n");
              Uart_Printf("PRSC_EN:  %5x  允许预分频\n",PRSC_EN);
              Uart_Printf("PRSCVL:   %5x  预分频值\n",PRSCVL);
              Uart_Printf("SEL_MUX:   ~0x7  模拟通道选择AIN0通道\n",SEL_MUX);
    Uart_Printf("STDBM:    %5x  正常工作模式\n",STDBM);
              Uart_Printf("READ_START:%4x  读数时不进行A/D转换\n",READ_START);
              Uart_Printf("ADC_STAR:  %4x ADC开启\n",ADC_STAR);
              Uart_Printf("变阻器控制的模拟信号经过A/D转换器转换为\n");      
    Uart_Printf("数字信号用串口显示,并且滑动变阻器同时控\n");
    Uart_Printf("制指示灯led的闪烁速度(时长)\n");              
   Uart_Printf("#########################################\n\n");               
}
//初始化AD控制寄存器
void ADC_INIT(){
  rADCCON&=(~((0x1<<14)|(0xff<<6)|(0x7<<3)|(0x1<<2)|(0x1<<1)|(0x1<<0)));
  rADCCON=(PRSC_EN<<14)|(PRSCVL<<6)|(SEL_MUX<<3)|(STDBM<<2)|(READ_START<<1);
   rADCCON|=(ADC_STAR<<0);          //开启ADC(开启ADC后,此位会自动清零)
 
}
 
//初始化LED,四个LED输出
voidLED_INIT(){                   
   rGPBCON=LED1_out|LED2_out|LED3_out|LED4_out;
}
 
//LED函数
void W1_LED(intget_data0){        
    rGPBDAT= LED4_ON;     //点亮四个LED
    Delay(get_data0);     //ADC后十位时延函数
    rGPBDAT= LED_OFF;     //熄灭LED
}
 
//串口打印变阻器模拟信号数值
void W1_ADC(int*read_xpdata){
              ADC_INIT(); //初始化AD控制寄存器
    /*****串口打印ADC数据函数****/
    while(rADCCON & 0x1);                //因为成功启动A/D转换后,该位会
                                          //自动清零,因此在这里检查ADC是否真正启动
    while(!(rADCCON & (1<<15)));            //使用查询方式等待ADC转换结束
   *read_xpdata=(int)(rADCDAT0&0x3ff);  //读取ADCDAT0后十位
    Uart_Printf("\n HELLO ADC# W1值为: %04d ",*read_xpdata);//串口输出ADCDAT0后十位值
    Delay(500);
              }
 
//子main函数
voidADC_read_W1(){                    
  
    int read_xpdata0;
    ADC_display(); 
    LED_INIT(); //初始化LED
  
    while(1)
    {
     /*串口打印变阻器模拟信号数值*/
     W1_ADC( &read_xpdata0 );//传递read_xpdata0地址,改变read_xpdata0的值来给W1_LED函数使用
   
     /*****LED点亮函数*****/
     W1_LED(read_xpdata0);                 //LED函数
    
    }
 
}
 


◆串口输出截图



  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值