基于28035的ePWM触发ADC采样设计

前言

玖道最近在做一个开关电源项目,需要用到TI 的TMS320F28035 芯片,实现控制电路的设计。简单来说就是利用28035采集信号量,经过算法计算,得到占空比,然后利用ePWM模块输出PWM波来控制功率开关管的导通和关断,从而实现拓扑的功率变换。

为了实现控制,我们需要在一个开关周期(PWM周期)内实现ADC采样,占空比计算等。那么,如何实现在每个开关周期内进行ADC采样呢?

答案是利用ePWM模块在每个PWM周期内去触发ADC模块进行采样,那究竟如何配置实现?

这就是本文要讲的主题了~

实验目的

通过ePWM模块和ADC模块,实现ePWM在每个PWM周期内发出SOC(start of conversion)信号,触发ADC进行采样,以此深入理解两个模块的工作原理与配置细节。

实验要求

如下图所示,通过ePWM模块产生固定频率和占空比的PWM信号,并在每个PWM周期开始处进行采样,即采样频率等于PWM频率。

在这里插入图片描述

硬件电路

如下图所示,ADC通过RG引脚采样可调电阻的电压值,并保存在结果寄存器ADCRESULT中。跳线帽短接3-5脚,可变电阻的电压值通过RGADIN0B相连,即ADC可通过ADIN0B对可变电阻值进行采样。这里的ADIN0B指的是ADC 16路复用输入通道中的GROUP B channel 0。具体如下图所示。
在这里插入图片描述
引脚
在这里插入图片描述
在这里插入图片描述
注意,ADCINB0就是一个ADC输入采样引脚,并不是通过GPIO进行复用的,所以并不需要配置GPIO,直接使用就行。

实验步骤

在这里插入图片描述
整个系统的程序流程图,大致如上图所示。

首先,是DSP系统的一些初始化操作,包括锁相环,看门狗,外设时钟使能,关闭中断,初始化PIE中断向量表等。

其次,就是配置EPWM模块,产生固定频率和占空比的PWM,并设置触发EPWMxSOCA(或EPWMxSOCB,这里选择EPWMxSOCA)信号。

然后,ADC模块配置采样输入通道触发源(接收EPWMxSOCA),采样窗的大小,并选择某个SOCx(x:0-15,这里选择SOC1)进行ADC转换和触发中断ADCINTx(x:1-9)

最后,就是进入循环,进行喂狗,显示等其他后台操作。发生ADC中断时,进入ADC中断服务函数,取出可变电阻采样值并保存到数组中。

大致流程就是这样,当然读懂的前提是充分了解28035的EPWM模块和ADC模块,即熟读TI官方的用户手册和数据手册。

另外,这里面还有很多细节,未曾提及,主要还是参考官方例程和芯片手册,然后结合需求进行修改。

代码解释


#include "DSP28x_Project.h"     // Device Header file and Examples Include File

// Prototype statements for functions found within this file.
__interrupt void adc_isr(void);   

// Global variables used in this example:
Uint16 ConversionCount;   
Uint16 Voltage1[10];

int main()
{
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP2803x_SysCtrl.c file.
   InitSysCtrl();

// Step 2. Initialize GPIO:
// This example function is found in the DSP2803x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio();  // Skipped for this example

// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
   DINT;

// Initialize the PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the DSP2803x_PieCtrl.c file.
   InitPieCtrl();

// Disable CPU interrupts and clear all CPU interrupt flags:
   IER = 0x0000;
   IFR = 0x0000;

// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example.  This is useful for debug purposes.
// The shell ISR routines are found in DSP2803x_DefaultIsr.c.
// This function is found in DSP2803x_PieVect.c.
   InitPieVectTable();

// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
   EALLOW;  // This is needed to write to EALLOW protected register
   PieVectTable.ADCINT1 = &adc_isr;
   EDIS;    // This is needed to disable write to EALLOW protected registers

// Step 4. Initialize all the Device Peripherals:
   InitAdc();  // For this example, initialize the ADC
   AdcOffsetSelfCal();

// Step 5. User specific code, enable interrupts:

// Enable ADCINT1 in PIE
   PieCtrlRegs.PIEIER1.bit.INTx1 = 1;   // Enable INT 1.1 in the PIE for ADCINT1
   IER |= M_INT1;                       // Enable CPU Interrupt 1
   EINT;                                // Enable Global interrupt INTM
   ERTM;                                // Enable Global real time interrupt DBGM

   ConversionCount = 0;

// Configure ADC
// Note: Channel ADCINB0  will be double sampled to workaround the ADC 1st sample issue for rev0 silicon errata

   EALLOW;
   AdcRegs.ADCCTL1.bit.INTPULSEPOS  = 1;    //ADCINT1 trips after AdcResults latch
   AdcRegs.INTSEL1N2.bit.INT1E      = 1;    //Enabled ADCINT1
   AdcRegs.INTSEL1N2.bit.INT1CONT   = 0;    //Disable ADCINT1 Continuous mode
   AdcRegs.INTSEL1N2.bit.INT1SEL    = 1;    //setup EOC1 to trigger ADCINT1 to fire
   AdcRegs.ADCSOC0CTL.bit.CHSEL     = 8;    //set SOC0 channel select to ADCINB0(dummy sample for rev0 errata workaround)
   AdcRegs.ADCSOC1CTL.bit.CHSEL     = 8;    //set SOC1 channel select to ADCINB0
   AdcRegs.ADCSOC0CTL.bit.TRIGSEL   = 5;    //set SOC0 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
   AdcRegs.ADCSOC1CTL.bit.TRIGSEL   = 5;    //set SOC1 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
   AdcRegs.ADCSOC0CTL.bit.ACQPS     = 6;    //set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
   AdcRegs.ADCSOC1CTL.bit.ACQPS     = 6;    //set SOC1 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
   EDIS;

// Assumes ePWM1 clock is already enabled in InitSysCtrl();
   EPwm1Regs.ETSEL.bit.SOCAEN   = 1;        // Enable SOC on A group
   EPwm1Regs.ETSEL.bit.SOCASEL  = 1;        // generate SOCx when TBCTR = ZERO
   EPwm1Regs.ETPS.bit.SOCAPRD   = 1;        // Generate pulse on 1st event
   EPwm1Regs.CMPA.half.CMPA     = 0x0080;   // Set compare A value
   EPwm1Regs.TBPRD              = 0xFFFF;   // Set period for ePWM1
   EPwm1Regs.TBCTL.bit.CTRMODE  = 0;        // count up and start

// Wait for ADC interrupt
   for(;;)
   {
   }
}

