CCS5.4+Proteus8的F28027实践课七、ADC

吃完饭回来了,现在开始我们的ADC实践操作。
直奔主题我们,那就是ADC编程操作流程是怎么样的。
其实通过上节理论课的学习,大家心里都应该有了模糊的感觉,一般的步骤如下:
1、使能ADC模块时钟( PCLKCR0.ADCENCLK =1)
2、启动模拟电路、带隙和参考源,ADCCTL1寄存器(ADCPWDN, ADCBGPWD, ADCREFPWD位=1)
3、使能ADC模块(ADCCTL1.ADCENABLE=1)
4、ADC中断相关设置(参考PIE)
5、模拟IO引脚复用设置(AIOMUX1)
6、SOC配置(触发、通道、采样窗口)
7、编写中断ISR(读取ADC结果)
了解了操作步骤,那我们就要了解相关的寄存器,由于寄存器又比较多,我这里就不一一讲述,大家直接去看手册就行了

了解了寄存器,下面就要看下具体的操作时序图了:
顺序采样的迟中断

顺序采样的早中断

同步采样的迟中断

同步采样的早中断

好了,时序图也看完了,我们现在来参考时序图写程序了。
我们先来个简单的,顺序采样的迟中断。
既然是ADC,那我们这节课肯定用到了TI提供的F2802x_Adc.c文件,另外,还要显示,也需要把我们上节课整理的F2802x_LCD12864.c文件。
首先我们一起来看下ADC初始化函数InitAdc()

