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....

Parents Reply Children
  • & 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