__interrupt void  adc_isr(void)
{
  Voltage1[ConversionCount] = AdcResult.ADCRESULT1; //discard ADCRESULT0 as part of the workaround to the 1st sample errata for rev0
  // If 20 conversions have been logged, start over
  if(ConversionCount == 9)
  {
     ConversionCount = 0;
  }
  else
  {
      ConversionCount++;
  }

  AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;     // Clear ADCINT1 flag reinitialize for next SOC
  PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;   // Acknowledge interrupt to PIE

  return;
}

实验结果

编辑好代码后,烧录到芯片中,然后Debug,全速运行,通过窗口[Window->show view->expression]添加采样值。可以看到,10个采样值在实时进行刷新,即实现了PWM触发ADC周期性采样。
在这里插入图片描述

总结

本文简单介绍了利用TMS320F28035的EPWM模块产生SOC信号,以此触发ADC模块进行采样的大致设计思路及流程,并结合官方例程给出相应代码和实验结果,其中并未详细讲述EPWM模块和ADC模块相关寄存器的具体配置过程,读者可参考TI官方手册:

  • 2803x Piccolo Technical Reference Manual.pdf
  • tms320f28035.pdf

体会

笔者认为学习DSP最好的方式就是:官方例程+数据手册+用户手册+开发板+CCS。

具体来讲呢,官方例程可以给我们提供一个程序正确的整体架构,比如一些初始化步骤,先初始化哪部分,然后再初始化哪部分,最后再怎么样。

数据手册+用户手册可以说是最重要的资料了,必须要反复研读英文原版(记住是英文版,中文版可能会有很多翻译错误,笔者踩过坑),而且最好是结合代码研读,并做好笔记,方便以后复习。

配合数据手册和用户手册将官方例程看懂之后,就可以进行自己的一些配置了,从底层新建工程,一步一步编写自己的代码,然后结合CCS+开发板进行调试。

调试代码的时间可能是编写代码所费时间的数倍不止,因为程序会有很多Bug,这个时候就要结合数据手册和用户手册,对代码进行一行一行的检查,弄懂每一行代码的作用,思考逻辑或寄存器配置是否错误。

当你从头到尾,成功完成一个小实验,实现理论到实验验证的闭环,相信你的能力和信心会提高不少。

  • 13
    点赞
  • 160
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
TMS320F28035是德州仪器(Texas Instruments)推出的一款数字信号控制器(Digital Signal Controller,DSC),它具有高性能的计算能力和丰富的外设接口。EPWM(Enhanced Pulse Width Modulation)是TMS320F28035中的一个模块,用于产生PWM信号。根据引用\[1\],在EPWM1模块中,ePWMA和ePWMB被设置为影子模式,并且在计数器为0时重载。这意味着在每个周期的计数器为0时,ePWMA和ePWMB的值会被重新加载。根据引用\[2\],如果要配置EPWM1的中断频率为300KHZ,则单个周期为3.333333333333333us,因此需要200个中断周期。根据引用\[3\],DCAH连接到比较器1的输出,DCAL连接到TZ2。其中,TZ2是一种功能,但在这个引用中没有具体使用到。 #### 引用[.reference_title] - *1* *3* [TMS320F28035学习笔记1_模拟比较器程序_Example_2803xEPwmDCEventTripComp](https://blog.csdn.net/weixin_44618926/article/details/120554126)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [TMS320F28035 的EPWM触发ADC采样笔记](https://blog.csdn.net/tiantangmoke/article/details/109056661)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rob月初

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值