Hi
I am trying to read the PWM counter register in MC56F827xx MCU (PWMA_SMnCNT) at a PWM reload ISR event (please see the attached code). It should read zero all the time as the reload event happens when the counter is reset, but, instead I read 143. Is there a delay once the Reload ISR is called and the counter register is read? Am I reading it correctly? Please help.
Thanks.
Rishad
Hi, Md,
I have reviewed your code, you enable Full Reload interrupt, in the ISR of Full Reload interrupt, you read the PWMA_SM0CNT;. From theory, the tick variable should be the value as PWMA_SM0INIT, which is zero.
As you know it takes time for the DSC core to execute ISR, for example, PC, SR register are stored to stack, jump to ISR, because you use the "#pragma interrupt saveall", all the DSC core registers have to be put into stack,that is why the delay exists and you get non-zero value when you read PWMA_SM0CNT;, it means that the PWMA_SM0CNT reaches up to 143 when you read it.
Pls delete the #pragma interrupt saveall and use #pragma interrupt on, have a try.
I suggest you toggle a GPIO in the ISR and compare the PWM and GPIO timing.
Hope it can help you
BR
Xiangjun Rong
Hi Xiangjun,
Thanks for your suggestion. #pragma interrupt on slightly reduces the delay. If you can tell me any other way of further reduce the delay that would be great.
In another ISR , ADC High Limit Interrupt, I am trying to read the ADC value at a specific point (please see the attached figure- I am trying to read the minimum value). I am using the following simple code to read the ADC result when the interrupt happens (Sample 0 > 0.85 V). However, I am reading multiple values (gradually increasing) instead of just one when the interrupt happens. Also the values are changing all the time. I am using a structure named adc0_array to save 100 values. Will you please let me know where is the problem?
Thanks. Rishad
SIM_PCE0 |= 0x1<<6; // Enable GPIOA clock
GPIOA_PER = 0x00FFU; // PER Enable for GPIOA 0-7
SIM_PCE2 |= 1<<7; // enable clock to ADC modules
ADC_CTRL1 = 0x2105;
ADC_CTRL2 = 0x1804U;
ADC_CLIST1 = 0x3210U; // SAMPLE3 - ANA3, SAMPLE2 - ANA2,SAMPLE1 - ANA1, SAMPLE0 - ANA0
ADC_SDIS = 0xFEFEU; // enable ADC channels 0&8 -> ANA0 (pin 22), ANB0 (pin33)
ADC_PWR = 0x01A0U; // power-up delay set to 26 clocks
ADC_HILIM0 = 0x431 << 3; // High limit threshold
/* Enable high limit interrupt - priority 1 */
INTC_IPR2 |= 1<<13;
for(;;) {
ADC_CTRL1 |= 1<<13;
}
#pragma interrupt alignsp
#pragma interrupt on
void ADCA_Ch0_HighLimit_ISR() {
adc_array* pAdc0_array = &adc0_array;
adc0_array.array[adc0_array.c] = (0x7ff8 & ADC_RSLT0) >> 3;
adc0_array.c++;
ADC_HILIMSTAT = 0xFFFF;
}
Hi, Md,
I do not think you can use your code to start ADC.
you can use the process:
ADC_CTRL1 |= 1<<13; //start ADC
poll if the completion is over, read sample
for(;;) {
ADC_CTRL1 |= 1<<13; //start ADC
//poll if the completion is over
while(!ADC_STAT&EOSI0) {}
unsigned int sample=ADC_RSLTx
}
Regarding the reducing the interrupt latency, you can use fast interrupt. Pls refer to the section:
12.3.3 Fast Interrupt Handling in RM of MC56F827xx.
You can use the signal in crossbar switch module to trigger ADC. pls refer to section 3.3.3 Inter-Peripheral Crossbar Switch (XBAR) and AND/OR/INVERT (AOI) Configuration
Hope it can help you
BR
Xiangjun Rong
Hi Xiang,
Thanks for your recommendation. Polling seems to give me slightly better results. However, I am still getting different values for different cycles. My first question, what can do to get consistent ADC values for different cycles of the feedback signal? The second question is, how can I make sure HILIM ISR executes only once a cycle to get the minimum value from the feedback signal (ref to the previous figure)?
Best regards,
Rishad