Topic : CCFn not resetted after interrupt in PCA High Speed Output Mode

Forum : 8051

Original Post
Post Information Post
May 21, 2011 - 2:47pm
Guest

In Ride 6.10 version, I have a routine using a high speed output mode of one of the PCA modules. CCFn is set when PCA register CHL match with the CCAPnHL register, causing the CCFn flag to be set to 1, and an interrupt occur. When the interrupt routine is called, the CCFn should be reset to 0 by the statement CCFn=0. But after the statement is processed, the CCFn flag still is 1. This causes continious interrupts. Does this happed also with the 8051 microcontroller, - or is it a bug in Ride software?

Replies
Post Information Post
+1
0
-1
May 24, 2011 - 9:49am
Raisonance Support Team

Hi Skule,

The version you are using is outdated. There are many different reasons that could make such a problem happen (Compiler misbehavior, header file invalid, simulator problem...).
Can you install the latest Ride7 and RKit-51 versions from http://www.mcu-raisonance.com/mcu_downloads.html and check again?

In case the problem persists, can you send us a zipped copy of your project so that we can reproduce the problem in our Labs?
Thanks by advance,

+1
0
-1
May 27, 2011 - 10:43pm
Guest

After installing the Ride7 and the RKit-51 I can't find any PCA view register possibilities, and the PCA registre CH an CL is not running in the debug mode, - even when the CR flag is set and the CCON register is set to 0xC0. No PCA interrupt occur at all in this version. At least it did that in the 6.1 version I have a lisence on. The microcontroller simulated is an AT89C51ED2 in the both cases.
Have I missed somthing in the setting in the Ride7-version??
Another strange matter: The AT80C51ED2 manual says than the PCA interrupt vector number is 7. But in RIDE it respons on number 6.

+1
0
-1
May 30, 2011 - 4:36pm
Raisonance Support Team

Hi Skule,

There should not be any simulation difference between Ride6 and Ride7.
What you can do is import your Ride6 project into Ride7 "Project | Open | Change "File type" to "Ride6 project" and open). Once you do this, all your specific project settings will be preserved, and you should recover the exact same behavior you had on Ride6.

In case you still have an issue, can you please send us a zipped copy of your project (including object, listings, map file) so that we can try to reproduce it in our Labs?

Best Regards,

+1
0
-1
May 30, 2011 - 5:20pm
Guest

The same source code was run in the both envirements, with diifferent results. The Harware Peripherals shown in Ride7 are Ports, Interrupt Controller and UART 0 only, while in Ride6 Timers and PCA register are shown in addition. In Ride7 the Intrrupt Controller showed UART 0 interrupt only, while in Ride 6 all interrupt levels where shown. The PCA interrupt setting did not serviced the PCA interrupt routines in RIDE7. In addition the CCFn- flags was not able to be resettet in the PCA interrupt routine in the Ride6 envirement.

I am very happy to ship my software case to you for further evaluation.

+1
0
-1
May 31, 2011 - 10:42am
Raisonance Support Team

Hi Skule,

We received your source code, but have not been able to reproduce the problem in our Labs.

We guessed that you are using an Atmel T89C51RD2, and programmed the following code (slightly modified from what you sent us):

#include 

char data flag0 = 0;

void fct_pca( void ) interrupt 6
{
    if ( CF == 1 ) // **********************  PCA overflow
    {
        CF = 0;
    }

    if ( CCF1 == 1 ) //  **********************  pulsbredde servo
    {
        CCF1 = 0;
    }

    if ( CCF0 == 1 ) //  **********************  pulsbredde servo
    {
        if ( flag0 == 0 ) // positiv triggeflanke.
        {
            CCAP0L = 0x10; //CL+kommando_pos-kommando_pos/256;  // sett neste compare-punkt (heltallsdivisjon)
            CCAP0H = 0x10; //CH+kommando_pos/256;
            flag0 = -1;
        }
        else
        {
            CCAP0L = 0xf0; //CL+(pulsbredde_total - kommando_pos)-(pulsbredde_total -kommando_pos)/256;  // sett neste compare-punkt
            CCAP0H = 0xf0; //CH+(pulsbredde_total - kommando_pos)/256;
            flag0 = 0;
        }
        CCF0 = 0;
    }
}

