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....
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" :)
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.
& 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; }