记录::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();

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值