-
        

Ergebnis 1 bis 5 von 5

Thema: 4 kanal fernsteuerung für tiny13

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    04.01.2008
    Beiträge
    41

    4 kanal fernsteuerung für tiny13

    Anzeige

    hallo zusammen,
    ich habe vor einiger Zeit den code für eine 4 Kanal Fernbedienung mit Tiny13 porgrammiert. Da ich das ganze erst in geraumer Zeit testen kann, wollte ich hier den code mal in die Runde werfen, in der Hoffnung das eventuelle Fehler aufgedeckt werden.
    Nun ein paar Daten zum selbstausgedachten code:
    Der 8 bit Timer (einziger timer im Tiny13) erzeugt die Trägerfrequenz von 38khz. An Pin PB2 ist eine IR Leuchtdiode über Vorwiderstand und Treiber angeschlossen.
    Als Taster werden normale 2 Schließer benutzt. Je ein Schließer eines Tasters hängt an PB0,PB3,PB4 und PB5. Der zweite Schließer jedes Tasters hängt zusammen mit den anderen an PB1 dem externen Interrupt, was den AVR aus dem Sleep modus aufwecken soll.
    Gesendet wird zuerst ein 3 Bit Header, dann ein 4 Bit Befehlsschlüssel. Alles wäre natürlich auch mit weniger Bits ausgekommen, aber so ist das Ganze meines Erachtens störsicherer. Der Zeitabstand zwischen jedem gesendeten Bit ist 2ms. Dazu wird die delay Funktion benutzt. Ob die Genauigkeit dazu ausreicht, weiß ich nicht. Nach jedem Bitblock wird 160ms gewartet.

    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/sleep.h>
    #define  F_CPU 1000000UL
    #include <util/delay.h>
    
    int main (void) {
    DDRB|=(1<<PB2);
    PORTB=0x3b;                     //Pullups an (außer PB2)
    TIMSK0 |= (1<<TOIE0);           //Timer Overflow Interrupt freischalten 
    ACSR = 0x80;					//Analog Comparator ausschalten
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    sei();
    while(1) {									//Hauptschleife,
    	do {         							//Interrupt pin gedrückt (low)
    											//header 101
    	 	 TCCR0B  = 0x1; 					//Timer starten
    	   	 _delay_ms(2);						//1
     	     TCCR0B  = 0; 						//Timer stoppen
        	 _delay_ms(2);						//0
             TCCR0B  = 0x1;						//Timer starten
             _delay_ms(2);						//1
    
    		if ((PINB & (1<<PINB0))==0) {	//code 1: 1010
    			_delay_ms(2);					//1
    			TCCR0B  = 0; 
    			_delay_ms(2);					//0
    	 		TCCR0B  = 0x1;
    	 		_delay_ms(2);					//1
    			TCCR0B  = 0;
    			_delay_ms(2);					//0
    		}
    		if ((PINB & (1<<PINB3))==0) {	//code 2: 1101
    			_delay_ms(4);					//11
    			TCCR0B  = 0; 
    			_delay_ms(2);					//0
    	 		TCCR0B  = 0x1;
    	 		_delay_ms(2);	 				//1
    		}
    		if ((PINB & (1<<PINB4))==0) {	//code 3: 0101
    			TCCR0B  = 0; 
    			_delay_ms(2);					//0
    	 		TCCR0B  = 0x1;
    	 		_delay_ms(2);					//1
    			TCCR0B  = 0; 
    			_delay_ms(2);					//0
    	 		TCCR0B  = 0x1;
    	 		_delay_ms(2);	 				//1
    
    		}
    		if ((PINB & (1<<PINB5))==0) {	//code 4: 1011
    			_delay_ms(2);					//1
    			TCCR0B  = 0; 
    			_delay_ms(2);					//0
    	 		TCCR0B  = 0x1;
    	 		_delay_ms(4);	 				//11
    
    		}
    		TCCR0B  = 0;
    		_delay_ms(160); 
    	} while((PINB & (1<<PINB1))==0);
    	 
        PORTB &= ~(1<<PB2);						//IR LED ausschalten
    	sleep_mode();                   		//in den Schlafmodus wechseln
     
    
    
    }
    }
    
    ISR (INT0_vect) {
    _delay_ms(50);								//Tasten entprellen
    }
    
    ISR (TIM0_OVF_vect ) {                      //Erzeugung der 38Khz Trägerfrequenz
    cli();
    PORTB ^= (1<<PB2);      					//PB2 toggeln
    TCNT0 = 0xe5;               				//Vorladen auf 229 -> 26 Schritte
    sei();
    }
    mfg Philip

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    25.11.2003
    Beiträge
    1.111
    Keine Ahnung, mit was Du progst, aber in meinem WinAVR sehen die ISR-Namen (TIM0_OVF_vect) etwas anders aus.
    Schön und portabel ist der Progstil nicht (PORTB=0x3b), aber das weißt Du wahrscheinlich auch.
    Auf die Schnelle kann ich Dir nur sagen, dass Du in der ISR die sei und cli nicht brauchst, weil der Controller das eh' macht.
    Für den Rest ist es zu spät...

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    04.01.2008
    Beiträge
    41
    Danke für die Antwort.
    Das mit dem 0x03 ist zwar unübersichtlich, aber stört mich nicht sonderlich.
    Das einzige was ich befürchte ist, dass sich irgendwo ein logischer Fehler eingeschlichen hat oder eine der If- Abfragen falsch ist.
    Ich benutze AVR Studio zum proggen. Der Code compiliert ohne Warnungen, also sollte auch der TIM0_OVF_vect passen. (steht ja auch so im Datenblatt vom Tiny13).

    Kann man den code noch effizienter gestalten bzw hat jemand eine Idee wie ich eine Funktion schreibe die die bits sendet, die ich per parameter übergebe: zb: void sende(0b1110) ?

    mfg

  4. #4
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.781
    Blog-Einträge
    8
    Hallo

    Einen RC5-Sender (IR-Fernbedienungen) mit dem tiny13 in Bascom haben wir hier entwickelt: Link. Anwendungen mit 4 Knöpfen finden sich gegen Ende des Threads. RC5 ist ein Quasistandart der sehr gut dokumentiert ist. Bei deiner "Insellösung" können etliche Probleme auftreten die man dem nacken Code auf den ersten Blick nicht ansieht.

    Kritisch scheint mir das Timeing per _msdelay zu sein. Wenn du schon mit 38kHz toggelst (die Umschaltfrequenz muss natürlich doppelt so hoch sein und kann im CTC-Mode des Timers viel einfacher erzeugt werden) könnest du diesen Takt auch als Basis deiner Bitlängen verwenden (und die Daten mit der 38kHz-ISR rausschieben). ( Datenblatt(1,7MB) S. 60ff. "Output Compare Unit")

    Läuft der tiny13 wirklich mit 1MHz-Takt?. Meine Tests mit den internen 9,6MHz liefen problemlos, du könntest dir den externen Takt sparen. Oder meinst du vielleicht den 1,2MHz-Defaulttakt der tiny13? ( Datenblatt(1,7MB) S. 22. "Default Clock Source")

    Gruß

    mic

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    04.01.2008
    Beiträge
    41
    Hallo,
    mit dem Takt meinte ich eigentlich den internen Takt es Tiny13. Ich dachte immer alle avrs laufen defaultmäßig auf 1Mhz.
    Die Umschaltfrequenz ist auch nicht doppelt... das werde ich aber ändern.
    Kritisch scheint mir das Timeing per _msdelay zu sein. Wenn du schon mit 38kHz toggelst (die Umschaltfrequenz muss natürlich doppelt so hoch sein und kann im CTC-Mode des Timers viel einfacher erzeugt werden) könnest du diesen Takt auch als Basis deiner Bitlängen verwenden (und die Daten mit der 38kHz-ISR rausschieben). ( Datenblatt(1,7MB) S. 60ff. "Output Compare Unit")
    Wie sieht so eine Lösung codemäßig aus? Ich bin noch recht unerfahren im Thema µC. Ich bräuchte da eine starthilfe (in c natürlich).

    mfg

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •