This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Problems with Timer1 and 2 of SAB80C535

Morning,

I have some stupid troubles with my SAB80C535 µP. I'm trying to read a acceleration sensor (ADXL202JE) with timer 1 and 2. It works aproximatily fine, excepting the "turbulent" resolution, when the timers work separately. But when i put the two timers together in the main programm then all is messed up. The equation is all disturbed and i get astronomical numbers close to ininit or zero. Can it be posible that the timer 1 and 2 cant work together or are there any priority confuses??
Its driving me crazy !!!!!

Thanks for any answer....

  • I have some suggestions, but I see no reason to talk to a non-person ('no name'). If you are so worried about your identity, why do you even use the web.

    Erik

  • Oh, you thought i'm from outta space or something like that?? Just a joke. Here's my real name: Andreas Sturm from "zee" Germans. I would really apriciate your sugestion, please.

  • I have some stupid troubles with my SAB80C535 µP. I'm trying to read a acceleration sensor (ADXL202JE) with timer 1 and 2. It works aproximatily fine, excepting the "turbulent" resolution, when the timers work separately. But when i put the two timers together in the main programm then all is messed up. The equation is all disturbed and i get astronomical numbers close to ininit or zero. Can it be posible that the timer 1 and 2 cant work together or are there any priority confuses??

    Andreas,
    what I guess you are seeing is that the timer interrupts interact because the ISR for one is not completed before the interrupt for the other activates. This would lead to situations like e.g. T1 interrupt and start executing the T1 ISR then t2 set the interrupt flag while reading 47. When the T1 ISR completes, the T2 ISR is entered, but by that time T2 reads 69 OOPS.

    I can not totally visualize your thingy by your description, but from what little I get I would suggest you look into doing it with a PCA (most derivatives) or a CGA (NXP LPC series) maybe some other manufacturers have something similar with different names, i would not know.

    Re PCA, have a look at The PCA cookbook
    www.intel.com/.../270609.htm

    Its driving me crazy !!!!!
    you will get over it, most seasoned '51 developers have no problem with that simply because "you can not be driven to where you already are" :)

    Erik

  • set the interrupt flag while reading 47 . Whats that supposed to mean? What is 47 or 69 OOPS ?? This is not happening to me.... i've covered the main program in some while statements with leaving them only after setting a flag in the interrupt routine. It must be something with the timers working tougether, i dont know.
    you will get over it, most seasoned '51 developers have no problem with that simply because "you can not be driven to where you already are" :)
    ohhh man, this is so funny, even my shoes are laughing, ohhhh....ohhhh ....please stop..

  • Whats that supposed to mean
    ?show your timer ISRs (please with

     and
    

    - see above) and I may be able to come up with a concrete example.

    Erik

  • & l t p r e & g t and & l t / p r e & g t

    when enterd withour spaces do work in other fora to show the 'pre modifiers', just not here

    so above you see 'pre' in a full form, please use it

    erik

  • "so above you see 'pre' in a full form, please use it"

    Erik is just asking you to follow the instructions when you post source code - see: http://www.keil.com/forum/tips.asp

  • My source cod is extremely big. I'll try to post it:

    
                    e = 0;          // Laufvariable für die Arrays löschen
                    r = 0;
                    f = 0;
                    printf ("Daten werden eingelesen \n");
    
    
                    TMOD = TMOD & 0x0F;         // Timer 1 Control-Register wird gelöscht
                    T2CON = 0x40;                   // Timer 2 gestoppt, kein Reload, positive Flanke für CC0
                                                                    // so wird erkannt wann der Impuls beginnt.
    // Priorität der Interrupts festlegen
    
                    IP0 = IP0 || 0x03;              // Interrupt 1 und 3 auf
                    IP1 = IP1 || 0x03;              // höchste Priorität setzen
    
    
    
            while (e <= 999) //&& (r <= 1000) )
            {
    
                    test_X = 0;             // Testvariablen ob die ISR schon
                    test_Y = 0;     // durchgelaufen ist für verschiedene Achsen
                    test_T2= 0;
    
    // Interrupt enable flags im IEN0 und IEN1
                    EAL = 1;        //      All interrupt are enabled
                    EX1 = 0;        //      Disable Interrupt for T1
                    EX3 = 0;        //      Disable Interrupt for CC0
                    EX4 = 0;        //      Disable Interrupt for CC1
                    ET1 = 0;        //      Disable Interrupt for T1 overflow
                    ET2 = 0;        //      Disable Interrupt for T2 overflow
    
    // Timer 1 Control Byte (Timer 1 stoppen wird erst später benutzt)
                    TF1 = 0;        // Timer 1 overflow bit (deleted)
                    TR1 = 0;        // Timer 1 run bit (deleted)
                    IT1 = 0;        // Interrupt positiv flankengetriggert
    
    // Register der Timer löschen
                    TL1 = 0;        // Zählregister des Timers 1
                    TH1 = 0;        // löschen
                    TL2 = 0;        // Zählregister des Timers 2
                    TH2 = 0;        // löschen
    
    // Register der Capture - Unit (CC0 & CC1) vom Timer 2 löschen
    //              CRCL = 0;       // Capture-Register der
    //              CRCH = 0;       // CC0 und der
    //              CCL1 = 0;       // CC1 löschen
    //              CCH1 = 0;
    
    //
    //Mit dem Timer 1 wird die Impulsbreite für die Y-Achse gemessen.
    //
            while (test_Y == 0)
            {
                            IE1 = 0;
                            TMOD = TMOD | 0x90;
                            TR1 = 1;
                            EX1 = 1;
            }
    //
    //      Timer 2 in "capture mode", bei CC1 wird die Zeit T2 für beide Achsen messen.
    //
            while (test_T2 == 0)    // Prüfen ob ISR nicht durchlaufen wurde
            {
                    if (IEX4 == 1)          // Wenn die positive Flanke erkannt wurde
                    {
                            IEX4 = 0;
                            CCEN  = 0x04;   // CC1 capture on rising edge
                        T2CON = 0x41;       // startet der Timer 2 in "capture mode" bei 1MHz
                            EX4 = 1;                // External interrupt enable for CC1
                    }
            }
    //
    // Timer 2 in "capture mode", bei CC0 wird die Impulsbreite für die X-Achse gemessen
    //
            while (test_X == 0)
            {
                    if (IEX3 == 1)
                    {
                            IEX3 = 0;
                            CCEN = 0x01;    // CC0 wird erst auf steigende Flanke gestellt
                            T2CON = 0x01;   // zur Impulserkennung und dann auf fallende um
                            EX3 = 1;                // den Impuls zu messen.
                    }
            }
    
    //
    // Aus den Werten der beiden Achsen (T1_X und T1_Y) und der gemeinsamen Periodendauer
    // T2 wird der Beschleunigungswert ausgerechnet.
    //
                            X = T1_X;               // Dateikonvertierung in Gleitkommazahl
                            Y = T1_Y;               // für die Division
                            Z = T2;
    
            // Nach dem folgendem Algorithmus wird der g-Wert berechnet
            // für beide Achsen mit der gemeinsamen Periodendauer T2
                            ACC_ARRAY_Y[e] = ((Y/Z)-0.5)/0.125;
                            ACC_ARRAY_X[e] = ((X/Z)-0.5)/0.125;
    
    //                      printf ("ACC_X[%d] = %f g \n",e, ACC_ARRAY_X[e]);
    //                      printf ("ACC_Y[%d] = %f g \n",e, ACC_ARRAY_Y[e]);
    
                            e = e + 1;                              // Array-Variable um 1 erhöhen
    //                      printf ("%d \n",e);           // Aktueller Stand ausgeben
    
    }
    //
    //Nach dem einlesen und verarbeiten werden die zwie g Werte ausgegeben
    //
            while (r <= 999)
            {
                            FILTER_X = (ACC_ARRAY_X[r] + ACC_ARRAY_X[r+1] + ACC_ARRAY_X[r+2])/3;
                            printf ("ACC_Xxx[%d] = %f g \n",r, FILTER_X);
                            r = r + 1;
            }
    
            while (f <= 999)
            {
                            FILTER_Y = (ACC_ARRAY_Y[f] + ACC_ARRAY_Y[f+1] + ACC_ARRAY_Y[f+2])/3;
                            printf ("ACC_Y[%d] = %f g \n",f, FILTER_Y);
                            f = f + 1;
            }
    

    That is the main program, the ISR is following:

  • This is the ISR:

     void timer1_Int  (void) interrupt 2    // Y-Achse T1
            {
    // Diese ISR wird die Impulsbreite T1 (ms) für die Y-Achse aufnehmen
    // und wird dann mit der Periodendauer T2 (die für X und Y gleich ist)
    // als Algorithmus die Beschleunigung ausgeben.
    
                            TR1 = 0;        //      Timer 1 gestoppt
    
            // Timer 1 Register einlesen und g-Wert ausrechnen für Y
                            T1_Y = TH1;
                            T1_Y = T1_Y << 8;
                            T1_Y = T1_Y | TL1;
    
            // Timer 1 Register löschen und Interrupt Routine verlassen
            //              TH1 = 0;                        // Register mit Zählwert
            //              TL1 = 0;                        // von T1 löschen
    
                            test_Y = 1;
    
                            EX1 = 0;
                            IE1 = 0;                        // Interrupt flag löschen
    
    
            }
    
    void timer2_CC0_Int  (void) interrupt 10        // X-Achse T1
            {
    // Diese ISR wird die Impulsbreite für die X-Achse einlesen
    // und zusammmen mit T2 den Beschlwert ausgeben
    
                            T2CON = 0x40;           //      Timer 2 stoppen
                            CCEN =  0x00;
    
            // Register der CC0 einlesen und g-Wert ausrechnen für X
                            T1_X = CRCH;                    // Wert aus den Registern der
                            T1_X = T1_X << 8;         // Capture-Unit auslesen
                            T1_X = T1_X | CRCL;
    
            // Register von Timer 2 löschen
                            TL2 = 0;                        // Zählregister des
                            TH2 = 0;                        // Timers und der
    
            // Register der CC1 löschen
                            CRCL = 0;                       // Capture unit CC0
                            CRCH = 0;                       // löschen
    
                            test_X = 1;             // ISR Laufvariable setzen
                            IEX3 = 0;
    
            }
    
    void timer2_CC1_Int  (void) interrupt 11        // X & Y-Achse T2
            {
    // Diese ISR wird die Periodendauer für die X und Y-Achse
    // T2 einlesen und weiterverarbeiten
                            T2CON = 0x40;           //      Timer 2 stoppen
                            CCEN =  0x00;
    
            // Register der CC1 einlesen und Periodendauer T2 speichern
                            T2 = CCH1;
                            T2 = T2 << 8;
                            T2 = T2 | CCL1;
    
            // Register von Timer 2 löschen
                            TL2 = 0;
                            TH2 = 0;
    
            // Register der CC1 löschen
                            CCL1 = 0;
                            CCH1 = 0;
    
                            test_T2 = 1;            // Laufvariable setzen
                            IEX4 = 0;                       // Interrupt flag löschen
    
            }
    

    The comments are in german so if you have questions dont be afraid to ask. Thanks

  • could you tell us what are and what triggers interrupts 10 and 11?

    Erik

  • Interrupt 10 is for the CC0 unit of timer 2 and is triggered at falling edge. In the main program i first wait for the rising edge and then start the timer and then the interrupt ocurs at the next rising edge. Thats how i messure the pulswidth of one period.

    Interrupt 11 is for the CC1 unit of the timer 2 and is trigered at rising edge and it is used to messure the time of one period.

  • anyhow, as stated before and now with a specific example
    if T2 interrupts and, one instruction cycle later T1 interrupts, you will get a misread on T1 of something like 40 counts (I can not give anything accurate based on C source). Could that be what you are seing?

    Erik

  • The first timer that starts is the Timer 1:

            while (test_Y == 0)
            {
                            IE1 = 0;
                            TMOD = TMOD | 0x90;
                            TR1 = 1;
                            EX1 = 1;
            }
    


    The while statement is there so the program can't change to anouther while statement. It waits till the interrupt of timer1 is over and then goes to the next statement. I dont know if this is the problem. Because even if i put timer 1 first or second it doesn't matter, the reaction is the same. What i am seeing on the Timer 1 register is 0. That meens he doesent start o something like that. How could that be?

  • Just to see, Y would try

            {
                            IE1 = 0;
                            TMOD = TMOD & 0x0f;
                            TMOD = TMOD | 0x90;
                            TR1 = 1;
                            EX1 = 1;
            }
    

    Erik