主题中讨论的其他器件:C2000WARE
您好!
我遇到了软件强制 ADC 转换的问题。 我有两个 ADC 中断。 一个是在 SO0和 SOC1上同步进行 ADC 转换时 EOC 触发的快速中断。 较慢的中断是在 SOC2和 SOC3上同步进行 ADC 转换时 EOC 触发的。 较慢的中断 SOC 从快速中断中的递减采样数中触发。 我注意到代码中有伪中断、似乎是软件强制中断调用的原因;在注释掉软件强制中断调用后、伪快速中断不会发生。 这个问题的另一个因素是我在 PIE 中使用了两个中断。 当我将较慢的中断更改为使用 PIEIER10时、代码工作正常。 请参阅以下代码。 我会发布我的所有代码、但很遗憾它很大。 重要的一点不是直接使用整个寄存器访问、而不是 c2000ware 代码中的逐位示例。 下面是我观察到的内容的屏幕截图
并注释掉软件强制中断
在软件强制中断的情况下、中断保持触发状态
以下 是相关的代码摘录。 我``问题出在快速 ISR 内部的 Δ Σ AdcRegs.ADCSOCFRC1 |= ADCSOC_SOC2;Δ Σ。 我的调试器显示 PIEIFR1和 ADCINTFLG 的中断标志看起来正确、也只有 ADCINT1处于暂挂状态。 然而、在调用软件强制 SoC 后、ADCINTFLG 会转至0x0103、PIEIFR1 = 0x0022、ADCINTOVF = 0x0003。 我已经检查 了 AdcRegs.ADCSOCFRC1的存储器地址、它是正确的。
问题:
- 是否无法从 ISR 上下文中调用软件强制 SoC?
- RMW 操作和 ADCSOCFRC1不正确吗?
- 是否一次无法使用来自 PIE 组的多个中断?
static const PwmConfig resolver_pwm_config = { .enable_center_aligned=true, .counts=937,//94, .adc_trigger={.enable=true, .event_scaler=ePwmSocPulseOnThirdEvent}, .compliment={.enable=false, .edge_delay=0}, .sync={.enable=false, .phase_counts=0, .sync_out=ePwmSyncOutSyncIn} }; static const SampleConfig resolver_adc_config = { .soc_index=0, .channel=eAdcInA0, .trigger_source=eAdcTriggerPwm1SocA, .sample_time=7, .enable_simultaneous_sample=true, .adc_interrupt={.enable=true, .interrupt_index=1} }; static const SampleConfig current_adc_config = { .soc_index=2, .channel=eAdcInA1, .trigger_source=eAdcTriggerSoftware, .sample_time=7, .enable_simultaneous_sample=true, .adc_interrupt={.enable=true, .interrupt_index=2} }; __interrupt void adc_resolver_isr(void) { static const unsigned down_count = 4; static unsigned isr_count = 0; hal_resolver_isr_pin_toggle(); hal_resolver_sin = AdcResult.ADCRESULT0; hal_resolver_cos = AdcResult.ADCRESULT1; // start phase current adc sampling if (++isr_count >= down_count) { isr_count = 0; AdcRegs.ADCSOCFRC1 |= ADCSOC_SOC2; } AdcRegs.ADCINTFLGCLR |= ADCINT_BIT1; AdcRegs.ADCINTOVFCLR |= ADCINT_BIT1; PieCtrlRegs.PIEACK = PIEACK_GROUP1; } __interrupt void adc_current_isr(void) { static unsigned down_count = 20; static unsigned isr_count = 0; hal_current_isr_pin_toggle(); hal_current_a = AdcResult.ADCRESULT2; hal_current_b = AdcResult.ADCRESULT3; AdcRegs.ADCINTFLGCLR |= ADCINT_BIT2; AdcRegs.ADCINTOVFCLR |= ADCINT_BIT2; PieCtrlRegs.PIEACK = PIEACK_GROUP1; } void hal_boot_init(void) { f28_setup_system_control(&system_config); DINT; // Disable CPU interrupts f28_setup_peripheral_interrupt_control(); // Disable CPU interrupts and clear all CPU interrupt flags IER = 0x0000; IFR = 0x0000; f28_setup_peripheral_interrupt_table(); // map isrs EALLOW; PieVectTable.ADCINT1 = &adc_resolver_isr; PieVectTable.ADCINT2 = &adc_current_isr; PieVectTable.ADCINT9 = &adc_1kHz_isr; PieVectTable.TINT2 = &cpu_timer2_isr; PieVectTable.SPIRXINTA = &sci_rxa_isr; EDIS; hal_gpio_init(); f28_adc_init(); f28_adc_soc_setup(&adc_1khz_config); f28_adc_soc_setup(¤t_adc_config); f28_adc_soc_setup(&resolver_adc_config); f28_timer_init(&CpuTimer2Regs, &msec_timer_config); f28_sci_init(&SciaRegs, &sci_a_config, LSPCLK_SPEED); f28_can_init(&can_node, &can_bitrate, &can_mask_filter); f28_pwm_init(&EPwm1Regs, &resolver_pwm_config); // Enable ADCINT1,2,9 PieCtrlRegs.PIEIER1 = (PIEIxR_INTx1 | PIEIxR_INTx2 | PIEIxR_INTx6); // Enable SCIRXA PieCtrlRegs.PIEIER9 = (PIEIxR_INTx1); // Enable Int1=Adc; Int9=sci; Int14=timer2 interrupt IER = (IxR_INT1 | IxR_INT9 | IxR_INT14); // Enable global Interrupts and higher priority real-time debug events EINT; // Enable Global interrupt INTM ERTM; // Enable Global realtime interrupt DBGM }
最后、这里是使用 ADCINT3和 PIEIER10的跟踪。 这就是我期望发生的情况。 代码更改如下;该代码不会在软件 SoC 启动后产生奇数 ADCINTFLG = 0x0103。 但是、它会产生 ADCINTFLG = 0x0005、PIEIF1 = 0x0002、PIEIF10 = 0x0007、ADCINTOVF = 0x0000。 这里奇怪的是、为什么 ADCINTFLG = 0x0005而不是0x0001?
static const SampleConfig current_adc_config = { .soc_index=2, .channel=eAdcInA1, .trigger_source=eAdcTriggerSoftware, .sample_time=7, .enable_simultaneous_sample=true, .adc_interrupt={.enable=true, .interrupt_index=3} }; __interrupt void adc_current_isr(void) { static unsigned down_count = 20; static unsigned isr_count = 0; hal_current_isr_pin_toggle(); hal_current_a = AdcResult.ADCRESULT2; hal_current_b = AdcResult.ADCRESULT3; AdcRegs.ADCINTFLGCLR |= ADCINT_BIT3; AdcRegs.ADCINTOVFCLR |= ADCINT_BIT3; PieCtrlRegs.PIEACK = PIEACK_GROUP10; } void hal_boot_init(void) { f28_setup_system_control(&system_config); DINT; // Disable CPU interrupts f28_setup_peripheral_interrupt_control(); // Disable CPU interrupts and clear all CPU interrupt flags IER = 0x0000; IFR = 0x0000; f28_setup_peripheral_interrupt_table(); // map isrs EALLOW; PieVectTable.ADCINT1 = &adc_resolver_isr; PieVectTable.ADCINT3 = &adc_current_isr; PieVectTable.ADCINT9 = &adc_1kHz_isr; PieVectTable.TINT2 = &cpu_timer2_isr; PieVectTable.SPIRXINTA = &sci_rxa_isr; EDIS; hal_gpio_init(); f28_adc_init(); f28_adc_soc_setup(&adc_1khz_config); f28_adc_soc_setup(¤t_adc_config); f28_adc_soc_setup(&resolver_adc_config); f28_timer_init(&CpuTimer2Regs, &msec_timer_config); f28_sci_init(&SciaRegs, &sci_a_config, LSPCLK_SPEED); f28_can_init(&can_node, &can_bitrate, &can_mask_filter); f28_pwm_init(&EPwm1Regs, &resolver_pwm_config); // Enable ADCINT1,2,9 PieCtrlRegs.PIEIER1 = (PIEIxR_INTx1 | PIEIxR_INTx6); PieCtrlRegs.PIEIER10 = PIEIxR_INTx3; // Enable SCIRXA PieCtrlRegs.PIEIER9 = (PIEIxR_INTx1); // Enable Int1=Adc; Int9=sci; Int14=timer2 interrupt IER = (IxR_INT1 | IxR_INT9 | IxR_INT10 | IxR_INT14); // Enable global Interrupts and higher priority real-time debug events EINT; // Enable Global interrupt INTM ERTM; // Enable Global realtime interrupt DBGM }