KEA128的ADC有8个寄存器
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.读取结果(读取之后转换完成标志位会自动清零)
//===========================================================================
//文件名称: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
//主循环结束==========================================================
}