void main( void )
{
    CL = 0xF0;
    CH = 0x0F;
    CCAP1L = 0x10;  // Set initial value PCA (CHL)
    CCAP1H = 0x10;
    CMOD = 3;       // div 2 (6Mz operation), PCA Enable Counter Overflow Interrupt
    CCAPM0 = 0x4D;  // #0 High Speed Output enable
    CCAPM1 = 0x4D;  // #1 High Speed Output enable
    CCON = 0xC3;    // PCA Counter Run, Module 0 & Module 1 interrupt flag enable
    CR = 1;         // start PCA register
    EC = 1;         //enable PCA interrupt
    EA = 1;         // enable mai interrupt

    while ( 1 )
    {
    }
}

When launching the simulator on Ride7, we clearly have the Timer0, Timer1, Timer2 and PCA peripherals.
When running the code, the simulator works fine, we can see the increasing CHL register in the PCA.

I think you selected a wrong device in the list. Can you try to import your Ride6 project (see procedure in my reply above) and check again? Double-check the device in both Ride6 and Ride7, they should have the exact same name.

Best Regards,

+1
0
-1
May 31, 2011 - 6:09pm
Guest

In the Ride 7 environment, after first selecting 'Reset to default this group options' in processor setting in Project Properties, and then selecting 'P89C51RD+' processor type again, all the registers appear in Debug View panel i Ride7 (as what happen i Ride 6). But still the CCF0 = 0 code line does not clear the CCF0 flag. That happen in the both Ride 6 and Ride 7 environment. If you set a break at this line in the interrupt routine, I suppose you will confirm my experience.

+1
0
-1
June 1, 2011 - 10:24am
Raisonance Support Team

Hi,

I confirm this behavior. This is similar on Ride6 and Ride7.

Best Regards,

+1
0
-1
June 2, 2011 - 12:22am
Guest

The point is that this should not happen, - according to AT89C51RD manual. The CCF0 flag should be cleared when CCF0=0 program code is applied. But CCF0 is still 1 after the code is applied. It is a bug here somewhere.

It seems to happen when CCAP0HL < CHL in the interrupt PCA routine. Otherwise CCF0=0 is processed correctly. Does this happen also in the microcontroller?? Or is this the case in the simulator only??

The bug can be avoided by insert the code

CCF0=0;
if (CCF0==0)
flag0=0; // or flag0=-1 in the other branch

in the code example above to take care of the delay setting. But that does not help much, since the P1.3 port toggles by each interrupt anyway.

+1
0
-1
June 8, 2011 - 11:34am
Raisonance Support Team

Hi,

You are partly right: The CCF0 flag will be cleared by the hardware when the CH:CL (or CHL) 16-bit counter is greater or equal than the 16-bit CCAPxH:CCAPxL (for example CCAP0HL).

Our simulator properly behaves this way.

You "avoiding" code above is invalid in that it does not do what it is intended to. Your PCA must be properly set.

Best Regards,

+1
0
-1
June 8, 2011 - 6:27pm
Guest

The microcontroller manual says that the CCFO flag is set by match, not by greater or equal. It still seems to me that it is a bug here. This is tested by monitoring the P1.3 port by scope. The port toggles according to manual, but not in the Ride6 and Ride 7 simulation. The simulating show true value both on P1.3 and CCFO all the time, even if they are cleared by code.
High speed output with different delays on the two value levels of P1.3 is accomplished with the code:

if (CCF0==1)
{
CCF0=0;
if (flag==0)
{
CCAP0H +=delay1;
flag=-1;
}
else
{
CCAP0H +=delay2;
flag=0;
} ;
};

+1
0
-1
June 13, 2011 - 4:30pm
Guest

Instead of using a flag vaiable it is also possible to use

if (P1^3==0)

to make sure that the first delay is used for the low level of P1^3 and the other delay is for the high level of P1^3, since the port is toggle on each interrupt. In that case you do not need to set the flag to the opposite value in the code lines above, since the flag is not jused at all.
The code will then be:

if (CCF0==1)
{
CCF0=0;
if (P1^3==0)
CCAP0H +=delay1;
else
CCAP0H +=delay2;
};

In the simulation in Ride7 (and i Ride6) CCF0 is not cleared when the code above tells it to do. P1^3 is also not clear as it should do. I use a flag in1 declared as:

sbit in1 = P1^3;

instead of P1^3 in the code above, and that seems to work better in the simulations also.
The port P1^3 has been monitored by scope at the microcontroller, and it seems to work well there, both CCF0 and P1^3. So it is obviously something wrong in the simulator.