本帖最后由 gentalk 于 2016-4-10 21:12 编辑
小弟最近用F28335开发一个项目需要使用F28335的片内ADC,于是配置了一个ePWM+ADC的采集模式,也成功了,基本搞清楚了ADC各个寄存器的作用,使用ePWM给ADC提供启停信号,并设置采样率,然后利用ADC完成转换的中断去操作数据,成功地完成了一个ePWM+ADC的基本配置,代码如下:
void Init_ADC_PWM(void) //PWM给转换信号,ADC完成后产生中断
{
EALLOW;
PieVectTable.ADCINT=&ADC0_ISR;
EDIS;
IER|=M_INT1;
PieCtrlRegs.PIECTRL.bit.ENPIE=1;
PieCtrlRegs.PIEIER1.bit.INTx6=1;
EINT;
ERTM;
EALLOW;
SysCtrlRegs.HISPCP.all=ADC_MODCLK; //设置高速外设时钟为25MHz
EDIS;
AdcRegs.ADCTRL1.bit.SUSMOD=0X3;
AdcRegs.ADCTRL1.bit.ACQ_PS=0x3;
AdcRegs.ADCTRL3.bit.ADCCLKPS=ADC_CKPS;
AdcRegs.ADCTRL1.bit.SEQ_CASC=1;
AdcRegs.ADCTRL2.bit.RST_SEQ1=1;
AdcRegs.ADCCHSELSEQ1.bit.CONV00=0x0;
AdcRegs.ADCTRL1.bit.CPS=1;
AdcRegs.ADCTRL1.bit.CONT_RUN=0;
AdcRegs.ADCTRL1.bit.SEQ_OVRD=0; //为0时MAX_CONV1有效
AdcRegs.ADCMAXCONV.bit.MAX_CONV1=0; //自动转换0~1通道的值
AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ=1; //级联状态下打开SOCB_SEQ,由ePWM SOCB信号启动
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1=1;
}
interrupt void ADC0_ISR(void)
{
PieCtrlRegs.PIEACK.all=PIEACK_GROUP1;
BUF_sample[adc_num]=((AdcRegs.ADCRESULT0)>>4);
adc_num++;
if(adc_num>BUF_SIZE)
adc_num=0;
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; //必须写1来重置序列1,否则下次采集的时候值有可能不变,导致采样率非常低
AdcRegs.ADCST.bit.INT_SEQ1_CLR=1; //清除中断标志
}
PWM的设置开启了SOCB事件,针对级联模式的启动,代码运行没有问题,但是我对排序器清零有些疑惑,也就是AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;这个寄存器。在找了些相关资料看了后,了解了启停模式和连续运行模式在排序器指针问题上是有区别的,在连续模式下,每次转换完conv配置的所有通道后,指针会复位到初始通道,这个过程是自动的,而启停模式下,也就是在上述代码中使用的模式,转换完所有的通道后指针并不会自动复位到初始通道,需要对RST_SEQ这个寄存器置1来让指针复位,不然读取的数据就会出错。在后期我想使用ePWM+ADC+DMA纯硬件来完成整个数据的采集工作,从而不需要一直进入中断,释放CPU,因为项目中对运算有一定要求,这里我就遇到了一个很大的问题,如果使用DMA去传输数据,DMA能够自动清除一些ADC的标志寄存器,但它并不能将RST_SEQ这个寄存器置位,在启停模式下无法将排序器指针复位,导致了数据采集错误,并且我寻找了几乎所有的样例,都没有人去完整地讨论这个问题,所以来论坛看看有没有大牛,能点拨几点。谢谢。
|