This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320C6748: pwm中断问题

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初始化代码:

  • 设置200kHz的PWM频率运行程序后发现主函数PWM0Init()语句后面的所有语句都没有执行

    单步调试有没有问题?flag的值是有变化的吗?

  • 这里Flag是由一个按键中断控制的,按下按键触发中断使Flag置1.
    如果在PWM0Init()函数中加了EHRPWETIntEnable()这句,也就是使能中断的话,后面的语句就全部没有执行,一直在执行PWM中断函数。
    如果在PWM0Init()函数中没有加EHRPWETIntEnable()这句,那么我就是按下按键之后使能中断,然后同样一直在执行PWM中断函数,其他语句也不执行了。
  • pwm能正常进中断这部分配置应该没有问题,去掉按键中断,简化一下程序,是否还有问题?

  • 把关于按键的引脚复用配置以及中断全部注释掉了,问题依然存在,一直在执行PWM中断函数,主函数中的其他内容没有执行。
  • 方便把工程上传吗?

  • /****************************************************************************/
    /*                                                                          */
    /*              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_BREAKPOINT     asm(" SWBP 0 ");
    
    // 时钟分频
    #define CLOCK_DIV_VAL     1
    #define CPU_CLK   	456e6/2
    #define PWM_CLK   200e3
    #define NX 8000			              //PWM_CLK/25
    #define SP        CPU_CLK/(2*PWM_CLK) //570
    #define PI	        3.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();
    
    	//PWM0
    	EHRPWM0PinMuxSetup();
    }
    
    /****************************************************************************/
    /*                                                                          */
    /*              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=1MHz
        EHRPWMTimebaseClkConfig(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)=1140
        EHRPWMLoadCMPA(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);//ok
        EHRPWMETIntSourceSelect(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 GPIO0
        GPIOBankIntEnable(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);
    }
    
    
    
    见附件,感谢

  • 我看一下晚点再给你回复。