这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » PIC18F,ADC多通道采集,定时采集

共6条 1/1 1 跳转至

PIC18F,ADC多通道采集,定时采集

助工
2021-09-12 23:51:03     打赏

程序说明:


处理器: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转换 */

    }  

}




专家
2021-09-13 00:02:52     打赏
2楼

感谢楼主的分享,很实用了。


专家
2021-09-13 00:21:35     打赏
3楼

感谢楼主的提供,谢谢楼主。


专家
2021-09-13 08:23:05     打赏
4楼

PIC的单片机用的不多了吧


高工
2021-09-13 08:54:28     打赏
5楼

感谢楼主的分享


专家
2021-09-13 08:54:11     打赏
6楼

学习


共6条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]