老笨来讲讲dsp28335的ADC的最基本用法。
先来看看硬件电路连接图:
程序
#include "DSP28x_Project.h"
#define ADC_CKPS 0x1 // ADC module clock = HSPCLK/2*ADC_CKPS = 25.0MHz/(1*2) = 12.5MHz
#define ADC_SHCLK 0xf // S/H width in ADC module periods = 16 ADC clocks
#define BUFF_SIZE 4
Uint16 SampleTable[BUFF_SIZE];
main()
{
Uint16 i;
InitSysCtrl();
EALLOW; //允许编辑受保护的寄存器
SysCtrlRegs.HISPCP.all = 0x3; //HSPCLK = SYSCLKOUT/6 = 25.0 MHz
EDIS; //禁止编辑
DINT; //关中断
InitPieCtrl(); //复位PIE控制寄存器为0
IER = 0x0000; //清除所有CPU中断标识
IFR = 0x0000;
InitPieVectTable(); //初始化中断向量表
InitAdc(); //开启ADC时钟,校准,ADC电路上电
AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK;
AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS;
AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; //1 级联模式
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 3; //设置最大通道数为n + 1,从通道0开始,按照顺序算
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; //通道(管脚)选择 ADCINA0
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1; //ADCINA1
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x8; //ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x9; //ADCINB1
AdcRegs.ADCTRL1.bit.CONT_RUN = 1; //连续运行模式
AdcRegs.ADCTRL2.all = 0x2000; //1 << 13; Start SEQ1. 级联模式下不需要开启SEQ2
for(i = 0; i < BUFF_SIZE; i++)
{
SampleTable[i] = 0;
}
for(;;)
{
while (AdcRegs.ADCST.bit.INT_SEQ1 == 0) {} //等待转换完成,级联不需要等待INT_SEQ2
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; //清除中断标识
SampleTable[0] = AdcRegs.ADCRESULT0>>4;
SampleTable[1] = AdcRegs.ADCRESULT1>>4;
SampleTable[2] = AdcRegs.ADCRESULT2>>4;
SampleTable[3] = AdcRegs.ADCRESULT3>>4;
}
}
程序解析
SysCtrlRegs.HISPCP.all = 0x3;
这个时钟的设置请看下图
再来看看是如何选择管脚的。dsp28335有1个12位adc共16个通道CONV00-CONV15,分为四个组,
ADCCHSELSEQ1-4,对应的管脚为ADCINA0-ADCINA7,ADCINB0-ADCINB7,在级联模式下就直
接设置对应的数值即可,现在仔细体会以下代码,应该不难理解:
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 3; //设置最大通道数为n + 1,从通道0开始,按照顺序算
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; //管脚为ADCINA0,转换结果在AdcRegs.ADCRESULT0
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1; //ADCINA1,AdcRegs.ADCRESULT1
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x8; //ADCINB0,AdcRegs.ADCRESULT2
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x9; //ADCINB1,AdcRegs.ADCRESULT3
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0xa; //ADCINB1,AdcRegs.ADCRESULT4
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x1; //ADCINA1,AdcRegs.ADCRESULT5
AdcRegs.ADCCHSELSEQ3.bit.CONV08 = 0xe; //ADCINB6,AdcRegs.ADCRESULT8
AdcRegs.ADCCHSELSEQ4.bit.CONV12 = 0xf; //ADCINB7,AdcRegs.ADCRESULT12
注意一下MAX_CONV1 = 3,最大通道数为3 + 1 = 4通道,也就是只转换CONV00,CONV01,CONV02,CONV03,结果存在ADCRESULT0-3中,ADCRESULT4及往后读出来为零。以此类推,MAX_CONV1 = 6,则只转换CONV00-CONV06。
观察结果
打开Expression窗口,添加SampleTable变量观察。用一字螺丝刀调节变阻器,可以看到数值相应变化。
好,老笨就说到这了。