#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
interrupt void epwm1_timer_isr(void);//PWM1中断服务程序
void InitEPwmTimer(void);            //PWM初始化程序
interrupt void adc_isr(void);//ADC中断服务程序
interrupt void cpu_timer0_isr(void);//定时器0的中断服务程序
void Adc_Config(void);//ADC配置程序
// 用到的变量:
Uint32 EPwm1TimerDuty = 50;
Uint16 ConversionCount = 0;
Uint16 Voltage1 = 0;

Uint32 Vcc[10] = {0};
Uint32 sum = 0;
float32 aveVcc = 0;
Uint16 flag = 0;

void main()
{
// 初始化系统控制:PLL,看门狗,使能外围时钟,见DSP281x_SysCtrl.c
InitSysCtrl();
DINT; //关闭总中断
InitPieCtrl();//初始化PIE控制寄存器,缺省状态为PIE中断禁止,标志位清除。见DSP2802x_PieCtrl.c
IER = 0x0000;//关闭外设中断:Disable CPU interrupts
IFR = 0x0000;//清除中断标志:clear all CPU interrupt flags
InitPieVectTable();//初始化PIE向量表,使得指针指向各自中断服务子程序,在本例中未用到的中断也会//被初始化
//默认ISR 子程序见 DSP2802x_DefaultIsr.c.
//InitPieVectTable()见 DSP2802x_PieVect.c.
InitCpuTimers(); //in DSP2802x_CpuTimers.c
ConfigCpuTimer(&CpuTimer0, 60, 10000);//设置周期10ms
CpuTimer0Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0
StopCpuTimer0();        //暂停Timer0// #define StopCpuTimer0()   CpuTimer0Regs.TCR.bit.TSS = 1
StartCpuTimer0();       //启动Timer0//#define StartCpuTimer0()   CpuTimer0Regs.TCR.bit.TSS = 0
// 设置中断服务程序入口
EALLOW; // 允许写入受EALLOW保护的寄存器
PieVectTable.EPWM1_INT = &epwm1_timer_isr;  //设置中断服务程序入口
PieVectTable.TINT0 = &cpu_timer0_isr;       //设置中断服务程序入口
PieVectTable.ADCINT1 = &adc_isr;            //设置中断服务程序入口
EDIS;                   // 禁止写入受EALLOW保护的寄存器
InitAdc();               // 初始化ADC,见文件“DSP2802x_Adc.c”
IER |= M_INT1;                      // 使能CPU中断 1
IER |= M_INT3;                      //使能中断,PWM的中断在PIE Group 3
PieCtrlRegs.PIEIER3.bit.INTx1 = 1; //开启  PIE中的 EPWM INTn  : Group 3 interrupt 1-4
PieCtrlRegs.PIEIER1.bit.INTx1 = 1;  // 使能中断,ADC的中断在PIE Group 1.1
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;  //允许 TINT0 ,在 PIE的 Group 1 ,interrupt 7

EINT;    //使能全局中断INTM
ERTM;   // 开启全局实时中断 DBGM

Adc_Config();        //初始化配置ADC

InitEPwm1Gpio();    //初始化PWM引脚
InitEPwmTimer();    // 初始化PWM模块
// 以下一直循环运行,等待ADC中断
for(;;)
{
if(flag==1)
{
int i = 0;
for(i=0;i<=9;i++)
{
sum += Vcc[i];
}
aveVcc = (float)(sum / 10) / 4095 * 3.3;
if(aveVcc > 2.4)
EPwm1TimerDuty --;
else
EPwm1TimerDuty ++;
flag = 0;
}
}

}//main

void Adc_Config(void)//配置ADC
{
  EALLOW;
  AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1;    //ADCINT1 中断信号在Adc结果锁存时产生
  AdcRegs.INTSEL1N2.bit.INT1E     = 1;    //开启ADCINT1
  AdcRegs.INTSEL1N2.bit.INT1CONT  = 0;    //禁止ADCINT1 连续模式
  AdcRegs.INTSEL1N2.bit.INT1SEL   = 0;    //设置 EOC0 去触发  ADCINT1,即SOC0转换完后再产生中断 ADCINT1
  AdcRegs.ADCSOC0CTL.bit.CHSEL    = 4;    //通道 SOC0 连接 ADCINA4

  AdcRegs.ADCSOC0CTL.bit.TRIGSEL  = 1;    //SOC0 的启动触发信号源为定时器0, 转换先后顺序为SOC0、SOC1、SOC2

  AdcRegs.ADCSOC0CTL.bit.ACQPS    = 6;    //设置SOC0的 采样保持窗长度为 7个 ADC Clock Cycles, (6 ACQPS+ 1)

  EDIS;
  //注意:第一个ADC的数据被舍弃。以防止有错,见device errata

}

void InitEPwmTimer()//初始化PWM
{
  EALLOW;
  SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;          //初始时暂停TBCLK时钟
  EDIS;
  EPwm1Regs.TBPRD = 1200-1;                        // PWM周期 = 1200个TBCLK计数周期
  EPwm1Regs.CMPA.half.CMPA = 12;                  // CMPA = 240个TBCLK计数周期
  EPwm1Regs.TBPHS.half.TBPHS = 0;                  // 相位寄存器值为0, 注意此指令,datasheet中有问题!
  EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;          // 禁止相位加载
  EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;  //即0x3,禁止同步信号输出
  EPwm1Regs.TBCTR = 0;                             // 复位TBCTR
  EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;       //增加计数模式

  EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;           //允许PRD镜像寄存器

  EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;         // TBCLK = SYSCLK, TB_DIV1=0
  EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;            // TBCLK = SYSCLK=60MHz
  EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;      //允许CMPA镜像寄存器
  EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;         //允许CPMB镜像寄存器
  EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;       // 在CTR = Zero时加载CMPA镜像值
  EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;       //在CTR = Zero时加载CMPB镜像值
  EPwm1Regs.AQCTLA.bit.PRD = AQ_SET;              // CTR = PRD后将EPWM1A置0
  EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;            // CTR = CMPA后将EPWM1A置1
  EALLOW;
  EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;       //ET_CTR_PRD;//;ET_CTRU_CMPA
  EPwm1Regs.ETSEL.bit.INTEN = 1;                  // Enable INT
  EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;             // Generate INT on 1st event
  SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;          //开启TBCLK时钟
  EDIS;


}

// PWM中断服务函数
interrupt void epwm1_timer_isr(void)
{
  EPwm1Regs.ETCLR.bit.INT = 1;// 清除中断标志
  // 中断应答,以允许后续中断
  PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
}

//定时器0的中断服务程序
interrupt void cpu_timer0_isr(void)
{
  Uint32 Duty = 0;
  Duty = 1200 * EPwm1TimerDuty / 100;
  EPwm1Regs.CMPA.half.CMPA = Duty;
  PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

//ADC采集中断服务函数
interrupt void adc_isr(void)
{
  if(flag == 0)
  {
    Voltage1 = AdcResult.ADCRESULT0;  //A4引脚取第2次的采样值
    Vcc[ConversionCount] = (float)Voltage1 / 4095 * 3.3;
  if (ConversionCount >= 9)
  {
    ConversionCount = 0;
    flag = 1;
  }
else
  ConversionCount++;
  AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;       //清除ADCINT1标志位以允许后续中断
  PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;   // PIE的中断应答
  }
}
End

本文标题:DSP-28027综合实验

本文链接:https://www.kitteno.com/archives/adc_pwm.html

除非另有说明,本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

声明:转载请注明文章来源。

最后修改:2022 年 06 月 03 日
如果觉得我的文章对你有用,请随意赞赏