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.
主要是ecap模块的问题。
我想用f28035的ecap模块捕捉电网频率,ecap模块的配置参照官方例程:Example_2803xECap_Capture_Pwm来弄的,烧录后实测也成功捕捉到电网频率。
但是我把ecap函数添加进主函数后就捕捉不到了,后来一步步排除,发现把epwm模块
(SetEPWM1(); // 初始化ePWM1
怀疑是epwm模块和ecap模块有什么不可言状的冲突,但是找了半天也没找到,希望官方人员帮忙解决问题。
谢谢。
另附代码如下:
void main(void) { InitSysCtrl(); // SetGpio(); // Initialize GPIO InitEPwm1Gpio(); InitEPwm2Gpio(); InitECap1Gpio(); DINT; InitPieCtrl(); IER = 0x0000; IFR = 0x0000; InitPieVectTable(); EALLOW; PieVectTable.EPWM1_INT = &epwm1_isr; PieVectTable.EPWM2_INT = &epwm2_isr; PieVectTable.ECAP1_INT = &ecap1_isr; PieVectTable.ADCINT1 = &adc_isr; EDIS; InitAdc(); // For this example, init the ADC AdcOffsetSelfCal(); EALLOW; SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // 停止所有ePWM时钟 EDIS; InitECapture1(); //Cap1功能初始化 SetEPWM1(); // 初始化ePWM1 SetEPWM2(); // 初始化ePWM2 InitADC(); EALLOW; SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // 启动所有ePWM时钟 EDIS; IER |= M_INT1+M_INT3+M_INT4; // Enable CPU Interrupt 1 PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // Enable INT 1.1 in the PIE PieCtrlRegs.PIEIER3.bit.INTx1 = 1; //使能PWM1中断 PieCtrlRegs.PIEIER3.bit.INTx2 = 1; //使能PWM2中断 PieCtrlRegs.PIEIER4.bit.INTx1 = 1; //使能ECAP1中断 EINT; // Enable Global interrupt INTM ERTM; // Enable Global realtime interrupt DBGM LoopCount = 0; ConversionCount = 0; for(;;) { LoopCount++; // EPwm1Regs.CMPA.half.CMPA = (8.6 / ((Ud_REG[0] * 3.3 / 4095) / 0.04782)) * TB_PERIOD; // EPwm2Regs.CMPA.half.CMPA = (8.6 / ((Ud_REG[0] * 3.3 / 4095) / 0.04782)) * TB_PERIOD; EPwm2Regs.CMPA.half.CMPA = (2 * ((Voltage3[0] * 3.3 / 4095) * 59.64 + 82.59) + 3.5) / ((Ud_REG[0] * 3.3 / 4095) / 0.04782 * 26) * TB_PERIOD; //110V使用 EPwm1Regs.CMPA.half.CMPA = (2 * ((Voltage3[0] * 3.3 / 4095) * 59.64 + 82.59) + 3.5) / ((Ud_REG[0] * 3.3 / 4095) / 0.04782 * 26) * TB_PERIOD; //110V使用 // EPwm2Regs.CMPA.half.CMPA = (2 * ((Voltage3[0] * 3.3 / 4095) * 59.64 + 82.59) + 3.5) / ((Ud_REG[0] * 3.3 / 4095) / 0.04782 * 26) * TB_PERIOD; //110V使用 // EPwm1Regs.CMPA.half.CMPA = (2 * ((Voltage3[0] * 3.3 / 4095) * 59.64 + 82.59) + 3.5) / ((Ud_REG[0] * 3.3 / 4095) / 0.04782 * 52) * TB_PERIOD; //220V使用 // EPwm2Regs.CMPA.half.CMPA = (2 * ((Voltage3[0] * 3.3 / 4095) * 59.64 + 82.59) + 3.5) / ((Ud_REG[0] * 3.3 / 4095) / 0.04782 * 52) * TB_PERIOD; //220V使用 // nCAP1=ECap1Regs.CAP1; }
但是我把ecap函数添加进主函数后就捕捉不到了,
能描述一下捕捉不到的具体现象是什么吗?从程序的角度来说。
个别eCAP引脚与ePWM引脚复用,需要注意一下。请看一下sprui10a_TMS320F2803x Microcontrollers Technical Reference Manual (Rev. A)第110页1.4.5 GPIO and Peripheral Multiplexing (MUX)。
我是用ecap来捕捉电网频率,单独的ecap程序能通过高低电平时间正确计算出电网频率,但是我把ecap程序添加进主函数后,高低电平时间是错误的,高低电平的读数不准确,因此无法正确计算出电网频率。
只有当把epwm的程序注释掉后,ecap的读数才会恢复为正确的读数。因此我怀疑是否epwm和ecap的程序产生了冲突。
另外epwm的程序用的是gpio0和gpio2,ecap用的是gpio19,应该不存在引脚复用的问题吧?
我看了下您发的技术索引手册110页,发现gpio19对应的是GPAMUX2 Register Bits里的7-6,gpio3对应的同样是GPAMUX1 Register Bits里的7-6。我使用了gpio19里的ecap1功能以及gpio3里的epwm2b功能,但是gpio19是MUX2,gpio3是MUX1呀,这会造成引脚复用吗?
l
我看了下您发的技术索引手册110页,发现gpio19对应的是GPAMUX2 Register Bits里的7-6,gpio3对应的同样是GPAMUX1 Register Bits里的7-6。我使用了gpio19里的ecap1功能以及gpio3里的epwm2b功能,但是gpio19是MUX2,gpio3是MUX1呀,这会造成引脚复用吗?
不会的。根据你的描述来看也是不会的。
按照你的描述,
工程可以正常工作-->添加eCAP后度数不准-->注释掉ePWM后正常,
添加的程序以及注释的程序能大致描述一下吗?
我建议你可以边添加程序边通过添加断点及单步运行的方式debug一下,看一下具体是哪一部分的代码导致问题产生。注释程序的过程可以通过同样的方式dubug。
添加的程序是ecap1的配置模块和中断模块,代码如下:
void InitECap1() { ECap1Regs.ECEINT.all = 0x0000; // Disable all capture interrupts ECap1Regs.ECCLR.all = 0xFFFF; // Clear all CAP interrupt flags ECap1Regs.ECCTL1.bit.CAPLDEN = 0; // Disable CAP1-CAP4 register loads ECap1Regs.ECCTL2.bit.TSCTRSTOP = 0; // Make sure the counter is stopped ECap1Regs.ECCTL2.bit.CONT_ONESHT = 1; // One-shot ECap1Regs.ECCTL2.bit.STOP_WRAP = 3; // Stop at 4 events ECap1Regs.ECCTL1.bit.CAP1POL = 1; // Falling edge ECap1Regs.ECCTL1.bit.CAP2POL = 0; // Rising edge ECap1Regs.ECCTL1.bit.CAP3POL = 1; // Falling edge ECap1Regs.ECCTL1.bit.CAP4POL = 0; // Rising edge ECap1Regs.ECCTL1.bit.CTRRST1 = 1; // Difference operation ECap1Regs.ECCTL1.bit.CTRRST2 = 1; // Difference operation ECap1Regs.ECCTL1.bit.CTRRST3 = 1; // Difference operation ECap1Regs.ECCTL1.bit.CTRRST4 = 1; // Difference operation ECap1Regs.ECCTL2.bit.SYNCI_EN = 1; // Enable sync in ECap1Regs.ECCTL2.bit.SYNCO_SEL = 0; // Pass through ECap1Regs.ECCTL1.bit.CAPLDEN = 1; // Enable capture units ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1; // Start Counter ECap1Regs.ECCTL2.bit.REARM = 1; // arm one-shot ECap1Regs.ECCTL1.bit.CAPLDEN = 1; // Enable CAP1-CAP4 register loads ECap1Regs.ECEINT.bit.CEVT4 = 1; // 4 events = interrupt } __interrupt void ecap1_isr(void) { nCAP1=(ECap1Regs.CAP1 + ECap1Regs.CAP2); nCAP2=(ECap1Regs.CAP3 + ECap1Regs.CAP4); Freq_Flag1=1; ECap1Regs.ECCLR.bit.CEVT4 = 1; ECap1Regs.ECCLR.bit.INT = 1; ECap1Regs.ECCTL2.bit.REARM = 1; PieCtrlRegs.PIEACK.all = PIEACK_GROUP4; }
注释掉的程序是epwm1的配置模块,代码如下:
void InitEPwm1(void) { EPwm1Regs.TBPRD = TB_PERIOD; EPwm1Regs.CMPA.half.CMPA = DUTY_VALUE; EPwm1Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1; EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Asymmetrical mode EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Master module EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW; EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR=Zero EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR=Zero EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // set actions for EPwm3A EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // EPwm1Regs.AQCTLA.bit.ZRO = AQ_CLEAR; // set actions for EPwm3A // EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // Interrupt where we will change the Compare Values EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT EPwm1Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 3rd event EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module EPwm1Regs.DBFED = DB_VALUE; // FED = 300 TBCLKs initially EPwm1Regs.DBRED = DB_VALUE; // RED = 300 TBCLKs initially }
添加的ecap1配置和中断程序是跟着官方例程来的所以应该不会有问题,epwm1注释掉之后ecap1程序就正常了,所以我怀疑是epwm1程序的问题。
您说的“边添加程序边通过添加断点及单步运行的方式debug一下”,我就是通过一步步添加程序来定位到是epwm1的问题的,另外单步运行是怎么操作的呢,这个没弄过。
目前只知道应该是epwm1的问题,但是具体是什么问题什么原因,就不清楚,所以很卡进度 T T
您说的“边添加程序边通过添加断点及单步运行的方式debug一下”,我就是通过一步步添加程序来定位到是epwm1的问题的,另外单步运行是怎么操作的呢,这个没弄过。
打了断点之后,debug按钮后面有单步运行的图标;
我会看一下的。另外在几个硬件上发现了这个问题?有没有多换几个板子尝试一下?
我在E2E上找到一个类似的问题:
看起来问题似乎与那个客户的硬件有关系。因为我们的工程师试过之后是正常的,复现不了问题。
链接里E2E上的问题跟我这个症状一致,只是芯片型号不同。
我有一个板子,所以没有办法换板子验证问题。
我完全是新手,我会在之后多试用断点单步运行的功能。
目前的情况是我把epwm1换成epwm2,epwm2换成epwm3,这样调换的目的是避免使用epwm1,测试结果显示ecap功能正常,epwm在debug时占空比数值正常,但是还需要用示波器实测波形是否正确,涉及到硬件改线所以暂时无法完全验证代码。
如果是问题原因来源于硬件,我会在有其它板子时尝试验证是否会发生同样问题。
目前的情况是我把epwm1换成epwm2,epwm2换成epwm3,这样调换的目的是避免使用epwm1,测试结果显示ecap功能正常,
看起来这个问题应该不是器件本身设计及原理上的问题。
如果ePWM资源充足的话,就先不要使用ePWM1了。