恩智浦 飞思卡尔Freescale Kinetis KEA128学习笔记4——ADC

KEA128的ADC有8个寄存器

恩智浦 飞思卡尔Freescale Kinetis KEA128学习笔记4——ADC_第1张图片

 

ADC编程基本步骤:

1.打开ADC模块时钟

2.开启ADC_APCTL1引脚控制寄存器相应引脚的AD功能(即关闭这些引脚的IO功能)

3.配置ADC_SC3寄存器的总线时钟,时钟分频,并根据采样精度定ADC_SC3_MODE位

4.配置ADC_SC2寄存器的软件触发位,比较功能禁用,默认外部参考电压Vrefh和Vrefl。

5.配置ADC_SC1寄存器的ADC模块使能和连续转换使能。选择采样通道。

6.等待转换完成

7.读取结果(读取之后转换完成标志位会自动清零)

恩智浦 飞思卡尔Freescale Kinetis KEA128学习笔记4——ADC_第2张图片

 

恩智浦 飞思卡尔Freescale Kinetis KEA128学习笔记4——ADC_第3张图片

恩智浦 飞思卡尔Freescale Kinetis KEA128学习笔记4——ADC_第4张图片

恩智浦 飞思卡尔Freescale Kinetis KEA128学习笔记4——ADC_第5张图片

恩智浦 飞思卡尔Freescale Kinetis KEA128学习笔记4——ADC_第6张图片

 

//===========================================================================
//文件名称:adc.h
//功能概要:adc底层驱动构件头文件
//版权所有:苏州大学飞思卡尔嵌入式中心(sumcu.suda.edu.cn)
//更新记录:2015-05-11
//===========================================================================

#ifndef _ADC_H         //防止重复定义( 开头)
#define _ADC_H

#include "common.h"    //包含公共要素头文件


//===========================================================================
//函数名称:adc_init
//功能概要:初始化adc模块                                                
//参数说明:channel:通道号
//       accurary采样精度:单端8-10-12
//===========================================================================
void adc_init(uint_8 channel,uint_8 accurary);

//===========================================================================
//函数名称:adc_read
//功能概要:进行一次AD采样
//参数说明:channel:单端输入 通道范围 0~ 31
//===========================================================================
uint_16 adc_readonce(uint_8 channel);

//============================================================================
//函数名称:ad_mid
//函数返回:16位无符号的AD值,中值滤波后的结果(范围:0-4095)
//参数说明:channel:通道号
//功能概要:采样三次,取中值
//============================================================================
uint_16 adc_mid(uint_8 channel);

//============================================================================
//函数名称:ad_ave
//函数返回:16位无符号的AD值,中值+均值滤波后的结果(范围:0~4095)
//参数说明:channel:通道号
//      N:均值次数(范围:0~255),每次调用中值滤波获得
//功能概要:中值+均值滤波,实际采样次数=3*N
//============================================================================
uint_16 adc_ave(uint_8 channel, int N);

#endif                 //防止重复定义( 开头)

//===========================================================================
//声明:
//(1)我们开发的源代码,在本中心提供的硬件系统测试通过,真诚奉献给社会,不足之处,
//     欢迎指正。
//(2)对于使用非本中心硬件系统的用户,移植代码时,请仔细根据自己的硬件匹配。
//
//苏州大学飞思卡尔嵌入式中心(苏州华祥信息科技有限公司)
//技术咨询:0512-65214835  http://sumcu.suda.edu.cn
//业务咨询:0512-87661670,18915522016  http://www.hxtek.com.cn

 

 

//===========================================================================
//文件名称:adc.c
//功能概要:ADC底层驱动构件源文件
//版权所有:苏州大学飞思卡尔嵌入式中心(sumcu.suda.edu.cn)
//更新记录:2015-05-11   V1.0
//===========================================================================
#include "adc.h"

//===========================================================================
//函数名称:adc_init
//功能概要:初始化一个AD转换通道
//参数说明:channel:通道号
//       accurary:单端采样精度8-10-12
//===========================================================================

void adc_init(uint_8 channel,uint_8 accurary)
{
    //1.打开ADC模块时钟
    SIM_SCGC |= SIM_SCGC_ADC_MASK;
    //开启引脚的AD功能
    ADC_APCTL1 |=0x0F;
    //选择总线时钟
    ADC_SC3 = (ADC_SC3 & ~ADC_SC3_ADICLK_MASK) | ADC_SC3_ADICLK(0b00);
    //输入时钟4分频
    ADC_SC3 = (ADC_SC3 & ~ADC_SC3_ADIV_MASK) | ADC_SC3_ADIV(0b10);
    //2.2 根据采样精度   定ADC_SC3_MODE位
    switch(accurary)
    {
        case 8:
            ADC_SC3 |= ADC_SC3_MODE(0);      //选择8位转换模式
            break;
        case 10:
            ADC_SC3 |= ADC_SC3_MODE(1);      //选择10位转换模式
            break;
        case 12:
            ADC_SC3 |= ADC_SC3_MODE(2);      //选择12位转换模式
            break;
        default:
            ADC_SC3 |= ADC_SC3_MODE(2);       //选择12位转换模式
            break;
    }
    //3.配置ADC_SC2:软件触发,比较功能禁用;默认外部参考电压 VREFH/VREFL
    ADC_SC2 = 0x00;
    //4.配置ADC_SC1:使能ADC,并设置为连续转换模式,使能外部引脚
    ADC_SC1|= ADC_SC1_ADCO_MASK;
    //选择采样通道
    ADC_SC1|=ADC_SC1_ADCH(channel);
}

