VxWorks开发板驱动程序学习之普通ADC驱动

后面还会讲到S3C2410用ADC结合触摸屏的驱动实验,此节简单介绍2410的ADC普通模式驱动方式。

S3C2410的ADC简介

S3C2410内置1个8通道的10位ADC,在2.5MHz的AD转换时钟下,最大转换速率可达500kHz。

先看ADC模块图:

这里写图片描述

此图来自S3C2410 datasheet. 简单说一下,外部晶体控制器部分控制外部的晶体管以控制触摸屏。AIN[0]-AIN[7]为七个模拟量输入通道,经8:1选择器后由内部逐次逼近式转换模块转换,后经ADC接口控制器送到中断源产生器再送到CPU。

S3C2410内置ADC的特性

  • 分辩率: 10-位
  • 微分线性度误差: ± 1.0 LSB
  • 积分线性度误差: ± 2.0 LSB
  • 最大转换速率: 500 KSPS
  • 低功耗
  • 供电电压: 3.3V
  • 输入模拟电压范围: 0 ~ 3.3V
  • 片上采样保持功能
  • 普通转换模式
  • 分离的X/Y轴坐标转换模式
  • 自动(连续) X/Y轴坐标转换模式
  • 等待中断模式

ADC普通转换模式(Normal Conversion Mode)

普通转换模式(AUTO_PST=0, XY_PST=0)用来进行一般的ADC转换。

这里简单看一下ADC的控制寄存器(ADCCON)、数据寄存器0(ADCDAT0)、数据寄存器1(ADCDAT1)、转换周期等待定时器(ADCDLY)的各位定义。

这里写图片描述

ADCCON 控制寄存器

ADCCONBIT[15-0]FUNCTION
ECFLG[15]1 = End of Conversion
PRESEN[14]1 = Enable
PRSCVL[13:6]1-255
SEL_MUX[5:3]AIN0 - AIN7
STDBM[2]1= Standby Mode
READ_START[1]1 = Enable start by Read operation
ENABLE_START[0]1 = A/D conversion start

ADCTSC 触屏控制寄存器(ADC Touch Screen Control)

ADCTSCBIT[8-0]FUNCTION
Reserved[8]SBZ (should be zero)
YM_SEN[7]select output value of YMON
YP_SEN[6]select output value of YPON
XM_SEN[5]
XP_SEN[4]
PULL_UP[3]1 = XP pull-up is disable
AUTO_PST[2]1 = Auto X/Y Position conversion mode, 0 = Normal ADC mode
XY_PST[1:0]Manual measurement of X-position or Y-position.

其它几个寄存器的各位定义就不再列出了,学习时可以理解各位的定义,具体编程时可以再查看相应的datasheet.

S3C2410的ADC普通模式驱动代码

    // 时钟定义
    #define     FCLK        (200*1000000)   
    #define     HCLK        (FCLK/2)        
    #define     PCLK        (HCLK/2)        

    // ADC 转换时钟频率 (2MHz)
    #define  ADC_FREQ       (2*1000000)

    UINT32  adc0, adc1; 
    // 硬件访问方式 
    #define SNGS3C_REG_READ(x,result)      ((result) = *(volatile unsigned int *)(x))
    #define SNGS3C_REG_WRITE(x,data)       (*((volatile unsigned int *)(x)) = (data))
    #define SNGS3C_REG_AND(x, data)        (*((volatile unsigned int *)(x)) &= (data))
    #define SNGS3C_REG_OR(x, data)         (*((volatile unsigned int *)(x)) |= (data))
    #define SNGS3C_REG_XOR(x, data)        (*((volatile unsigned int *)(x)) ^= (data))
    // 函数功能:读取指定通道的ADC转换值
    // 输入参数:通道值
    // 返回值:  转换结果
    int ReadAdc(int ch)
    {
        int i;

        ch = ch & 0x07;                  // 通道值为3位二进制数 0-7
        *(volatile UINT32 *)rADCCON = (1<<14)|((PCLK/ADC_FREQ - 1)<<6)
                                      |(ch<<3)|(0<<2)|(0<<1)|(0<<0);
        *(volatile UINT32 *)rADCTSC = (*(volatile UINT32 *)rADCTSC) & (~0x03);

    //  SNGS3C_REG_OR(rADCCON, (0|(1<<14)|((PCLK/ADC_FREQ -1)<<6)|(ch<<3)|(0<<2)|(0<<1)));
    //  SNGS3C_REG_AND(rADCTSC, (~0x03)); //普通ADC转换模式
        taskDelay(sysClkRateGet()/500);

        *(volatile UINT32 *)rADCCON |= 0x01;              // 启动ADC
        while((*(volatile UINT32 *)rADCCON )& 0x01);      // 等待ADC启动
        while(!((*(volatile UINT32 *)rADCCON) & 0x8000)); // 等待ADC完成
        return ((*(volatile UINT32 *)rADCDAT0) & 0x3ff);  // 返回转换结果 (0-1023)
    }
    // 函数名称: Adc_Main
    // 函数功能: ADC主任务
    void Adc_Main()
    {
        int   vin0, vin1;

        while(1)
        {   
            adc0 = ReadAdc(0);      // 读取通道的转换值
            adc1 = ReadAdc(1);

            vin0 = (adc0*3300) / 1024;  // 计算实际的真实电压值
            vin1 = (adc1*3300) / 1024;
            printf("AIN0 is %d mV,  AIN1 is %d mV \n", vin0, vin1);
            // 重定位到串口打印输出

            taskDelay(120);         // 任务主循环里面必须延时让出CPU,提高CPU使用率
        }
    }
    int AdcTask( void )
    {   
        int   iTaskID;
        iTaskID = taskSpawn( "tAdc",120,0,0x9000, (FUNCPTR)Adc_Main, 0,0,0,0,0, 0,0,0,0,0 );
        taskDelay( 10 );

        return iTaskID;
    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

轻蓝雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值