void InitAdc(void)
{
    extern void DSP28x_usDelay(Uint32 Count);// *IMPORTANT*
    // The Device_cal function, which copies the ADC calibration values from TI reserved
    // OTP into the ADCREFSEL and ADCOFFTRIM registers, occurs automatically in the
    // Boot ROM. If the boot ROM code is bypassed during the debug process, the
    // following function MUST be called for the ADC to function according
    // to specification. The clocks to the ADC MUST be enabled before calling this
    // function.
    // See the device data manual and/or the ADC Reference
    // Manual for more information.

        EALLOW;SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;(*Device_cal)();EDIS;// To powerup the ADC the ADCENCLK bit should be set first to enable
    // clocks, followed by powering up the bandgap, reference circuitry, and ADC core.
    // Before the first conversion is performed a 5ms delay must be observed
    // after power up to give all analog circuits time to power up and settle

    // Please note that for the delay function below to operate correctly the
    // CPU_RATE define statement in the DSP2802x_Examples.h file must
    // contain the correct CPU clock period in nanoseconds.
    EALLOW;AdcRegs.ADCCTL1.bit.ADCBGPWD  = 1;      // Power ADC BGAdcRegs.ADCCTL1.bit.ADCREFPWD = 1;      // Power referenceAdcRegs.ADCCTL1.bit.ADCPWDN   = 1;      // Power ADCAdcRegs.ADCCTL1.bit.ADCENABLE = 1;      // Enable ADCAdcRegs.ADCCTL1.bit.ADCREFSEL = 0;      // Select interal BGEDIS;DELAY_US(ADC_usDELAY);         // Delay before converting ADC channels}

初始化函数已经把我们的前三步都做完了,也就是使能时钟、上电、使能ADC模块;
那我们现在来进行SOC相关设置,也就是:触发源、采样时隙、通道选择。
触发源我们选择定时器0,因为我们做测试肯定输入一个稳定的直流电压,那用定时器最方便。
AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 1;
采样时隙就用最短时隙,也就是AdcRegs.ADCSOC0CTL.bit.ACQPS = 6;
由于TI那个实验板只引出了几个ADC引脚而已,我们就用ADCINA1,也就是AdcRegs.ADCSOC0CTL.bit.CHSEL = 1;
另外,我们说了,我们本次的实验是顺序采样,迟中断,那就是:
AdcRegs.ADCSAMPLEMODE.bit.SIMULEN0 = 1;
AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1;
到这里SOC相关设置就完成了,我们现在开始要对PIE中断就行相应的设置了。
我们这里采用简单的中断1,EOC脉冲触发ADCINTx脉冲
AdcRegs.INTSEL1N2.bit.INT1SEL = 0;
AdcRegs.INTSEL1N2.bit.INT1CONT = 1;
AdcRegs.INTSEL1N2.bit.INT1E = 1;
最后还要再PIE组里面打开ADCINT1开关:PieCtrlRegs.PIEIER1.bit.INTx1 = 1;
ADC中断函数就一个置位:

interrupt void ADCINT1_ISR(void)   // ADC  (Can also be ISR for INT10.1 when enabled){  // Insert ISR Code here

  // To receive more interrupts from this PIE group, acknowledge this interrupt
   PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;  // Next two lines for debug only to halt the processor here
  // Remove after inserting ISR Code

  //asm ("      ESTOP0");
  //for(;;);}

ADC中断也说完了,还有定时器设置,这个就参考我们前面写的那个程序,一模一样,也就是说采样时隙是1ms
首先是CPU.c文件

void InitCpuTimers(void)
{
    // CPU Timer 0// Initialize address pointers to respective timer registers:
    CpuTimer0.RegsAddr = &CpuTimer0Regs;// Initialize timer period to maximum:
    CpuTimer0Regs.PRD.all  = 1000;// Initialize pre-scale counter to divide by 1 (SYSCLKOUT):
    CpuTimer0Regs.TPR.bit.TDDR  = 59;CpuTimer0Regs.TPRH.bit.TDDRH = 0;// Make sure timer is stopped:
    CpuTimer0Regs.TCR.bit.TSS = 1;// Reload all counter register with period value:
    CpuTimer0Regs.TCR.bit.TRB = 1;// Reset interrupt counters:
    CpuTimer0.InterruptCount = 0;// CpuTimer 1 and CpuTimer2 are reserved for DSP BIOS & other RTOS
// Do not use these two timers if you ever plan on integrating
// DSP-BIOS or another realtime OS.
//
// Initialize address pointers to respective timer registers:
    CpuTimer1.RegsAddr = &CpuTimer1Regs;CpuTimer2.RegsAddr = &CpuTimer2Regs;// Initialize timer period to maximum:
    CpuTimer1Regs.PRD.all  = 0xFFFFFFFF;CpuTimer2Regs.PRD.all  = 0xFFFFFFFF;// Initialize pre-scale counter to divide by 1 (SYSCLKOUT):
    CpuTimer1Regs.TPR.all  = 0;CpuTimer1Regs.TPRH.all = 0;CpuTimer2Regs.TPR.all  = 0;CpuTimer2Regs.TPRH.all = 0;// Make sure timers are stopped:
    CpuTimer1Regs.TCR.bit.TSS = 1;CpuTimer2Regs.TCR.bit.TSS = 1;// Reload all counter register with period value:
    CpuTimer1Regs.TCR.bit.TRB = 1;CpuTimer2Regs.TCR.bit.TRB = 1;// Reset interrupt counters:
    CpuTimer1.InterruptCount = 0;CpuTimer2.InterruptCount = 0;}

然后是定时中断函数

interrupt void  TINT0_ISR(void)      // CPU-Timer 0{  // Insert ISR Code here

  // To receive more interrupts from this PIE group, acknowledge this interrupt
  PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;  // Next two lines for debug only to halt the processor here
  // Remove after inserting ISR Code//  asm ("      ESTOP0");//  for(;;);}

最后是相关中断设置

CpuTimer0Regs.TCR.bit.TIE = 1;
   StartCpuTimer0();
   EALLOW;
   PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
   PieCtrlRegs.PIECTRL.bit.ENPIE = 1;
   IER |= 0x0001;
   EINT;
   EDIS;

现在定时中断也写完了,就剩下ADC处理显示函数了

while(1)
   {
       if(AdcRegs.ADCSOCFLG1.bit.SOC0==1)
       {
           while(AdcRegs.ADCSOCFLG1.bit.SOC0==1);   AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;   DELAY_US(10);   sum+=AdcResult.ADCRESULT0;   i++;   }
       if(i==100)
       {
           sum/=100;   vol=sum*3.3/4095;   WRITECMD_LCD12864(0x01);   DISLPLAY_LONGSTRING(2,0,sum);   DISLPLAY_FLOATSTRING(3,0,vol);   WRITEDATA_LCD12864('v');   sum=0;   i=0;   }
   }

我是直接写在while死循环里面的,然后去捕捉转换标志位,采样100次,取平均值。
下载程序验证,成功,呵呵,上大家上效果图

突然想到一个刚才调试的问题,就是提示我.text段超出空间,我把段大小相应调整了下
.text : > PRAML0, PAGE = 0
PRAML0 : origin = 0x008000, length = 0x000c00
DRAML0 : origin = 0x008c00, length = 0x000400

具体的代码我会传到下载库和QQ群里面,大家有需要的话自行下载

(0)

相关推荐

  • GD32E230 ADC注入通道

    外部触发输入的上升沿可以触发规则组或注入组的转换. 用于 ADC 规则通道的 规则通道的 外部触发 ,很多场景上我们可以使用外部触发读取ADC,比如控制无刷电机要采样电机每相的电流时就需要用到注入通道 ...

  • CCS5.4+Proteus8的F28027实践课一、延时函数控制LED流水灯

    又是十二点了,但是很兴奋,因为从这节课开始,我们将会进行F28027一系列的动手实践练习,深入了解一门技术的唯一办法就是多动手实践,多总结反思. 来来来,不扯了,直接开始了. 在正式开始写程序前,我们 ...

  • CCS5.4+Proteus8的F28027实践课二、定时器0控制LED流水灯

    刚游泳回来,看到昨晚那篇博客访问量比较高,对我是莫大的鼓励,所以马不停蹄的去找了相关的手册准备我们今天的课程. 今天我们要说的是用定时器0产生的定时中断让LED闪烁. 大家都是大部分都是工科出身,应该 ...

  • CCS5.4+Proteus8的F28027实践课三、外部中断0控制LED流水灯

    吃完回来了,跟老弟打了个电话,他正处于事业的迷茫期,希望他早点走出这个状态.好了,现在已经晚上八点过十分了,希望十点前能把外部中断这个主题讲完. 外部中断的概念我还是稍微说下吧,就是你映射的外部中断引 ...

  • CCS5.4+Proteus8的F28027实践课四、并行驱动LCD12864

    趁着时间早,晚上九点四十,我们整理下12864的驱动程序,争取也弄成一个跟TI提供的类似源文件,然后共享给大家. 既然是12864,那最重要的肯定是12864时序的解读,在大学时期,12864还玩的真 ...

  • CCS5.4+Proteus8的F28027实践课五、实验板焊接调试

    今天回来的比较晚,但还是简单的把面包板给焊接调试了下,昨天写的那个12864程序果然不行..只能等明晚再搞了.力争做到一天一更,每天学习进步一点,才不会虚的慌. 今天的主要目的是把面包板焊接出来,稍微 ...

  • CCS5.4+Proteus8的F28027实践课六、实验板焊接调试(12864部分)

    下班早早回家就是为了把昨天没做完的事情搞完,但等我把12864调完之后,好想找块豆腐撞死算了,RS引脚跳线不知道什么时候被我弄断了,我竟然一直没有检查板子,只顾着对着时序图和寄存器检查程序,哎,直接给 ...

  • CCS5.4+Proteus8的F28027实践课八、内置温度传感器

    上午发布的ADC解读部分访问好高,呵呵,我又受鼓舞了,再接再励,把温度传感器这部分弄完就去吃晚饭. 看了下手册,温度传感器东西还真的不多,寄存器就一个ADCCTL1.TEMPCONV,其他的操作跟刚才 ...

  • CCS5.4+Proteus8的F28027实践课九、比较器

    今天写的不顺畅,一个AD写了八个小时,然后一个温度传感器又卡了四个小时,哎,没人能一马平川,特别是搞技术,我们的目的不是走马观花式的学习,而是真正了解寄存器的操作,不要怕时间不够,就怕时间花了还吃不透 ...

  • CCS5.4+Proteus8的F28027实践课十、SPI

    刚刚我们已经把SPI的理论知识部分讲完了,现在我们根据寄存器和时序图来写程序了. 首先,既然是SPI,肯定是复用了GPIO,我们先回顾下GPIO引脚说明: 从上面可以看到我们这次实践课需要复用GPIO ...