Part Number:TMS320C6748
问题:
在我的工程中主要是配置了PWM中断以及按键sw5的中断,PWM频率设置为200kHz,PWM中断触发设置成一次事件触发,(应该是每秒触发200k次中断吧),如下图所示。
PWM中断函数设置成一个计数的例子,如下图所示
主函数同样设置成一个计数的循环,如下图所示:
PWM0Init()函数是对PWM模块的一些配置,并使能了中断。设置200kHz的PWM频率运行程序后发现主函数PWM0Init()语句后面的所有语句都没有执行,设置断点调试后发现程序一直在执行PWM的中断函数,也就是说cnt2一直在计数,而cnt1没有计数。
DSPC6748主频456MHz,EPWM模块的时钟是228MHz,对于200kHz的中断,应该还有充足的时间去执行其他指令,将中断频率减小到20kHz,程序就能正常运行主函数其他指令,难道是PWM中断频率过高了吗?但是以前用的DSPF28335,主频150MHz,我最高将PWM中断设成1MHz,程序运行也没有这个问题。会不会是对哪些时钟模块的配置没有设置最高?或者与GEL文件的配置相关?
附PWM初始化代码:
Nancy Wang:
user6549373 说:设置200kHz的PWM频率运行程序后发现主函数PWM0Init()语句后面的所有语句都没有执行
单步调试有没有问题?flag的值是有变化的吗?
,
user6549373:
这里Flag是由一个按键中断控制的,按下按键触发中断使Flag置1.
如果在PWM0Init()函数中加了EHRPWETIntEnable()这句,也就是使能中断的话,后面的语句就全部没有执行,一直在执行PWM中断函数。
如果在PWM0Init()函数中没有加EHRPWETIntEnable()这句,那么我就是按下按键之后使能中断,然后同样一直在执行PWM中断函数,其他语句也不执行了。
,
Nancy Wang:
pwm能正常进中断这部分配置应该没有问题,去掉按键中断,简化一下程序,是否还有问题?
,
user6549373:
把关于按键的引脚复用配置以及中断全部注释掉了,问题依然存在,一直在执行PWM中断函数,主函数中的其他内容没有执行。
,
Nancy Wang:
方便把工程上传吗?
,
user6549373:
main.txt
/****************************************************************************/ /**/ /*SPWM中断与按键中断测试*/ /**/ /*2021年12月03日*/ /**/ /****************************************************************************/ // 注意:DSP ports, Shared RAM, UART0, EDMA, SPI0, MMC/SDs, //VPIF, LCDC, SATA, uPP, DDR2/mDDR (bus ports), USB2.0, HPI, PRU //这些外设使用的时钟来源为 PLL0_SYSCLK2 默认频率为 CPU 频率的二分之一 //但是,ECAPs, UART1/2, Timer64P2/3, eHRPWMs,McBSPs, McASP0, SPI1 //这些外设的时钟来源可以在 PLL0_SYSCLK2 和 PLL1_SYSCLK2 中选择 //通过修改 System Configuration (SYSCFG) Module //寄存器 Chip Configuration 3 Register (CFGCHIP3) 第四位 ASYNC3_CLKSRC //配置时钟来源 //(默认值) 0 来源于 PLL0_SYSCLK2 //1 来源于 PLL1_SYSCLK2 //如果不是为了降低功耗,不建议修改这个值,它会影响所有相关外设的时钟频率#include "TL6748.h"// 创龙 DSP6748 开发板相关声明#include "hw_types.h"// 宏命令 #include "hw_syscfg0_C6748.h"// 系统配置模块寄存器 #include "soc_C6748.h"// DSP C6748 外设寄存器 #include "math.h" #include "psc.h"// 电源与睡眠控制宏及设备抽象层函数声明 #include "ehrpwm.h"// 增强高精度脉宽调制宏及设备抽象层函数声明 #include "gpio.h"// 通用输入输出口宏及设备抽象层函数声明 #include "interrupt.h"// DSP C6748 中断相关应用程序接口函数声明及系统事件号定义 #include "float.h" #include "time.h" /****************************************************************************/ /**/ /*宏定义*/ /**/ /****************************************************************************/ // 软件断点 #define SW_BREAKPOINTasm(" SWBP 0 ");// 时钟分频 #define CLOCK_DIV_VAL1 #define CPU_CLK456e6/2 #define PWM_CLK200e3 #define NX 8000//PWM_CLK/25 #define SPCPU_CLK/(2*PWM_CLK) //570 #define PI3.1415926 unsigned short a[NX]={0}; unsigned short f; float r=0; float M=0.8;/****************************************************************************/ /**/ /*全局变量*/ /**/ /****************************************************************************//****************************************************************************/ /**/ /*函数声明*/ /**/ /****************************************************************************/ // 外设使能配置 void PSCInit(void);// GPIO 管脚复用配置 void GPIOBankPinMuxSet(void); void GPIOBankPinInit(void); // 产生波形 void PWM0Init(void);// DSP 中断初始化 void InterruptInit(void); // PWM 中断初始化 void PWMInterruptInit(void); // GPIO 中断初始化 void GPIOBankPinInterruptInit(void);// 中断服务函数 // PWM 事件 void PWMEventIsr(void); // 按键 事件 void USER0KEYIsr(void); void USER1KEYIsr(void);unsigned short Flag=0; unsigned int cnt0=0,cnt1=0,cnt2=0; unsigned short k1=0; /****************************************************************************/ /**/ /*主函数*/ /**/ /****************************************************************************/ int main(void) {// 外设使能配置PSCInit();// GPIO 管脚复用配置GPIOBankPinMuxSet();//GPIO 管脚初始化GPIOBankPinInit();// DSP 中断初始化InterruptInit();// PWM 中断初始化PWMInterruptInit();// GPIO 管脚中断初始化GPIOBankPinInterruptInit();unsigned short n;float r;r=0;f=275;k1=0;// PWM初始化PWM0Init();for(n=0;n<NX;n++){r=sin(2*n*PI*f/PWM_CLK);a[n]=SP/2*(1+M*r);//an是脉宽}// 主函数主循环cnt0=1;cnt1=1;cnt2=10;for(;;){if(Flag){if(cnt1>10000){cnt1=0;}else{cnt1=cnt1+1;}//EHRPWMETIntEnable(SOC_EHRPWM_0_REGS);//Flag=0;}else{if(cnt0>10000){cnt0=0;}else{cnt0=cnt0+1;}}} }/****************************************************************************/ /**/ /*PSC 初始化*/ /**/ /****************************************************************************/ void PSCInit(void) {// 使能 EHRPWM 模块// 对相应外设模块的使能也可以在 BootLoader 中完成PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_EHRPWM, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);// 使能 GPIO 模块// 对相应外设模块的使能也可以在 BootLoader 中完成PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_GPIO, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE); }/****************************************************************************/ /**/ /*GPIO 管脚复用配置*/ /**/ /****************************************************************************/ void GPIOBankPinMuxSet(void) {// 底板按键GPIOBank0Pin6PinMuxSetup();GPIOBank6Pin1PinMuxSetup();//PWM0EHRPWM0PinMuxSetup(); }/****************************************************************************/ /**/ /*GPIO 管脚初始化*/ /**/ /****************************************************************************/ void GPIOBankPinInit(void) {// 底板按键GPIODirModeSet(SOC_GPIO_0_REGS, 7, GPIO_DIR_INPUT);// USER0 KEY GPIO0[6]GPIODirModeSet(SOC_GPIO_0_REGS, 98, GPIO_DIR_INPUT);// USER1 KEY GPIO6[1] }/****************************************************************************/ /**/ /*PWM 输出波形*/ /**/ /****************************************************************************/ void PWM0Init(void) {// 时间基准配置// 时钟配置456M/2/228=1MHzEHRPWMTimebaseClkConfig(SOC_EHRPWM_0_REGS, SOC_EHRPWM_0_MODULE_FREQ/CLOCK_DIV_VAL, SOC_EHRPWM_0_MODULE_FREQ);// 配置周期EHRPWMPWMOpFreqSet(SOC_EHRPWM_0_REGS, SOC_EHRPWM_0_MODULE_FREQ/CLOCK_DIV_VAL,PWM_CLK, EHRPWM_COUNT_UP_DOWN, EHRPWM_SHADOW_WRITE_DISABLE);// 禁用输入同步信号EHRPWMTimebaseSyncDisable(SOC_EHRPWM_0_REGS);// 禁用输出同步信号EHRPWMSyncOutModeSet(SOC_EHRPWM_0_REGS, EHRPWM_SYNCOUT_DISABLE);// 仿真(DEBUG)模式行为配置EHRPWMTBEmulationModeSet(SOC_EHRPWM_0_REGS, EHRPWM_STOP_AFTER_NEXT_TB_INCREMENT);// 配置计数比较器子模块// 加载比较器 A 值456Mhz/2/PWM_CLK(200kHz)=1140EHRPWMLoadCMPA(SOC_EHRPWM_0_REGS, 500, EHRPWM_SHADOW_WRITE_DISABLE,EHRPWM_COMPA_NO_LOAD, EHRPWM_CMPCTL_OVERWR_SH_FL);// 加载比较器 B 值EHRPWMLoadCMPB(SOC_EHRPWM_0_REGS, 0, EHRPWM_SHADOW_WRITE_DISABLE,EHRPWM_COMPB_NO_LOAD, EHRPWM_CMPCTL_OVERWR_SH_FL);// 功能限定配置(输出引脚触发方式设定)// 时间基准计数等于有效计数比较寄存器 A/B 值时EPWM1_A翻转,波形由EPWM1_A输出//EHRPWMConfigureAQActionOnA(SOC_EHRPWM_0_REGS, EHRPWM_AQCTLA_ZRO_DONOTHING, EHRPWM_AQCTLA_PRD_DONOTHING,// EHRPWM_AQCTLA_CAU_EPWMXATOGGLE,EHRPWM_AQCTLA_CAD_DONOTHING,EHRPWM_AQCTLA_CBU_EPWMXATOGGLE,// EHRPWM_AQCTLA_CBD_DONOTHING, EHRPWM_AQSFRC_ACTSFA_DONOTHING);//加了死区控制,就只需要控制A,B会自动EHRPWMConfigureAQActionOnA(SOC_EHRPWM_0_REGS, EHRPWM_AQCTLA_ZRO_DONOTHING, EHRPWM_AQCTLA_PRD_DONOTHING,EHRPWM_AQCTLA_CAU_EPWMXAHIGH,EHRPWM_AQCTLA_CAD_EPWMXALOW,EHRPWM_AQCTLA_CBU_DONOTHING,EHRPWM_AQCTLA_CBD_DONOTHING, EHRPWM_AQSFRC_ACTSFA_DONOTHING);// 禁用(旁路,信号直接输出到斩波子模块)死区模块//EHRPWMDBOutput(SOC_EHRPWM_0_REGS, EHRPWM_DBCTL_OUT_MODE_BYPASS);//ePWMA是双边延时输入源EHRPWMDBSourceSelect(SOC_EHRPWM_0_REGS,EHRPWM_DBCTL_IN_MODE_AREDAFED);//使能双边延时EHRPWMDBOutput(SOC_EHRPWM_0_REGS, EHRPWM_DBCTL_OUT_MODE_AREDBFED);//死区为AHC模式EHRPWMDBPolaritySelect(SOC_EHRPWM_0_REGS, EHRPWM_DBCTL_POLSEL_AHC);//边沿延时时间EHRPWMDBConfigureRED(SOC_EHRPWM_0_REGS, 5);EHRPWMDBConfigureFED(SOC_EHRPWM_0_REGS, 5);// 禁用斩波子模块EHRPWMChopperDisable(SOC_EHRPWM_0_REGS);// 禁用错误控制事件EHRPWMTZTripEventDisable(SOC_EHRPWM_0_REGS, EHRPWM_TZ_ONESHOT);EHRPWMTZTripEventDisable(SOC_EHRPWM_0_REGS, EHRPWM_TZ_CYCLEBYCYCLE);// 事件触发配置// 每一次事件发生产生中断EHRPWMETIntPrescale(SOC_EHRPWM_0_REGS, EHRPWM_ETPS_INTPRD_FIRSTEVENT);// 时间基准计数等于0 产生事件//EHRPWMETIntSourceSelect(SOC_EHRPWM_0_REGS, EHRPWM_ETSEL_INTSEL_TBCTREQUCMPAINC);//okEHRPWMETIntSourceSelect(SOC_EHRPWM_0_REGS, EHRPWM_ETSEL_INTSEL_TBCTREQUZERO);//ok//EHRPWMETIntSourceSelect(SOC_EHRPWM_0_REGS, EHRPWM_ETSEL_INTSEL_TBCTREQUCMPADEC);//ok// 使能中断EHRPWMETIntEnable(SOC_EHRPWM_0_REGS);// 禁用高精度子模块EHRPWMHRDisable(SOC_EHRPWM_0_REGS);}/****************************************************************************/ /**/ /*PWM 中断初始化*/ /**/ /****************************************************************************/ void PWMInterruptInit(void) {// 注册中断服务函数IntRegister(C674X_MASK_INT4, PWMEventIsr);// 映射中断到 DSP 可屏蔽中断IntEventMap(C674X_MASK_INT4, SYS_INT_EHRPWM0);// 使能 DSP 可屏蔽中断IntEnable(C674X_MASK_INT4);} /****************************************************************************/ /**/ /*GPIO 管脚中断初始化*/ /**/ /****************************************************************************/ void GPIOBankPinInterruptInit(void) {// 底板按键中断// 配置 USER0 KEY GPIO0[6] 为下降沿触发GPIOIntTypeSet(SOC_GPIO_0_REGS, 7, GPIO_INT_TYPE_FALLEDGE);// 配置 USER1 KEY GPIO6[1] 为上升沿及下降沿触发GPIOIntTypeSet(SOC_GPIO_0_REGS, 98, GPIO_INT_TYPE_BOTHEDGE);// 使能 GPIO BANK 中断GPIOBankIntEnable(SOC_GPIO_0_REGS, 0);// USER0 KEY GPIO0GPIOBankIntEnable(SOC_GPIO_0_REGS, 6);// USER1 KEY GPIO6// 注册中断服务函数IntRegister(C674X_MASK_INT6, USER0KEYIsr);IntRegister(C674X_MASK_INT5, USER1KEYIsr);// 映射中断到 DSP 可屏蔽中断IntEventMap(C674X_MASK_INT6, SYS_INT_GPIO_B0INT);IntEventMap(C674X_MASK_INT5, SYS_INT_GPIO_B6INT);// 使能 DSP 可屏蔽中断IntEnable(C674X_MASK_INT6);IntEnable(C674X_MASK_INT5);} /****************************************************************************/ /**/ /*DSP 中断初始化*/ /**/ /****************************************************************************/ void InterruptInit(void) {// 初始化 DSP 中断控制器IntDSPINTCInit();// 使能 DSP 全局中断IntGlobalEnable(); }/****************************************************************************/ /**/ /*中断服务函数*/ /**/ /****************************************************************************/ void PWMEventIsr(void) {IntEventClear(SYS_INT_EHRPWM0);EHRPWMETIntClear(SOC_EHRPWM_0_REGS);if(cnt2>10000){cnt2=0;}else{cnt2=cnt2+1;}}/****************************************************************************/ /**/ /*中断服务函数*/ /**/ /****************************************************************************/ void USER0KEYIsr(void) {// 软件断点 方便调试//SW_BREAKPOINT;// 禁用 GPIO BANK 0 中断GPIOBankIntDisable(SOC_GPIO_0_REGS, 0);// 清除 GPIO BANK 0 中断状态IntEventClear(SYS_INT_GPIO_B0INT);if(GPIOPinIntStatus(SOC_GPIO_0_REGS, 7) == GPIO_INT_PEND){// 清除 GPIO0[6] 中断状态GPIOPinIntClear(SOC_GPIO_0_REGS, 7);Flag=1;}// 使能 GPIO BANK 0 中断GPIOBankIntEnable(SOC_GPIO_0_REGS, 0); } void USER1KEYIsr(void) {// 软件断点 方便调试//SW_BREAKPOINT;// 禁用 GPIO BANK 6 中断GPIOBankIntDisable(SOC_GPIO_0_REGS, 6);// 清除 GPIO BANK 6 中断状态IntEventClear(SYS_INT_GPIO_B6INT);if(GPIOPinIntStatus(SOC_GPIO_0_REGS, 98) == GPIO_INT_PEND){// 清除 GPIO6[1] 中断状态GPIOPinIntClear(SOC_GPIO_0_REGS, 98);Flag=0;}// 使能 GPIO BANK 6 中断GPIOBankIntEnable(SOC_GPIO_0_REGS, 6); }见附件,感谢
,
Nancy Wang:
我看一下晚点再给你回复。