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

来源:互联网 发布:c语言自学书籍 编辑:程序博客网 时间:2024/04/30 10:49

后面还会讲到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 控制寄存器

ADCCON BIT[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)

ADCTSC BIT[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 0
原创粉丝点击