//============================================================================
//函数名称:adc_readonce
//功能概要:对AD通道进行一次采样
//参数说明:channel:通道范围 0~31
//============================================================================
uint_16 adc_readonce(uint_8 channel)
{
    uint_16 ADCResult = 0;
    //设置SC1寄存器通道号
    ADC_SC1 = (ADC_SC1 & ~ADC_SC1_ADCH_MASK) | ADC_SC1_ADCH(channel);
    
    //等待转换完成
    while(!(ADC_SC1 & ADC_SC1_COCO_MASK));

    //读取转换结果
    ADCResult = (uint_16)ADC_R;
    //清ADC转换完成标志
    ADC_SC1 &= ~ADC_SC1_COCO_MASK;
    //返回读取结果
    return ADCResult;
}
//============================================================================
//函数名称:ad_mid
//函数返回:16位无符号的AD值,中值滤波后的结果(范围:0-4095)
//参数说明:channel:通道号
//功能概要:采样三次,取中值
//============================================================================
uint_16 adc_mid(uint_8 channel)
{
	uint16_t i,j,k,tmp;
	//1.取3次A/D转换结果
	i = adc_readonce(channel);
	j = adc_readonce(channel);
	k = adc_readonce(channel);
	//2.取中值
	if (i > j)
	{
	    tmp = i; i = j; j = tmp;
	}
	if (k > j)
	  tmp = j;
	else if(k > i)
	  tmp = k;
    else
      tmp = i;
	return tmp;
}

//============================================================================
//函数名称:ad_ave
//函数返回:16位无符号的AD值,中值+均值滤波后的结果(范围:0~4095)
//参数说明:channel:通道号
//      N:均值次数(范围:0~255),每次调用中值滤波获得
//功能概要:中值+均值滤波,实际采样次数=3*N
//============================================================================
uint_16 adc_ave(uint_8 channel, int N)
{

	long int i;
	float tmp;
    int  j;

    i=0;
    for(j = 0; j < N; j++) i=i+(long int)adc_mid(channel);
    tmp =i / N;

    return (uint_16)tmp;
}

MAIN

//说明见工程文件夹下的Doc文件夹内Readme.txt文件
#include "includes.h"

int main(void)
 {
    //1. 声明主函数使用的变量
    uint_32 mRuncount;     //主循环计数器
    uint_16 ADCResult[8];   //存放AD结果
    int i;
    //2. 关总中断
    DISABLE_INTERRUPTS;
    //3. 初始化外设模块
    uart_init (UART_2, 9600);        //波特率使用9600
    light_init(LIGHT_RED, LIGHT_OFF);     //初始化灯0
    //light_init(RUN_LIGHT_1, LIGHT_OFF);     //初始化灯1
    //light_init(RUN_LIGHT_2, LIGHT_OFF);     //初始化灯2
    //light_init(RUN_LIGHT_3, LIGHT_OFF);     //初始化灯3
    adc_init(1,10);      //初始化,通道,采样精度
    adc_init(2,12);      //初始化,通道,采样精度
    adc_init(3,12);      //初始化,通道,采样精度
    printf("Hello Uart! 2015-5-11\r\n"); //串口发送初始化提示
    //4. 给有关变量赋初值
    mRuncount = 0;            //主循环计数器
    //5. 使能模块中断
    uart_enable_re_int(UART_2);   //使能串口2接收中断
    //6. 开总中断
    ENABLE_INTERRUPTS;

    //进入主循环
    //主循环开始==================================================================
    for (;;) {
        //运行指示灯闪烁-----------------------------------------------
        mRuncount++;               //主循环次数计数器+1
        if (mRuncount >= RUN_COUNTER_MAX)  //主循环次数计数器大于设定的宏常数
        {
            mRuncount = 0;           //主循环次数计数器清零
            light_change(LIGHT_RED);      //灯0(RUN_LIGHT_0)状态变化
            //light_change(RUN_LIGHT_1);      //灯1(RUN_LIGHT_1)状态变化
            //light_change(RUN_LIGHT_2);      //灯2(RUN_LIGHT_2)状态变化
            //light_change(RUN_LIGHT_3);      //灯3(RUN_LIGHT_3)状态变化
            //以下加入用户程序----------------------------------------------
            //进行一次各个通道采样
            ADCResult[0] = adc_readonce(0);
            ADCResult[1] = adc_readonce(1);
            ADCResult[2] = adc_readonce(2);
            ADCResult[3] = adc_readonce(3);
            ADCResult[4] = adc_mid(4);
            ADCResult[5] = adc_mid(5);
            ADCResult[6] = adc_ave(6,10);
            ADCResult[7] = adc_ave(7,30);
            //芯片温度采集通道
//            temp=(adc_read(22)*5000)>>10;
//            VTemp=25-(temp-1396)/3.638;
//            //将采集的A/D值通过串口发送到PC
//             //1字节=8位,ADCResult的长度16*16位=16*2字节=32字节
            for(i=0;i<8;i++)
            {
            printf("%d\t",ADCResult[i]);
            }
            printf("\n");
//            printf("%d.",(uint_16)VTemp);
//            printf("%d\r\n",(uint_16)((VTemp-(uint_16)VTemp)*100));
        }

    }  //主循环end_for
       //主循环结束==========================================================
}

 

你可能感兴趣的:(KEA128)