We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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....
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?
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?
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; }