#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 日
© 允许规范转载