记录::STC8H.ADC.[多路,自动,循环]采集-中断实现

adc.h

#ifndef __ADC_H__
#define __ADC_H__



void adcInit(void);

// #define SINGLE_ADC  
#define LOOP_ADC

#ifdef SINGLE_ADC
unsigned int adcStart(unsigned char channel);
#endif

#ifdef LOOP_ADC
typedef enum  
{
    USER_ADC_NAME_1 = 0,
    UAER_ADC_NAME_2,
    ADC_NAME_MAX,
}ADC_NAME_ENUM;
#define ADC_TABLE_SIZE  ADC_NAME_MAX

typedef struct 
{
    unsigned char channel;
    unsigned int adc_data;
}ADC_TABLE_TYPE;

extern ADC_TABLE_TYPE adc_table[ADC_TABLE_SIZE];
void adcIsrOpen(void);
unsigned int adcGet(unsigned char channel);
#endif

#endif

adc.c

#include "adc/adc.h"
#include "head_file/STC8H.h"

static volatile unsigned int adc_ret=0;

void adcInit(void)
{
    P_SW2 |= 0x80;
    ADCTIM = 0xff;      
    P_SW2 &= 0x7F;
    ADCCFG = 0x2f;      
    ADC_CONTR = 0x80;   //开启ADC电源
}

#ifdef SINGLE_ADC
unsigned int adcStart(unsigned char channel)
{
    ADC_CONTR = 0xc0+channel;
    while(!(ADC_CONTR&0x20));
    ADC_CONTR &= ~0x20;
    adc_ret = ADC_RES;
    return (adc_ret<<8) | ADC_RESL;;
}
#endif

#ifdef LOOP_ADC
//adc的循环通道数据{通道, 结果存放位置}
ADC_TABLE_TYPE adc_table[ADC_TABLE_SIZE] = {
    {0, 0}, //通道0
    {1, 1}, //通道1
};
static volatile unsigned char adc_sp = 0;
//开启adc中断,开启后自动启动循环转换
void adcIsrOpen(void)
{
    adc_sp = 0;
    EADC = 1;
    EA   = 1;
    ADC_CONTR |= (0xc0+adc_table[adc_sp].channel);
}
//中断
void adcIsr(void) interrupt 5
{
    ADC_CONTR &= ~0x2f;
    adc_ret = ADC_RES;
    adc_table[adc_sp].adc_data = ((adc_ret<<8) | ADC_RESL);
    adc_sp++;
    if(adc_sp>=2)
    {
        adc_sp = 0;
    }
    ADC_CONTR |= (0xc0+adc_table[adc_sp].channel);
}
//获取adc通道数值
//传入的通道不是直接的 单片机adc通道,而是adc_table数组的下标,
//实际的 adc通道 应当是 adc_table[channel].channel;
unsigned int adcGet(unsigned char channel)
{
    return adc_table[channel].adc_data;
}

// void adcIsrClose(void)
// {
//     EADC = 0;
//     EA   = 0;
// }
#endif

原理:

adc在中断模式中每次完成转换都会触发中断,在中断中切换adc通道并重新开始adc测量转换

 

使用:

adc.h 中:

在 ADC_NAME_ENUM 添加枚举(名字其实随意,只是用来标记adc通道,顺便获取数组最大值而已)

注意:需要在ADC_NAME_MAX前添加

typedef enum  
{
    USER_ADC_NAME_1 = 0,
    UAER_ADC_NAME_2,
    ADC_NAME_MAX,
}ADC_NAME_ENUM;

adc.c 中:

ADC_TABLE_TYPE adc_table[ADC_TABLE_SIZE] 内添加并初始化一个结构体,详情看结构体结构

ADC_TABLE_TYPE adc_table[ADC_TABLE_SIZE] = {
    {0, 0}, //通道0
    {1, 1}, //通道1
};

main.c 中:


    adcInit();
    adcIsrOpen();
posted @ 2025-01-17 00:23  FBshark  阅读(6)  评论(0编辑  收藏  举报