Part Number:TMS320F28377SOther Parts Discussed in Thread:C2000WARE
void ConfigureADC(void)
{
EALLOW;
//write configurations
AdcbRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4
AdcSetMode(ADC_ADCB, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
//Set pulse positions to late
AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1; //设置ADC的中断产生时机在转换后产生中断
AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1;
DELAY_US(1000);
EDIS;
}
void SetupADCSoftware(void)
{
Uint16 acqps;
//determine minimum acquisition window (in SYSCLKS) based on resolution
if(ADC_RESOLUTION_12BIT == AdcaRegs.ADCCTL2.bit.RESOLUTION){
acqps = 14; //75ns
}
else { //resolution is 16-bit
acqps = 63; //320ns
}
//Select the channels to convert and end of conversion flag
EALLOW;
//ADCB
AdcbRegs.ADCSOC5CTL.bit.CHSEL = 5; //SOC5 will convert pin B5
AdcbRegs.ADCSOC5CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cycles
AdcbRegs.ADCSOC5CTL.bit.TRIGSEL = 2; //SOC5触发源选择为CPU1 Timer1
AdcbRegs.ADCINTSEL1N2.bit.INT1SEL = 1; //end of SOC1 will set INT1 flag
AdcbRegs.ADCINTSEL1N2.bit.INT1E = 1; //enable INT1 flag
AdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared
}
主函数如下:
void main(void)
{
float T=7.2; //设置DAC锯齿波周期为2.4ms
//double step = 0;
// 系统初始化,配置PLL,关闭看门狗,使能外设时钟
test();
InitSysCtrl();
// 关中断
DINT;
// 初始化Pie控制寄存器
InitPieCtrl();
// 不使能中断,清中断标志
IER = 0x0000;
IFR = 0x0000;
// 初始化中断向量表
InitPieVectTable();
// 配置DAC输出
configureDAC(DAC_NUM);
//注册中断服务函数
EALLOW;
PieVectTable.TIMER0_INT = &cpu_timer0_isr;
PieVectTable.TIMER1_INT = &cpu_timer1_isr;
EDIS;
//初始化CPU定时器
InitCpuTimers();
// 配置CPU的时钟 T*(float)(10^(3)/3072
// 200MHz CPU Freq, 1 second Period (in uSeconds)
ConfigCpuTimer(&CpuTimer0, 200,T*(float)1000/1024);
CpuTimer0Regs.TCR.all = 0x4000; //启动定时器
// 配置 ADCs 及 使能 ADC power
ConfigureADC();
// 设置 ADCs 转换序列
SetupADCSoftware();
ConfigCpuTimer(&CpuTimer1, 200,2.4*(float)1000/256); //ad采样率
CpuTimer1Regs.TCR.all = 0x4000; //启动定时器
//使能对应的中断
IER |= M_INT1;
IER |= M_INT13;
IER |= M_INT14;
//使能中断向量表对应的中断
PieCtrlRegs.PIEIER1.bit.INTx7 = 1; //使能定时器中断
//使能全局中断和实时调试中断
EINT;
ERTM;
// 初始化串口
SCIStdioInit();
// 打印adc数据
while(1);
}
void test()
{
//double a1[1024];
int t1;
for(t1=0;t1<1024;t1++)
{
a1[t1]=1.5+(float)t1/2560;
}
}
void configureDAC(Uint16 dac_num)
{
EALLOW;
DAC_PTR[dac_num]->DACCTL.bit.DACREFSEL = REFERENCE;
DAC_PTR[dac_num]->DACOUTEN.bit.DACOUTEN = 1;
DAC_PTR[dac_num]->DACVALS.all = 0;
DELAY_US(10); // Delay for buffered DAC to power up
EDIS;
}
__interrupt void cpu_timer0_isr(void)
{
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; //0x0001赋给12组中断ACKnowledge寄存器,对其全部清除,不接受其他中断
//CpuTimer0.InterruptCount++;
dacval = (Uint16)((a1[n]/3.0)*4095);
n = (n==1023)?0:(n+1);
DAC_PTR[DAC_NUM]->DACVALS.all = dacval;
}
__interrupt void cpu_timer1_isr(void)
{
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; //0x0001赋给12组中断ACKnowledge寄存器,对其全部清除,不接受其他中断
// //大三角边每条边需采集256点,小三角每条边需采集128点 同一个采样率
// DELAY_US(1);
// //启动 ADCB 转换
// AdcbRegs.ADCSOCFRC1.all = 0x003F; //SOC0 ~ SOC5
// // 等待 ADCB 转换完成
// while(AdcbRegs.ADCINTFLG.bit.ADCINT1 == 0);
// AdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;
AdcbResult[0] = AdcbResultRegs.ADCRESULT5;
// 计算 ADCs 的实际电压值
//Adcb_V[0] = (float)AdcbResult[0]*3/4095;
//int a1;
//a1 = (int)((Adcb_V[0]-1)*10000);
//串口打印 ADC 各个通道数据
SCIprintf("%d ",AdcbResult[0]);
//SCIprintf("Adcb_V = 1.%d\n",a1);
//SCIprintf("ADCINB0 = %d,Adcb_V = 1.%d\n",AdcbResult[0],a1);
}
Susan Yang:
"发现DA周期变得很长"
能否详细说明下?另外若是可以的话,请上传整个工程,我们拿开发板来测试一下
,
cong huang:
Sigle_wave.zip
,
cong huang:
本来DA产生的锯齿波是7.2ms一个周期,但是利用定时器开启AD后,用示波器看到DA出现的波形周期变成了300多ms,关闭定时器timer1又恢复正常了。
,
Susan Yang:
谢谢给出工程,我今天拿板子看一下是否能复现您的问题
,
Susan Yang:
我用28379D的launchpad测试了一下,一直卡在下面的语句
,
Susan Yang:
我在timer1和timer0的中断服务程序内均设置了断点,测试发现:
运行后每次都先进timer1,而后进timer0
是否有可能是timer1 中断服务程序处理时间长,从而影响了timer0?
,
cong huang:
设置的timer1时间确实比timer0长,如果会影响timer0,是不是不能用两个timer来做了,至少是不用timer1做定时器来采集?
,
Susan Yang:
是的,不建议使用两个timer来做 ADC/DA,您可以尝试使用其他的触发源
,
cong huang:
好的谢谢,另外请问官方有377s PWM触发AD采集的例程吗,能否发一下呢?
,
Susan Yang:
您可以下载 C200ware,在其安装文件夹内可以找到
C2000Ware\device_support\f2837xs\examples\cpu1\adc_soc_epwm
,
cong huang:
好的 谢谢
,
Susan Yang:
很高兴能帮到您。若是可以请点击确认答案