ADC 简介
ADC(Analog-to-Digital Converter)是一种用于将连续的模拟信号转换为离散的数字信号的设备。在嵌入式系统中,ADC常常用于从传感器等模拟源采集数据,并将其转换为数字形式,以便进一步处理和分析。
DSP28335 ADC 特点
- 12位分辨率:ADC可以将模拟信号转换为12位的数字值,提供了相对较高的精度。
- 多通道支持:ADC模块通常支持多个模拟输入通道,可以同时对多个信号进行转换。
- 采样速率:ADC的采样速率取决于时钟设置和分辨率,可以调整以适应不同的应用需求。
- 中断支持:ADC转换完成后可以生成中断,用于通知处理器采样已经完成。
ADC 配置和使用
要使用DSP28335的ADC模块,通常需要进行以下步骤:
- 配置ADC时钟和分辨率:设置ADC时钟源和分辨率,以确定采样速率和精度。
- 配置输入通道:选择要进行转换的模拟输入通道,并设置增益、参考电压等参数。
- 配置中断(可选):如果需要在转换完成时得到通知,可以配置ADC中断。
- 启动转换:通过软件触发开始ADC转换。
- 等待转换完成:等待ADC转换完成,可以使用中断或轮询方式。
- 读取结果:一旦转换完成,可以读取转换结果,通常是一个数字值。
ADC初始化
#define ADC_MODCLK 0x3
#define ADC_CKPS 0x1
#define ADC_SHCLK 0xF
void ADC_Config()
{
AdcRegs.ADCTRL3.bit.ADCPWDN = 0x1; //启停模式
AdcRegs.ADCTRL3.bit.ADCBGRFDN = 0x3;
AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK; //ADC采样时间设置
AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS; //ADC内核分频
AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; //级联工作模式
AdcRegs.ADCTRL3.bit.SMODE_SEL = 0; //顺序采样
AdcRegs.ADCTRL1.bit.CONT_RUN = 0; //0-启停模式 1-连续模式
AdcRegs.ADCTRL1.bit.SEQ_OVRD = 1; //完成排序后
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 0x1; //打开SEQ1中断 允许向CPU发出中断 用于级联、双通道1
AdcRegs.ADCREFSEL.bit.REF_SEL = 0; //0-选择内部参考电压 1-选择外部参考电压
//ADC 十六通道采集
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; //通道与寄存器映射
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1;
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x2;
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x3;
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x4;
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x5;
AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x6;
AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x7;
AdcRegs.ADCCHSELSEQ3.bit.CONV08 = 0x8;
AdcRegs.ADCCHSELSEQ3.bit.CONV09 = 0x9;
AdcRegs.ADCCHSELSEQ3.bit.CONV10 = 0xA;
AdcRegs.ADCCHSELSEQ3.bit.CONV11 = 0xB;
AdcRegs.ADCCHSELSEQ4.bit.CONV12 = 0xC;
AdcRegs.ADCCHSELSEQ4.bit.CONV13 = 0xD;
AdcRegs.ADCCHSELSEQ4.bit.CONV14 = 0xE;
AdcRegs.ADCCHSELSEQ4.bit.CONV15 = 0xF;
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0xF; //设置通道数量
}
ADC十六通道的启停采样实验
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
#include "DSP2833x_Gpio.h"
#include "ADCConfig.h"
#define LED1 GpioDataRegs.GPADAT.bit.GPIO0
#define LED2 GpioDataRegs.GPADAT.bit.GPIO1
#define LED3 GpioDataRegs.GPADAT.bit.GPIO2
#define LED4 GpioDataRegs.GPADAT.bit.GPIO3
#define LED5 GpioDataRegs.GPADAT.bit.GPIO4
#define SAMPLE_SIZE 16 //采样通道数
volatile Uint16 sampleTable[SAMPLE_SIZE];
volatile float resultTable[SAMPLE_SIZE];
void configtestled(void);
void timer0_Init(void);
interrupt void timer0_isr(void); //timer0中断函数
void ADC_Task();
void main(void)
{
InitSysCtrl();
//initGpio();
InitXintf16Gpio();
DINT;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
configtestled();
ADC_Config();
timer0_Init();
while(1){
}
}
void configtestled(void)
{
EALLOW;
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0; // GPIO0复用为GPIO功能
GpioCtrlRegs.GPADIR.bit.GPIO0 = 1; // GPIO0设置为输出
GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 0; //
GpioCtrlRegs.GPADIR.bit.GPIO1 = 1;
GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 0; //
GpioCtrlRegs.GPADIR.bit.GPIO2 = 1;
GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 0; //
GpioCtrlRegs.GPADIR.bit.GPIO3 = 1;
GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 0; //
GpioCtrlRegs.GPADIR.bit.GPIO4 = 1;
EDIS;
}
void timer0_Init(void)
{
EALLOW;
PieVectTable.TINT0 = &timer0_isr; //定时器中断地址
EDIS;
InitCpuTimers();
ConfigCpuTimer(&CpuTimer0, 150, 1000); //定时为 1 ms
CpuTimer0Regs.TCR.all = 0x4001; //设置 TSS bit = 0
IER |= M_INT1; //CPU-Timer0 属于CPU INT1 使能
PieCtrlRegs.PIEIER1.bit.INTx7 = 1; //使能 TINT0 在 PIE 中 第七中断
EINT; //使能INTM中断
ERTM; //使能DBGM中断
}
interrupt void timer0_isr(void)
{
//清除中断标志
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1; //软件启动转换器
ADC_Task();
}
void ADC_Task()
{
int count = 0;
while(AdcRegs.ADCST.bit.INT_SEQ1 == 0);
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; //清楚INT_SEQ1标志位
//获取ADC采样数据
sampleTable[count++] = (AdcRegs.ADCRESULT0) >> 4;
sampleTable[count++] = (AdcRegs.ADCRESULT1) >> 4;
sampleTable[count++] = (AdcRegs.ADCRESULT2) >> 4;
sampleTable[count++] = (AdcRegs.ADCRESULT3) >> 4;
sampleTable[count++] = (AdcRegs.ADCRESULT4) >> 4;
sampleTable[count++] = (AdcRegs.ADCRESULT5) >> 4;
sampleTable[count++] = (AdcRegs.ADCRESULT6) >> 4;
sampleTable[count++] = (AdcRegs.ADCRESULT7) >> 4;
sampleTable[count++] = (AdcRegs.ADCRESULT8) >> 4;
sampleTable[count++] = (AdcRegs.ADCRESULT9) >> 4;
sampleTable[count++] = (AdcRegs.ADCRESULT10) >> 4;
sampleTable[count++] = (AdcRegs.ADCRESULT11) >> 4;
sampleTable[count++] = (AdcRegs.ADCRESULT12) >> 4;
sampleTable[count++] = (AdcRegs.ADCRESULT13) >> 4;
sampleTable[count++] = (AdcRegs.ADCRESULT14) >> 4;
sampleTable[count++] = (AdcRegs.ADCRESULT15) >> 4;
int i;
for(i = 0; i < SAMPLE_SIZE; i++)
{
resultTable[i] = (float)sampleTable[i] * 3.0 / 4096.0;
}
}
//===========================================================================
// No more.
//===========================================================================
实验结果
该数据为端口悬挂下随机生成的数据,但是可以看到数据会不断的刷新