程序说明:
处理器:PIC18F66K80系列
系统频率:32M (外部晶振8M,4倍频得到)
通道:AN1,AN2,AN3
源文件
#include "bsp.h"
/*
*********************************************************************************************************
* 函 数 名: ADC_Init
* 功能说明: ADC初始化
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void ADC_Init()
{
TRISA = 0xFF; //PORTA as input
ANCON0 = 0X0F; //引脚配置为模拟通道
ADCON1 = 0x00; // 外部正参考电压,AVdd为负电压,模拟反相通道为AVss
ADCON2 = 0xAA; // FOSC/32 as conversion clock, Result is right justified,Aquisition time of 12 TAD
ADRESH = 0;
ADRESL = 0;
ADC_StartConversion(ADC_CHS_1);
}
/*
*********************************************************************************************************
* 函 数 名: ADC_GetConversionValue
* 功能说明: ADC读取
* 形 参: 无
* 返 回 值: ADC通道采集结果
*********************************************************************************************************
*/
uint16_t ADC_GetConversionValue()
{
uint16_t ADC_Result = 0;
// Conversion finished, return the result
ADC_Result = (uint16_t)ADRESH << 8|(ADRESL&0xE0);
return ADC_Result; //Returns Result
}
/*
*********************************************************************************************************
* 函 数 名: ADC_StartConversion
* 功能说明: ADC启动转换
* 形 参: channel,采集通道
* 返 回 值: 无
*********************************************************************************************************
*/
void ADC_StartConversion(uint8_t channel)
{
// select the A/D channel
ADCON0bits.CHS = channel;
// Turn on the ADC module
ADCON0bits.ADON = 1;
// Acquisition time delay
//__delay_us(ACQ_US_DELAY);
// Start the conversion
ADCON0bits.GO_NOT_DONE = 1;
}
头文件
/*
* File: adc.h
* Author: Administrator
*
* Created on 2017年7月11日, 下午4:33
*/
#ifndef ADC_H
#define ADC_H
#ifdef __cplusplus
extern "C" {
#endif
// 转换通道个数
#define ADC_CHS_NUM 3
#define ADC_SAMP_CNT 3
#define ACQ_US_DELAY 5//ADC采集延时时间
#define ADC_CHS_1 0x01//AN1采集通道
#define ADC_CHS_2 0x02//AN2采集通道
#define ADC_CHS_3 0x03//AN3采集通道
void ADC_Init();
uint16_t ADC_GetConversionValue();
void ADC_StartConversion(uint8_t channel);
#ifdef __cplusplus
}
#endif
#endif /* ADC_H */
应用函数
应用函数放在主循环定时1ms调用,1ms切换一次采集通道,1ms后读取上一通道的采集结果。
/*
*********************************************************************************************************
* 函 数 名: AdcPro
* 功能说明: ADC滤波处理
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void AdcPro(void)
{
static uint16_t buf[ADC_SAMP_CNT][ADC_CHS_NUM];
static uint8_t write;
static uint8_t index = ADC_CHS_1;
uint16_t sum;
uint8_t i;
if(index == ADC_CHS_1)//通道1采集
{
buf[write][ADC_CHS_1] = ADC_GetConversionValue();
/* 下面这段代码采用求平均值的方法进行滤波
也可以改善下,选择去掉最大和最下2个值,使数据更加精确
*/
sum = 0;
for (i = 0; i < ADC_SAMP_CNT; i++)
{
sum += buf[i][ADC_CHS_1];
}
SysRunData.ADC_Buf[ADC_CHS_1] = sum / ADC_SAMP_CNT; /* ADC采样值由若干次采样值平均 */
index = ADC_CHS_2;
ADC_StartConversion(ADC_CHS_2); /* 软件启动下次ADC转换 */
}
else if(index == ADC_CHS_2)//通道2采集
{
buf[write][ADC_CHS_2] = ADC_GetConversionValue();
/* 下面这段代码采用求平均值的方法进行滤波
也可以改善下,选择去掉最大和最下2个值,使数据更加精确
*/
sum = 0;
for (i = 0; i < ADC_SAMP_CNT; i++)
{
sum += buf[i][ADC_CHS_2];
}
SysRunData.ADC_Buf[ADC_CHS_2] = sum / ADC_SAMP_CNT; /* ADC采样值由若干次采样值平均 */
index = ADC_CHS_3;
ADC_StartConversion(ADC_CHS_3); /* 软件启动下次ADC转换 */
}
else if(index == ADC_CHS_3)//通道3采集
{
buf[write][ADC_CHS_3] = ADC_GetConversionValue();
/* 下面这段代码采用求平均值的方法进行滤波
也可以改善下,选择去掉最大和最下2个值,使数据更加精确
*/
sum = 0;
for (i = 0; i < ADC_SAMP_CNT; i++)
{
sum += buf[i][ADC_CHS_3];
}
SysRunData.ADC_Buf[ADC_CHS_3] = sum / ADC_SAMP_CNT; /* ADC采样值由若干次采样值平均 */
if (++write >= ADC_SAMP_CNT)
{
write = 0;
}
index = ADC_CHS_1;
ADC_StartConversion(ADC_CHS_1); /* 软件启动下次ADC转换 */
}
}