零基础DSP实战TMS320F28035:第七节,模数转换ADC实战
一、TMS320F28035 ADC
本节述及的 ADC 模块是一个12位的循环式 ADC ,。该 A / D 转换器的模拟电路,下文称之为"内核",包括前端模拟多路复用器( MUX ),采样和保持( S / H )电路,转换内核,稳压器,以及其他模拟支持电路。数字电路、本章称之为"外包装",包括可编程转换器,结果寄存器,模拟电路接口,外设总线接口以及与其他片上模块的接口。
二、ADC模数转换介绍
ADC 模块的功能包括:
● 内置双采样保持电路的12位 ADC 内核。
● 同步采样或顺序采样模式。
全范围模拟量输人:固定0~3.3V(内置),或 VREFHI / VREFLO 比例输入
(外加)。
● 运行于完整的系统时钟频率,无需分频。
● 多达16通道的多路输入。
● 16个可进行触发源、采样窗以及通道配置的 SOCx 。
● 有16个结果寄存器(每个均可单独寻址)用于存储转换值。
● 多种触发源,包括:
-S / W ﹣软件立即启动( software immediate start )。
-EPWM1-7 SOCA 及 SOCB ;
-GPIO XINT2;
ADC定时器0/1/2中断。
ADCINT1/2
● 9个灵活的PIE中断,可以配置任何转换后的中断请求。
二、ADC配置步骤
1.打开时钟与ADC功能初始化
代码如下(示例):
直接引用库函数,注意代码中的注释说明。
// EALLOW;
//打开ADC时钟
// SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;
// (*Device_cal)();
// EDIS;
//
// EALLOW;
//打开ADC模拟电压供电
// AdcRegs.ADCCTL1.bit.ADCBGPWD = 1; // Power ADC BG
// AdcRegs.ADCCTL1.bit.ADCREFPWD = 1; // Power reference
// AdcRegs.ADCCTL1.bit.ADCPWDN = 1; // Power ADC
// AdcRegs.ADCCTL1.bit.ADCENABLE = 1; // Enable ADC
//打开ADC基准源,这里我们选择内部基准源VREF
// AdcRegs.ADCCTL1.bit.ADCREFSEL = 0; // Select interal BG
// EDIS;
InitAdc();//函数中关键语句为上述几条
2.ADC应用配置
(1)配置ADCCTL1寄存器
(2)配置INTSEL1N2寄存器
(3)配置ADC触发源
(4)配置采集顺序
(5)配置采集速度
(6)中断配置
(7)中断服务函数
EALLOW;
AdcRegs.ADCCTL1.bit.INTPULSEPOS= 1; //中断短脉冲在转换完成产生,规定中断产生脉冲产生的实时机
AdcRegs.ADCCTL1.bit.TEMPCONV = 1; //ADCA5内部温度采集,内部采样接到内部ADCA5采样端口
AdcRegs.ADCCTL1.bit.VREFLOCONV = 1; //ADCB5连接到VREFLO,我们使用的是内部基准源,故此引脚用作ADC采集端口
AdcRegs.INTSEL1N2.bit.INT1E = 1; //Enabled ADCINT1,使能ADC中断
AdcRegs.INTSEL1N2.bit.INT1CONT = 0; //Disable ADCINT1 Continuous mode
AdcRegs.INTSEL1N2.bit.INT1SEL = 6; //EOC中断源的选择6,也就是SOC6选择的引脚转换结束后产生的EOC作为中断源
AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 0x02; //采样触发源的选择定时器1,以下转换源均为定时器1
AdcRegs.ADCSOC1CTL.bit.TRIGSEL = 0x02;
AdcRegs.ADCSOC2CTL.bit.TRIGSEL = 0x02;
AdcRegs.ADCSOC3CTL.bit.TRIGSEL = 0x02;
AdcRegs.ADCSOC4CTL.bit.TRIGSEL = 0x02;
AdcRegs.ADCSOC5CTL.bit.TRIGSEL = 0x02;
AdcRegs.ADCSOC6CTL.bit.TRIGSEL = 0x02;
AdcRegs.ADCSOC7CTL.bit.TRIGSEL = 0x02;
AdcRegs.ADCSOC8CTL.bit.TRIGSEL = 0x02;
AdcRegs.ADCSOC9CTL.bit.TRIGSEL = 0x02;
// AdcRegs.ADCSOC10CTL.bit.TRIGSEL= 0x02;
// AdcRegs.ADCSOC11CTL.bit.TRIGSEL= 0x02;
// AdcRegs.ADCSOC12CTL.bit.TRIGSEL= 0x02;
// AdcRegs.ADCSOC13CTL.bit.TRIGSEL= 0x02;
// AdcRegs.ADCSOC14CTL.bit.TRIGSEL= 0x02;
// AdcRegs.ADCSOC15CTL.bit.TRIGSEL= 0x02;
//同步/单独采样方法,规定SOC0/1==SOC2/3==SOC4/5==SOC6/7……每一对儿是独立采样还是同事采样
AdcRegs.ADCSAMPLEMODE.bit.SIMULEN0 = 1; //采样模式选择,同步采样
AdcRegs.ADCSAMPLEMODE.bit.SIMULEN2 = 1; //采样模式选择,同步采样
AdcRegs.ADCSAMPLEMODE.bit.SIMULEN4 = 1; //采样模式选择,同步采样
AdcRegs.ADCSAMPLEMODE.bit.SIMULEN6 = 0; //采样模式选择,独立采样
AdcRegs.ADCSAMPLEMODE.bit.SIMULEN8 = 0; //采样模式选择,独立采样
// AdcRegs.ADCSAMPLEMODE.bit.SIMULEN10 = 0;
// AdcRegs.ADCSAMPLEMODE.bit.SIMULEN12 = 0;
// AdcRegs.ADCSAMPLEMODE.bit.SIMULEN14 = 0;
//设置SOC同步采样时必须选择是Ax和Bx序号一致的ADC端口,才能进行同步采样
AdcRegs.ADCSOC0CTL.bit.CHSEL = 1; //同步 采样采样通道选择A1
AdcRegs.ADCSOC1CTL.bit.CHSEL = 1; //同步 采样采样通道选择B1
AdcRegs.ADCSOC2CTL.bit.CHSEL = 3; //同步 采样采样通道选择A3
AdcRegs.ADCSOC3CTL.bit.CHSEL = 3; //同步 采样采样通道选择B3
AdcRegs.ADCSOC4CTL.bit.CHSEL = 7; //同步 采样采样通道选择A7
AdcRegs.ADCSOC5CTL.bit.CHSEL = 7; //同步 采样采样通道选择B7
AdcRegs.ADCSOC6CTL.bit.CHSEL = 5; //独立 采样采样通道选择A5
AdcRegs.ADCSOC7CTL.bit.CHSEL = 12; //独立 采样采样通道选择B4
AdcRegs.ADCSOC8CTL.bit.CHSEL = 14; //独立 采样采样通道选择B6
// AdcRegs.ADCSOC10CTL.bit.CHSEL= X;
// AdcRegs.ADCSOC11CTL.bit.CHSEL= X;
// AdcRegs.ADCSOC12CTL.bit.CHSEL= X;
// AdcRegs.ADCSOC13CTL.bit.CHSEL= X;
// AdcRegs.ADCSOC14CTL.bit.CHSEL= X;
// AdcRegs.ADCSOC15CTL.bit.CHSEL= X;
//通过上述寄存器 ADCSAMPLEMODE 和 ADCSOC0CTL.bit.CHSEL 配置
//我们将的采样对应关系为:
// SOC0 ==> A1
// SOC1 ==> B1
//
// SOC2 ==> A3
// SOC3 ==> B3
//
// SOC4 ==> A7
// SOC5 ==> B7
//
// SOC6 ==> A5
//
// SOC7 ==> B4
//
// SOC8 ==> B6
AdcRegs.ADCSOC0CTL.bit.ACQPS = 6; //采集速度选择最快的
AdcRegs.ADCSOC1CTL.bit.ACQPS = 6; //采集速度选择最快的
AdcRegs.ADCSOC2CTL.bit.ACQPS = 6; //采集速度选择最快的
AdcRegs.ADCSOC3CTL.bit.ACQPS = 6; //采集速度选择最快的
AdcRegs.ADCSOC4CTL.bit.ACQPS = 6; //采集速度选择最快的
AdcRegs.ADCSOC5CTL.bit.ACQPS = 6; //采集速度选择最快的
AdcRegs.ADCSOC6CTL.bit.ACQPS = 6; //采集速度选择最快的
AdcRegs.ADCSOC7CTL.bit.ACQPS = 6; //采集速度选择最快的
AdcRegs.ADCSOC8CTL.bit.ACQPS = 6; //采集速度选择最快的
AdcRegs.ADCSOC9CTL.bit.ACQPS = 6; //采集速度选择最快的
//定义中断服务函数
PieVectTable.ADCINT1 = &adc_isr;
//打开中断向量
PieCtrlRegs.PIEIER1.bit.INTx1 = 1;
IER |= M_INT1;
二、ADC应用
1.工程介绍
(1)工程中我们使用了ADC中断;
(2)采集顺序采用了有同步有顺序的采样方式;
(3)我们采用的定时器1 的触发源;
(4)工程中增加sys_adc.h和sys_adc.c,与之前的章节配置工程方式一致;
(5)在ADC中断服务函数中获取采集到的ADC结果,示例代码与调试结果如下
interrupt void adc_isr(void)
{
AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //清中断标志
AdcRegs.ADCINTOVFCLR.bit.ADCINT1 = 1; //清溢出中断标志
//=================================================================
D402TOGGLE();
//adc采样结果的获取,ADC缓冲区位ADCRESULTx
adc_result[0] = AdcResult.ADCRESULT0; // Read the ANA1 conversion result
adc_result[1] = AdcResult.ADCRESULT1; // Read the ANB1 conversion result
adc_result[2] = AdcResult.ADCRESULT2; // Read the ANA3 conversion result
adc_result[3] = AdcResult.ADCRESULT3; // Read the ANB3 conversion result
adc_result[4] = AdcResult.ADCRESULT4; // Read the ANA7 conversion result
adc_result[5] = AdcResult.ADCRESULT5; // Read the ANB7 conversion result
adc_result[6] = AdcResult.ADCRESULT6; // Read the ANA5 conversion result
adc_result[7] = AdcResult.ADCRESULT7; // Read the ANB4 conversion result
adc_result[8] = AdcResult.ADCRESULT8; // Read the ANB6 conversion result
//=================================================================
PieCtrlRegs.PIEACK.bit.ACK1 = 1; //使能别的中断
}
下图可以观察到获取的ADC数值在程序运行时一直发生变化,我们这里默认采样结果正常,因为当前没有给一些接力信号。
总结
在实际应用时,ADC采样的时机、触发源、采样结果的处理、与程序稳定性有非常强的关系,实际应用时应多慎重考虑,根据产品特点,制定合适的设计方案。