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