Hi Guys,
I followed the code by the second example (p.6-7). Unfortunately, it never came out the waveform as shown in figure 6. I guess it is the problem of interrupt. Following is the complete codes. Could you please give me some hints to correct the problem? Thanks in advance!
Ed
---------------------------------------------------------------------------------------------------
/* error existing!!!
GENERATE PULSE OUTPUT STRINGS (CONTINUOUS MODE)
PULSE WIDTH = (DelayB - DelayA)*PDB_freq
PULSE PERIOD = PDB COUNTER MODULO * PDB_freq
PERIOD = RTC overflow period (RTC clock)
*/
#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
void rtc_init(void);
void pdb1_init(void);
char pdb1_cont_times = 0;
void main(void) {
SOPT1 = SOPT1_BKGDPE_MASK | SOPT1_RSTPE_MASK;//Disable COP,disable stop,Enable Reset
//EnableInterrupts; /* enable interrupts */
/* include your code here */
rtc_init();
pdb1_init();
pdb1_cont_times = 0;
PTDD_PTDD3 = 0;
EnableInterrupts;
for(;;) {
//__RESET_WATCHDOG(); /* feeds the dog */
} /* loop forever */
/* please make sure that you never leave main */
}
void rtc_init(void) {
/* Select the 1-KHz clock as the clock source, prescaler is 10 and modulo is 2 */
/* So that it triggers every 20 ms */
RTCMOD = 0x01;
/* RTCSC: RTIF(b7)=0,RTCLKS(b6:b5)=0,RTIE(b4)=0,RTCPS(b3:b0)=11 (0xB) */
/* RTCLKS = 0, Select the 1 KHz low power oscillator as clock source */
/* RTCPS = 11, RTC prescaler is 10 */
RTCSC = 0x0B;
}
void pdb1_init(void) {
PDB1CTRL1 = 0x00;
//PDB1CTRL2 = 0x00U;
PDB1CTRL2 = 0x02; //Enable continuous mode
PDB1MOD = 0x20;
//PDB1DLYA = 0x01U;
//PDB1DLYB = 0xFFFFU;
PDB1DLYA = 0x01;
PDB1DLYB = 0xff;
PDB1CTRL1_LDOK = 1;
//PDB1SCR = 0xC0U;
PDB1SCR = 0xF0; //Enable counter overflow interrupt
}
void interrupt rtc_isr(void){
PTDD_PTDD3 ^= 1;
RTCSC_RTIF = 1; /* Clear RTC interrupt */
}
void interrupt pdb1_isr(void){
if(PDB1SCR_COF == 1){
PDB1SCR_COF = 1;
if(PDB1CTRL2_CONT)
{
if(++pdb1_cont_times >= 5)
{
PDB1CTRL2_CONT = 0; //Disable continuous mode
pdb1_cont_times =0;
}
}else
{
PDB1CTRL2_CONT = 1;
pdb1_cont_times = 0;
}
}
if(PDB1SCR_DAF == 1)
PDB1SCR_DAF = 1;
if(PDB1SCR_DBF == 1)
PDB1SCR_DBF = 1;
}
---------------------------------------------------------------------------------------------------
Hi Ed,
If example 1 (PDB1 One-shot Mode) can work on your board, but example 2 (PDB1 Countinous Mode) cannot work, I think the cause could be that the register PDB1MOD is set as 0x20 on your code, it's smaller than PDB1DLYB, which is 0xFF, so that Trigger B even will never happen. The output pin keeps high, doesn't it?
However, if both example 1 and example 2 don't work, you need check the system initialization code and hardware connection.
Hope that helps.
Best regards,
Gang
Hello Gang,
Thanks for quick replying. You are right, there are some errors in the code. I corrected these errors and now it looks nearly the same as in the app. note. However, the output waveform is still different from Fig 6. I also attach the screenshoot of the waveform. What would be the reason?
(BTW, example 1 works out exactly the same results as shown in Fig 4 and 5. )
----------------------------------------------------------------------------------
/* error existing!!!
GENERATE PULSE OUTPUT STRINGS (CONTINUOUS MODE)
PULSE WIDTH = (DelayB - DelayA)*PDB_freq
PULSE PERIOD = PDB COUNTER MODULO * PDB_freq
PERIOD = RTC overflow period (RTC clock)
*/
#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
void rtc_init(void);
void PDB1_init(void);
char PDB1_cont_times;
void main(void) {
SOPT1 = SOPT1_BKGDPE_MASK | SOPT1_RSTPE_MASK;//Disable COP,disable stop,Enable Reset
//EnableInterrupts; /* enable interrupts */
/* include your code here */
rtc_init();
PDB1_init();
PDB1_cont_times = 0;
PTDD_PTDD3 = 0;
EnableInterrupts;
for(;;) {
//__RESET_WATCHDOG(); /* feeds the dog */
} /* loop forever */
/* please make sure that you never leave main */
}
void rtc_init(void) {
/* Select the 1-KHz clock as the clock source, prescaler is 10 and modulo is 2 */
/* So that it triggers every 20 ms */
RTCMOD = 0x01;
/* RTCSC: RTIF(b7)=0,RTCLKS(b6:b5)=0,RTIE(b4)=0,RTCPS(b3:b0)=11 (0xB) */
/* RTCLKS = 0, Select the 1 KHz low power oscillator as clock source */
/* RTCPS = 11, RTC prescaler is 10 */
RTCSC = 0x0B;
}
void PDB1_init(void) {
PDB1CTRL1 = 0x00;
//PDB1CTRL2 = 0x00U;
PDB1CTRL2 = 0x02; //Enable continuous mode
PDB1MOD = 0x2000;
//PDB1DLYA = 0x01U;
//PDB1DLYB = 0xFFFFU;
PDB1DLYA = 0x01;
PDB1DLYB = 0x1000;
PDB1CTRL1_LDOK = 1;
//PDB1SCR = 0xC0U;
PDB1SCR = 0xF0; //Enable counter overflow interrupt
}
void interrupt rtc_isr(void){
PTDD_PTDD3 ^= 1;
//RTCSC_RTIF = 1; /* Clear RTC interrupt */
}
void interrupt PDB1_isr(void){
if(PDB1SCR_COF == 1){
PDB1SCR_COF = 1;
if(PDB1CTRL2_CONT)
{
if(++PDB1_cont_times >= 5)
{
PDB1CTRL2_CONT = 0; //Disable continuous mode
PDB1_cont_times =0;
}
}else
{
PDB1CTRL2_CONT = 1;
PDB1_cont_times = 0;
}
}
if(PDB1SCR_DAF == 1)
PDB1SCR_DAF = 1;
if(PDB1SCR_DBF == 1)
PDB1SCR_DBF = 1;
}
----------------------------------------------------------------------------------
Hi Ed,
The waveform is very weird, I don’t know how it happens. But on the RTC interrupt service routine, RTCSC_RTIF should be written 1 to clear the RTC interrupt flag. Please modify and try whether it can make anything different.
Best Regards,
Gang Chen
Hi Gang,
I uncomment the line
RTCSC_RTIF = 1; | /* Clear RTC interrupt */ |
however, the waveform looks the same as before. I am pretty sure there must be something wrong with the interrupt function. I tested the interrupt using following code. In the True-Time Simulator window "Data", variables Seconds and Minutes are always zero, variable x changes seemly randomly (not from 0 to 9 as | expected).
Regards,
Ed
---------------------------------------------------------------
#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
int Seconds ;
int Minutes ;
int x;
void main(void) {
SOPT1 = SOPT1_BKGDPE_MASK | SOPT1_RSTPE_MASK;//Disable COP,disable stop,Enable Reset
EnableInterrupts; /* enable interrupts */
/* include your code here */
Seconds =0;
Minutes =0;
x = 0;
RTCMOD = 0x0f; //count from 0 to 9 and then interrupt happens, therefore 10*0.1sec = 1sec time-out
RTCSC = RTCSC_RTIE_MASK | RTCSC_RTCPS3_MASK | RTCSC_RTCPS2_MASK | RTCSC_RTCPS1_MASK| RTCSC_RTCPS0_MASK;
for(;;) {
if(RTCCNT ==5 && x<10) x = x+1;
else if(x>=10) x=0;
//__RESET_WATCHDOG(); /* feeds the dog */
} /* loop forever */
/* please make sure that you never leave main */
}
//#pragma TRAP_PROC
void interrupt RTC_ISR(void){
RTCSC = RTCSC | RTCSC_RTIF_MASK; //Clear RTIF BY WRITING A 1 TO IT
/* RTC interrupts every 1 Second */
Seconds = Seconds + 1;
/* 60 seconds in a minute */
if (Seconds > 59){
Minutes++;
Seconds = 0;
}
}
---------------------------------------------------------------
Hi Ed,
According to your description, I think maybe the RTC interrupt service routine is not entered. How do you define the interrupt vector address? Could you set a breakpoint to find if it enters the RTC_ISR() function when the RTC interrupt happens?
Best Regards,
Gang Chen
Hi Gang,
It seems not allowed to set breakpoint within a interrup routine. When I do it, the breakpoint is set in the previous bracket '}' above the interrupt routine. I checked RTIF bit value of register RTCSC is always 0, doesn't that means the interrupt routine is entered? I also find if I comment out the interrupt service routine, the RTIF bit is always 1.
Ed
Hi Ed,
It’s also weird that you could not set a breakpoint with an interrupt routine. Can you set any breakpoint elsewhere?
Maybe you can try to clean your project, and re-build it. Or move the interrupt function to a different place of the code. Please check whether the file paths in your project are all correct, and whether the generated bin files are updated when you re-build the project.
Best Regards,
Gang Chen
Hi Gang Chen,
Thanks for your kind reply.
To be honest, the interrupt problem is always there, in other words, I never succeed in interrupt routine in several projects. The tricky thing is, when I remove the interrupt, everything work out fine; if it is added, the waveform is always strange. I tested followings, breakpoint is fine, it doesn't help whether I move the interrupt function to an another location of the code. One more thing, I am testing the example of synchronizing FTM, ADC, with PDB. Without adc_isr, everything works fine, I got similar waveforms of PWM output and PDB pulse as shown in Fig 11; as long as the adc_isr is added, these two waveforms become strange and unstable, what's more, ADCR register value is always 0 which indicates ADC module doesn't work. I am completed lost with interrupt function.
Do you have some testing codes which works out fine with MP16? Maybe I can copy it and quickly test it on my board.
Regards,
Ed
Hi Ed,
The zipped project is based on CW10.x. Are you using CW6.x? Could you please send me your project package to have a test?
Best Regards,
Gang Chen
Hi Ed,
Sorry for late reply.
On your project files, you defined interrupt service routines, but you didn’t define the vector address for those interrupts. That’s why on your program the interrupts will not happen.
Please refer to the enclosed file, add below statements onto file project.prm to define vector addresses:
VECTOR 0 _Startup /* Reset vector: this is the default entry point for an application. */
VECTOR ADDRESS 0xFFCE rtc_isr
VECTOR ADDRESS 0xFFDE PDB1_isr
Best regards,
Chen Gang
Hi Chen Gang,
Yes, you are right! Finally it works out fine. Thanks a lot for your help:-)
Now I would like to set the Interrupt Priority, I don't understand the description of Interrupt Level SettingRegisters (ILRS0–ILRS11) in the reference manual completely. Do you know any app. note that explains this topic clearly?
Regards,
Ed
Hi Ed,
Glad to know you have solved the problem and got expected results, congratulations!
I don’t have AN about the interrupt priority control either. However I think it should be very straightforward and easy to use. Please rise a new topic on the community if you have further problems and questions about it, we will be glad to help you.
Best Regards,
Gang Chen