TMS320F2803x、TMS320F2806x ADC开发笔记
ADC模块框图
SOC结构
中断结构
ADC转换时序
直接上代码
- ADC.C文件如下:
/*
* 粗略的延时函数,大于或等于1ms
*/
void delayUs(Uint16 n)
{
Uint16 i;
Uint32 j;
for(i=0;i<n;i++)
for (j = 0; j < 90; j++); //>= 1us
}
/*
* ADC模块初始化
*/
void ADC_Init(void)
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;//使能ADC时钟
(*Device_cal)();//调用在boot ROM中的校准ADC和内部振荡器的
EDIS;
EALLOW;
AdcRegs.ADCCTL1.bit.ADCPWDN=1;//1-给核心内部的模拟电路通电
AdcRegs.ADCCTL1.bit.ADCBGPWD=1;//1-给带隙缓冲器核心内的电路通电
AdcRegs.ADCCTL1.bit.ADCREFPWD=1;//1-给核心内部的参考缓冲电路通电
AdcRegs.ADCCTL1.bit.ADCENABLE=1;//1-启用ADC。必须在ADC转换前设置(建议在设置ADC上电位后直接设置)
AdcRegs.ADCCTL1.bit.ADCREFSEL = 0; //选择内部的参考电源
EDIS;
delayUs(1000);//在转换前需要经过1ms延时
//设置ADC时钟 = SYSCLK/2 // CLKDIV2EN | CLKDIV4EN | ADCCLK
EALLOW; //------------------------------------
AdcRegs.ADCCTL2.bit.CLKDIV2EN=1; // 0 | 0 | SYSCLK
AdcRegs.ADCCTL2.bit.CLKDIV4EN=0; // 0 | 1 | SYSCLK
EDIS; // 1 | 0 | SYSCLK/2
// 1 | 1 | SYSCLK/4
delayUs(1000);//Delay before converting ADC channels
}
/*
* ADC 通道初始化 以及 IO初始化
*/
void InitAdcConfigAndIO(void)
{
EALLOW;
/* Configure ADC pins using AIO regs*/
//AIOx Pin总是连通着ADC Channel x和/Comparator input x,不需要额外设置
//但是有些AIOx需要关闭它的IO输入输出路径,以防止影响采集
GpioCtrlRegs.AIOMUX1.bit.AIO2 =2;//bit5:4, 00/01时,AIO2 enabled;10/11时,AIO2 disabled (default)
GpioCtrlRegs.AIOMUX1.bit.AIO4 =2;
GpioCtrlRegs.AIOMUX1.bit.AIO6 =2;
GpioCtrlRegs.AIOMUX1.bit.AIO10 =2;
GpioCtrlRegs.AIOMUX1.bit.AIO12 =2;
GpioCtrlRegs.AIOMUX1.bit.AIO14 =2;
AdcRegs.ADCCTL2.bit.ADCNONOVERLAP=0;//1-Overlap of sample is not allowed
//0-Overlap of sample and conversion is allowed
AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1;//0-当ADC开始转换时产生INT脉冲
//1-INT脉冲生成发生在ADC结果锁存到其结果寄存器之前的1个周期
AdcRegs.ADCINTFLGCLR.all=0x1ff; //清除ADCINT1-9的中断标志
AdcRegs.ADCINTOVFCLR.all=0X1FF; //清除1-9的中断溢出标志,连续模式下可以忽略,因为连续模式溢出时会重头开始启动转换。
//(如果设置了相应的ADCINTFLG位,并且生成了选择的额外EOC触发器,则会发生溢出条件。)
AdcRegs.INTSEL1N2.all=0; //禁用ADCINT1、2
AdcRegs.INTSEL1N2.bit.INT1CONT=0;//0-在ADCINTy标志(在ADCINTFLG寄存器中)被用户清除之前,不会产生更多的ADCINTy脉冲。
AdcRegs.INTSEL1N2.bit.INT2CONT=0;//1-无论是否清除标志位,只要产生EOC脉冲,就会产生ADCINTy脉冲。(连续模式)
AdcRegs.INTSEL1N2.bit.INT1E=1;//启用ADCINT1
AdcRegs.INTSEL1N2.bit.INT2E=0;//禁用ADCINT2
AdcRegs.INTSEL1N2.bit.INT1SEL=0x0f;//EOC15触发ADCINT1
AdcRegs.INTSEL1N2.bit.INT2SEL=0;//EOC0触发ADCINT2
AdcRegs.INTSEL3N4.all=0; //禁用ADCINT3、4
AdcRegs.INTSEL5N6.all=0; //禁用ADCINT5、6
AdcRegs.INTSEL7N8.all=0; //禁用ADCINT7、8
AdcRegs.INTSEL9N10.all=0; //禁用ADCINT9
AdcRegs.SOCPRICTL.all=0; //关于优先级等配置
AdcRegs.ADCSAMPLEMODE.all=0; //全部设置为顺序采样模式
AdcRegs.ADCINTSOCSEL1.all=0; //无ADCINT触发SOC
AdcRegs.ADCINTSOCSEL2.all=0;
EDIS;
}
/*
*CH_sel - 通道号
*ACQPS_Value - 采样窗口值
*Trig_Sel - ADC转换的触发源选择
*return mean - 返回采样16次CH_sel的ADC值的平均值
*/
Uint32 GetChResult(Uint16 CH_sel,Uint8 ACQPS_Value,Uint8 Trig_Sel)
{
Uint32 mean=0;
EALLOW;
AdcRegs.ADCSOC0CTL.bit.TRIGSEL=Trig_Sel;//0-只允许软件触发
AdcRegs.ADCSOC1CTL.bit.TRIGSEL=Trig_Sel;
AdcRegs.ADCSOC2CTL.bit.TRIGSEL=Trig_Sel;
AdcRegs.ADCSOC3CTL.bit.TRIGSEL=Trig_Sel;
AdcRegs.ADCSOC4CTL.bit.TRIGSEL=Trig_Sel;
AdcRegs.ADCSOC5CTL.bit.TRIGSEL=Trig_Sel;
AdcRegs.ADCSOC6CTL.bit.TRIGSEL=Trig_Sel;
AdcRegs.ADCSOC7CTL.bit.TRIGSEL=Trig_Sel;
AdcRegs.ADCSOC8CTL.bit.TRIGSEL=Trig_Sel;
AdcRegs.ADCSOC9CTL.bit.TRIGSEL=Trig_Sel;
AdcRegs.ADCSOC10CTL.bit.TRIGSEL=Trig_Sel;
AdcRegs.ADCSOC11CTL.bit.TRIGSEL=Trig_Sel;
AdcRegs.ADCSOC12CTL.bit.TRIGSEL=Trig_Sel;
AdcRegs.ADCSOC13CTL.bit.TRIGSEL=Trig_Sel;
AdcRegs.ADCSOC14CTL.bit.TRIGSEL=Trig_Sel;
AdcRegs.ADCSOC15CTL.bit.TRIGSEL=Trig_Sel;
AdcRegs.ADCSOC0CTL.bit.ACQPS = ACQPS_Value;//设置采样窗口值
AdcRegs.ADCSOC1CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC2CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC3CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC4CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC5CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC6CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC7CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC8CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC9CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC10CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC11CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC12CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC13CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC14CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC15CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC0CTL.bit.CHSEL=CH_sel;//通道选择
AdcRegs.ADCSOC1CTL.bit.CHSEL=CH_sel;
AdcRegs.ADCSOC2CTL.bit.CHSEL=CH_sel;
AdcRegs.ADCSOC3CTL.bit.CHSEL=CH_sel;
AdcRegs.ADCSOC4CTL.bit.CHSEL=CH_sel;
AdcRegs.ADCSOC5CTL.bit.CHSEL=CH_sel;
AdcRegs.ADCSOC6CTL.bit.CHSEL=CH_sel;
AdcRegs.ADCSOC7CTL.bit.CHSEL=CH_sel;
AdcRegs.ADCSOC8CTL.bit.CHSEL=CH_sel;
AdcRegs.ADCSOC9CTL.bit.CHSEL=CH_sel;
AdcRegs.ADCSOC10CTL.bit.CHSEL=CH_sel;
AdcRegs.ADCSOC11CTL.bit.CHSEL=CH_sel;
AdcRegs.ADCSOC12CTL.bit.CHSEL=CH_sel;
AdcRegs.ADCSOC13CTL.bit.CHSEL=CH_sel;
AdcRegs.ADCSOC14CTL.bit.CHSEL=CH_sel;
AdcRegs.ADCSOC15CTL.bit.CHSEL=CH_sel;
EDIS;
delayUs(10);
if(Trig_Sel==0)AdcRegs.ADCSOCFRC1.all=0xffff; //软件触发SOC1-S0C15转换
#if Interrupt_Allow==0
//Wait for ADCINT1 to trigger, then add ADCRESULT0-15 registers to sum
while (AdcRegs.ADCINTFLG.bit.ADCINT1 == 0);
AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//Must clear ADCINT1 flag since INT1CONT = 0
//AdcRegs.ADCINTOVFCLR.bit.ADCINT1=1;
mean +=AdcResult.ADCRESULT0;
mean +=AdcResult.ADCRESULT1;
mean +=AdcResult.ADCRESULT2;
mean +=AdcResult.ADCRESULT3;
mean +=AdcResult.ADCRESULT4;
mean +=AdcResult.ADCRESULT5;
mean +=AdcResult.ADCRESULT6;
mean +=AdcResult.ADCRESULT7;
mean +=AdcResult.ADCRESULT8;
mean +=AdcResult.ADCRESULT9;
mean +=AdcResult.ADCRESULT10;
mean +=AdcResult.ADCRESULT11;
mean +=AdcResult.ADCRESULT12;
mean +=AdcResult.ADCRESULT13;
mean +=AdcResult.ADCRESULT14;
mean +=AdcResult.ADCRESULT15;
mean >>=4;
#endif
return mean;
}
#if Interrupt_Allow
void OpenAdcInterrupt_PIE(void)
{
EALLOW;
PieVectTable.ADCINT1 = &ADCINT1Isr_dasen; //自定义中断函数
EDIS;
//开启CPU 第10组中断并使能第10组中断的第1 个小中断,即ADCINT1
IER |=M_INT1;
PieCtrlRegs.PIEIER1.bit.INTx1=1;
PieCtrlRegs.PIEACK.bit.ACK1=1;//写1去清除ACK位
//使能总中断
EINT;
ERTM;
}
char NUMCHAR_[16];
__interrupt void ADCINT1Isr_dasen(void)
{
Uint32 mean=0;
float32 val;
if(AdcRegs.ADCINTFLG.bit.ADCINT1)
{
AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//Must clear ADCINT1 flag since INT1CONT = 0
mean +=AdcResult.ADCRESULT0;
mean +=AdcResult.ADCRESULT1;
mean +=AdcResult.ADCRESULT2;
mean +=AdcResult.ADCRESULT3;
mean +=AdcResult.ADCRESULT4;
mean +=AdcResult.ADCRESULT5;
mean +=AdcResult.ADCRESULT6;
mean +=AdcResult.ADCRESULT7;
mean +=AdcResult.ADCRESULT8;
mean +=AdcResult.ADCRESULT9;
mean +=AdcResult.ADCRESULT10;
mean +=AdcResult.ADCRESULT11;
mean +=AdcResult.ADCRESULT12;
mean +=AdcResult.ADCRESULT13;
mean +=AdcResult.ADCRESULT14;
mean +=AdcResult.ADCRESULT15;
mean >>=4;
val=(float32)mean/4096;
val *=3.3;
sprintf(NUMCHAR_,"ADC INT_val:%f V\r\n", val);
UARTa_SendString(NUMCHAR_);
}
PieCtrlRegs.PIEACK.bit.ACK1=1;//写1去清除ACK位
}
#endif
- ADC.h文件如下:
/*
* ADC.h
*
* Created on: 2023年2月24日
* Author: chends
*/
#ifndef ADC_H_
#define ADC_H_
#include "DSP28x_Project.h"
#define Interrupt_Allow 0 //1-打开中断;0-不打开中断
void delayUs(Uint16 n);
void ADC_Init(void); //adc初始化
Uint32 GetChResult(Uint16 CH_sel,Uint8 ACQPS_Value,Uint8 Trig_Sel);//获取ADC结果
void InitAdcConfigAndIO(void);//ADC配置及ADCIO配置
#if Interrupt_Allow
void OpenAdcInterrupt_PIE(void);//中断使能函数
__interrupt void ADCINT1Isr_dasen(void);//中断处理函数
#endif
#endif /* ADC_H_ */