Hallo zusammen, versuche auf einem Atmega 128 eine variable Pulspaketbreite für eine eigene, definierte Codesequenz zu einem TSOP-Baustein im Polling zu erstellen. Erste Versuche mit 2 Timern führten zu einem gegenseitigen stören beider eingesetzten ISRs mit CTC oder Overflow Routinen. Nun habe ich einen einfachen C-Code für den Timer 0 geschrieben der allerdings noch im Timing und der Ausführung von Low un High "zickt"...*grübel* Hat jemand eine Idee wo drann es liegt bzw. gibt es eine noch einfachere Alternative solche Burst-Pakete mit der Nutzung von möglichst wenig Systemresourcen herzustellen?! Anbei der Code (Bild siehe Anhang): ------------------------------------------------------------------ #include <stdlib.h> #include <avr/io.h> #include <avr/interrupt.h> #include <avr/signal.h> volatile unsigned char code [6] = {1,200,100,300,100,400,100000}; //Array with 7 Values volatile unsigned char compare = 0; //Counter for Array place volatile unsigned char set= 0; //Setting high or Low Phase volatile unsigned char i= 0; //Counter for Compare to array value int boot_periphericals() // I/O and basic settings { SREG |= (1<<SREG_I); // Global Interrupts aktivieren } void boot_timer0 () // Timer 0 (8Bit) { DDRA = 0xFF; // PA0, PA1, PA2 selected as output PORTA = 0x00; // PA0, PA1, PA2 outputs on low (0) TCNT0 = 0x00; // Timer Start value OCR0 = 255; // Timer CTC value (0-255) TIMSK |=(1<<OCIE0); // Timer 0 CTC Match Interrupt enable } void boot_watchdog() // Watchdog for reseting in case of global corruption { WDTCR |= (1<<WDE); // Enable Watchdog with Timeout after 14.0 ms (Datasheet page 56) } //---------------------------------------------------------------------- ---------------- int main (void) { boot_periphericals(); boot_timer0(); // Loading Timer 0 settings boot_watchdog(); // Loading Watchdog settings while(1) { i++; if(i==code[compare]) { if (set ==0) { TCCR0 |=(1<<WGM01)|(1<<CS00); // Timer 1 on CTC Mode, MCU clockspeed compare++; i=0; set=1; if(compare ==6) compare=0; } else { TCCR0 = 0x00; // Timer 0 off PORTA = 0x00; compare++; i=0; set=0; if(compare ==6) compare=0; } } } return 0; } //---------------------------------------------------------------------- ---------------- ISR (SIG_OUTPUT_COMPARE0) //Interrupt Handling Routine /(automat. Aufruf vom Timer) { PORTA =~ PORTA; // invert PORTA } //delay_us(13)
Koenntest du nicht einfach ein Byte seriell über ein I/O Pin rausschieben? Gruß, Dirk
Naja, Ziel ist nicht nur einfach einen I/O Pin für 1 u 0 zu toggeln sondern gezielt Pakete a la http://www.mikrocontroller.net/attachment/89/irp-ojojo.jpg mit einer selbstdefinierten High & Low Länge zu generieren um einen eigen Codesequenz zu erstellen. Grüße Maddin
Hallo Dirk, vielen Dank für den Link, hab' ich mir angeschaut und ein Programm in ähnlichem Stile erstellt.Ich bekomme meinen generierten Code und meine Anfangs- und Endsignale, allerdings noch zusätzlich eine Totzeit die ich mir nicht erkären kann (siehe Bild blauer Abschnitt)....!? Woher kommt das bzw. wie kann ich dies unterdrücken/entfernen? Abgesehen davon habe ich eine generelle Frage. Gibt es nicht die Möglichkeit so eine Sequenz über Timer oder ähnliches ablaufen zu lassen, damit die Main für andere Aufgaben frei bleibt. Denn im Moment brauche ich ja einen ganzen Proz nur für's senden. Ich wollte eigentlich von einem Proz, dass Senden und Empfangen gleichzeitig steuern und die Bitkombi vergleichen. Vielen dank im Vorraus Grüße Maddin Anbei das Programm: ------------------------------------------ #include <inttypes.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #include <stdio.h> #include <avr/signal.h> #include <util/delay.h> #include <avr/interrupt.h> #include <avr/io.h> //---------------------------------------------------------------------- -------------------- // Variablen Declaration //---------------------------------------------------------------------- -------------------- #define pulses_amount (uint8_t)(20) //Enter here amount of pulses per high cycle #define cycle_ratio (uint8_t)(9) //Enter here Half dutycycle for Freq #define IR_PORT PORTA #define IR_PIN PA0 #define IR_ON IR_PORT |= (1<<IR_PIN) #define IR_OFF IR_PORT &= ~(1<<IR_PIN) //volatile unsigned char code [6] = {100000,65535,100000,65535,100000,655350}; //Array with 7 Values //volatile unsigned int compare = 0; //Counter for Array place uint8_t i=0,set=0; // integer value I with 32 bit declared uint16_t a=0,b=0,x=0,y=0,z=0; //---------------------------------------------------------------------- -------------------- // Prototypen Declaration //---------------------------------------------------------------------- -------------------- void boot_periphericals (); void boot_watchdog(); void set_high(); void set_low(); void initbit(); void endpeak(); void bit0(); void bit1(); void freq_toggle(); //---------------------------------------------------------------------- -------------------- // Main- Function //---------------------------------------------------------------------- -------------------- void main () { boot_periphericals(); boot_watchdog(); // Loading Watchdog settings while (1) { initbit(); bit1(); bit0(); bit0(); bit1(); bit1(); endpeak(); } } //---------------------------------------------------------------------- -------------------- // Subfunctions //---------------------------------------------------------------------- -------------------- void boot_periphericals () // I/O and basic settings { DDRA = 0x01; // PA0, selected as output PORTA = 0x00; // PA0, outputs on low (0) } void boot_watchdog() // Watchdog for reseting in case of global corruption { WDTCR |= (1<<WDE); // Enable Watchdog with Timeout after 14.0 ms (Datasheet page 56) } void initbit() { set_low(); set_low(); set_low(); set_high(); set_high(); set_high(); set_low(); set_low(); set_low(); } void endpeak() { IR_ON; for (b=0; b<1; b++) asm volatile("nop"); IR_OFF; for (b=0; b<1; b++) asm volatile("nop"); } void bit0() { set_low(); set_high(); } void bit1() { set_high(); set_low(); } void set_high() { for(a=0; a<pulses_amount; a++) { freq_toggle(); } } void set_low() { IR_OFF; for (x=0; x<30; x++) { for (y=0; y<18; y++) asm volatile("nop"); } } void freq_toggle () { IR_ON; for (b=0; b<cycle_ratio; b++) asm volatile("nop"); IR_OFF; for (b=0; b<cycle_ratio; b++) asm volatile("nop"); }
Hallo, ich habe mal die Bitfolge im main verlängert und dabei festgestllt, dass der MCU die hälfte meiner Bits gar nicht mehr bearbeitet und zusätzlich immer noch die Totzeit bringt. Bin echt am verzweifeln... hat da jemand ne Ahnung? Bitfolge in der Main Vorgabe : bit1(); bit0(); bit0(); bit1(); bit1(); bit0(); bit1(); bit0(); bit1();bit1() Grüße Maddin
Oh, hab's jetzt hinbekommen die ganze Codesequenz laufen zulassen, aber die Totzeit ist immer noch da.....hmmm?! Anbei ein Bild Im Code wurden die ganzen "volatile unsigned char" als "uint8_t" geschrieben und schon ging die gesamte Sequenz Maddin
Ich glaube der Watchdog schlaegt zu. Nimm mal zum testen den Watchdog raus. Dirk
Die Codesequenz bricht nach 11 Stellen (von 20 ) nun doch wieder ab... Hat jemand eine Idee....?? Mittlerweile ist der Sendecode in einem Array und wird im über die main schrittweise eingelesen und in Sendebits umgewandelt: volatile unsigned char code [19] = {0,1,1,1,0,1,1,0,0,0,0,1,0,0,0,1,0,0,0,0}; Vielen Dank im Vorraus
Ah yeah...vielen Dank für den Hinweise Dirk. Es war der Watchdog... Aber abweichend nochmal die Frage ob man das nicht auch anders machen kann als einen Proz nur mit dem Senden über die Main auszulasten. Denn dann müsste ich ja einen ATTini dafür abstellen und meinen ATmega mit dem Dekodieren des Empfangssignal "beauftragen". Gruss Maddin
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.