3 - 输入/输出:ADC(模数转换)

本文将介绍K60(Freescale Kinetis K60)和XS128(Freescale S12XS128)的ADC用法。
K60使用了野火的12年版底层库,请参考《三天入门 Cortex-M4—Kinetis 系列 野火 Kinetics 开发板教程》。
XS128请参考飞思卡尔提供的Datasheet.

ADC可以将电压信号转换成数字信号。
你可以配置它的读取精度,我这里用10bits或12bits。
以K60为例,如果配置精度为10bits,那么它就将3.3V电压平均分成1024份,数字输出为0则代表0V,输出1024则代表5V,输出512则代表2.5V。
同样,使用ADC之前,要对它进行初始化。


K60

以陀螺仪ENC03的读取为例.

初始化

/*************************************************************************
*  函数名称:ADdevice_init
*  功能说明:AD设备初始化函数
*  参数说明:
*  函数返回:无
*  修改时间:2012-2-14
*  备    注:根据需要进行初始化AD通道
*************************************************************************/


void ADdevice_init()
{
    //ENC 03 初始化  PE3
    adc_init(ENC_AD,ENC_X_CH);

}

其中宏定义

/***************ENC 03*******************************************/
#define ENC_AD        ADC1
#define ENC_X_CH      SE7a             //垂直方向陀螺仪端口 PE3

读数

下面将陀螺仪的电压值,读取AD30次,取平均值存储到到全局变量gyro_stand_voltage中。

/*************************************************************************
*  函数名称:gyro_init
*  功能说明:陀螺仪初始采集零偏值
*  参数说明:
*  函数返回:无
*  修改时间:2014-3-15
*  备    注:刚启动的时候,AD读数可能不稳,先延迟2s再读数。肥叉烧
*************************************************************************/

void gyro_init()
{
  delayms(2000);
  gyro_stand_voltage = ad_ave(ENC_AD,ENC_X_CH,ADBITS,30);     //直立陀螺仪零偏置 12bits 2000 400
}

XS128

以陀螺仪ENC03的读取为例.

初始化

void ADC_Init(void)
{
        ATD0CTL1=0b00100000;   //10位精度,采样前不放电,AN0作触发源
        ATD0CTL2=0b01000000;   //标志位自动清零,禁止外部触发,禁止中断    
        ATD0CTL3=0b10001000;   //右对齐无符号,每次转换1个序列,No FIFO
        ATD0CTL4=0b01000100;   //采样时间为8个ATDClock
        //ATDClock=[BusClock*0.5]/[PRS+1]=80M/2/(4+1)=8M
        ATD0CTL5=0b00000000;   //特殊通道禁止,单通道采样,单通道转换
        ATD0DIEN=0b00000000;   //禁止数字输入    
}

各寄存器配置请参考数据手册。(其实直接用上面的代码就可以)
如图,以ATD0CTL1为例。
ATDCTL1

读数

下面引用大杨总的代码

/*************************************************************************
*                飞思卡尔智能车程序  直立行走例程                                        
* 文件名 :[ENC03.c]
* 描  述 :陀螺仪相关设置
* 设  计 :snowwolf
*  Email :snowwolf2012@qq.com
* 说  明 :
************************************************************************/

#include "Includes.h"
#include "ENC03.h"

int ReadATD(unsigned char channel) //读取0 1 通道AD
{
    ATD0CTL5 = channel;  
    while(!ATD0STAT0_SCF);
    return ATD0DR0;
}

int GetOffset()
{
    char i,j;
    unsigned long temp = 0;
    //GYRO1
    for(j=0;j<100;j++)//采集100次
    {
        for(i=0;i<31;i++)//采集31次
            temp += ReadATD(CHANNEL_GYRO);                
        Delay_ms(5);//20ms
    }
    temp /= 64;
    GYRO_Vol = temp/100.0;//参考电压4.96V,496/1023/31/100 = /6400
    GYRO_Vol_Offset = GYRO_Vol;
    return 0;
}