Hi Allz,
da ich momentan wieder mehr Zeit habe mich den µC zu widmen versuche ich
mein lange rausgeschobenes IR-Projekt fertig zu bekommen.
Ich habe genannten Code aus der Codesammlung genommen und entsprechend
angepasst. Rausgekommen ist ein IR-Einschalter für PC's. Man kann eine
Taste in einem 2313 programmieren, die im eeprom abgespeichert wird,
welche bei Knopfdruck dann den PC einschaltet. So weit so gut.
Nun hab ich zwei Probleme:
1.) Von der RC5.C Routine hab ich relativ wenig bis nichts verstanden.
2.) Ich möchte es universeller machen so daß auch verschiendene IR-Codes
benutzt werden können.
Generell verstehe ich nicht so recht wie die empfangen Codes überhaupt
in den µC "kommen". Definiert ist:
1
#define xRC5_IN PIND
2
#define xRC5 PD2 // IR input low active
Mit dem ersten define wird festgelegt das xRC5_IN die Eingangspins des
Port D "anspricht". Ist dadurch automatisch festgelegt das alle Pins
dieses Ports als Eingänge arbeiten?
Zum anderen ist xRC5 der Datenport an dem die IR-Diode dranhängt. Nur
hier kommen ja wirklich Daten in den µC, sprich hier kommt das
demodulierte Signal des IR-Empfänger als Rechteck Impuls an, oder?
Das war's mal zum Einstieg, sonst wird das ein recht langer Monolog und
keiner liest das ;).
Hoffe ich frage nicht zu viel Grundsätzliches, aber ich hab wirklich
viel gesucht und nicht wirklich eine Antwort auf meine Fragen bekommen.
Gruß und good Night, Markus
> Ist dadurch automatisch festgelegt das alle Pins dieses Ports als Eingänge> arbeiten?
Mit einem #define wird nur eine Textersetzung definiert. Das hat aber
auch gar nichts mit irgendwelchen Einstellungen zu tun. Wenn da etwas
wie
1
#define xRC5_IN PIND
steht, bedeutet das nur, dass an jeder Stelle, an der der Ausdruck
"xRC5_IN" im Programmcode auftaucht, dieser durch "PIND" ersetzt wird
(wobei "PIND" wiederum in der Headerdatei als
Special-Function-I/O-Register definiert ist und durch seine Adresse im
I/O-Space ersetzt wird...). Den Port als Eingang konfigurieren geht über
die Register DDRD und PORTD.
johnny.m wrote:
> Den Port als Eingang konfigurieren geht über> die Register DDRD und PORTD.
Hi johnny.m,
diese grundlegenden Sachen wie man Ports als Aus- bzw. Eingang
konfiguriert sind mir schon klar. Nur in diesem Beispiel wird der PortD
eben nicht so konfiguriert! Das Codebeispiel ist hier zu finden:
Beitrag "Fernbedien RC5 Empfänger".
Das funktioniert wie gesagt perfekt. Der PortB wird auch konfiguriert da
im Beispiel LED's angesteuert werden. Aber der Eingang an PortD wird
nirgends konfiguriert?!?
Wieso geht das dann?
Markus
> Nur in diesem Beispiel wird der PortD eben nicht so konfiguriert!
Er wird gar nicht explizit konfiguriert, wenn ich mich nicht verguckt
habe. Also sind die Register DDRD und PORTD mit den default-Reset-Werten
"0x00" belegt. Das bedeutet Port D ist als Eingang ohne Pull-Ups
konfiguriert.
johnny.m wrote:
>> Nur in diesem Beispiel wird der PortD eben nicht so konfiguriert!> Er wird gar nicht explizit konfiguriert, wenn ich mich nicht verguckt> habe. Also sind die Register DDRD und PORTD mit den default-Reset-Werten> "0x00" belegt. Das bedeutet Port D ist als Eingang ohne Pull-Ups> konfiguriert.
Sehr interessant! Das wußte ich bisher nicht, ist aber im Nachhinein
logisch (wie meistens).
Danke!
Markus
Hallo miteinander. Hat vielleicht jemand ein Programm zum Senden per RC5
geschrieben? Oder gar eine Platine? Ich hab leider noch (fast) nichts
dazu gefunden.
Mit FastAvr-Basic.
Ich benutze die AdressBit und die Command-Bit zusammen, um mindestens 1
Byte zu übertragen.
$Device= m16
$Stack = 32
$Clock = 8
$Timer1=Timer, Prescale=1, CompareA=Toggle, Clear
Dim ToggleBit As Bit
Dim Adr As Byte, Command As Byte
Dim wert As Byte, wert1 As Byte , wert2 As Byte, zaehler As Byte
Declare Sub RC5out(adr As Byte, command As Byte)
Declare Sub BitLow()
Declare Sub BitHigh()
Const Delay=89
Set DDRD.5
Compare1A=101
Start Timer1
Adr=0
Do
For zaehler= 60 To 178
wert= zaehler
wert1=Shift(Right,6, wert)
wert2=&b00111111 & wert
RC5out(wert1,wert2)
WaitMs 255
Next
Loop
Sub RC5out(adr As Byte, command As Byte)
Local i As Byte
BitHigh()
BitHigh()
If ToggleBit Then
BitHigh()
Else
BitLow()
End If
For i=0 To 4
If adr.4 Then
BitHigh()
Else
BitLow()
End If
Shift(Left,1,adr)
Next
For i=0 To 5
If command.5 Then
BitHigh()
Else
BitLow()
End If
Shift(Left,1,command)
Next
$Timer1=Timer, CompareA=Reset
End Sub
Sub BitLow()
$Timer1=Timer, CompareA=Toggle
WaitUs Delay
$Timer1=Timer, CompareA=Reset
WaitUs Delay
End Sub
Sub BitHigh()
WaitUs Delay
$Timer1=Timer, CompareA=Toggle
WaitUs Delay
$Timer1=Timer, CompareA=Reset
End Sub
Hi Leutz,
möchte mal den ersten Block aus der genannten Routine durchkauen. In der
Interruptroutine wird zuerst folgendes geprüft:
1
if(++rc5_time>PULSE_MAX){// count pulse time
2
if(!(tmp&0x4000)&&tmp&0x2000)// only if 14 bits received
3
rc5_data=tmp;
4
tmp=0;
5
}
Der erste if-Ausdruck (++rc5_time > PULSE_MAX) prüft bei jedem Durchlauf
ob eben diese Bedingung erfüllt ist, zählt dabei aber jedesmal rc5_time
hoch.
1. Richtig?
Wenn nun das 15. Bit (0x4000) nicht gesetzt ist und das 14. Bit schon
dann wurden insgesamt 14 Bits empfangen und der rc5_data Variablen
übergeben.
2. Richtig?
Markus
Da niemand widerspricht geh ich mal davon aus dasalles richtig ist :).
Jetzt kommt's aber dicke:
1
if((rc5_bit^xRC5_IN)&1<<xRC5){// change detect
2
rc5_bit=~rc5_bit;// 0x00 -> 0xFF -> 0x00
3
4
if(rc5_time<PULSE_MIN)// to short
5
tmp=0;
6
7
if(!tmp||rc5_time>PULSE_1_2){// start or long pulse time
8
if(!(tmp&0x4000))// not to many bits
9
tmp<<=1;// shift
10
if(!(rc5_bit&1<<xRC5))// inverted bit
11
tmp|=1;// insert new bit
12
rc5_time=0;// count next pulse time
13
}
14
}
Hier versteh ich schon mal die erste Zeile nicht. rc5_bit ist ja
deklariert als "uchar rc5_bit". xRC5_IN stellt den gesamt Port D (also
8bit) dar. Dieser wird bitweise XOR verknüpft mit eben rc5_bit. Und was
hats dann mit dem "& 1<<xRC5" auf sich?
Bitte mal um Erklärung des Ausdrucks, steht irgendwie auf der Leitung...
Markus
Es soll der Zustand eines Portpins (xRC5) abgefragt werden. Das ganze
ist für das Programm aber nur dann von Interesse, wenn sich der Zustand
des Pins im Vergleich zum vorhergehenden geändert hat. Daher die
(bitweise) EXOR-Verknüpfung, die nur dann eine "1" ergibt, wenn die
Ausgangswerte unterschiedlich sind. Da bei der EXOR-Verknüpfung der
komplette Port eingelesen wird, jedoch für die Auswertung nur das eine
Bit xRC5 von Bedeutung ist, wird dieses mit einer bitweisen
UND-Verknüpfung maskiert, so dass alle anderen Bits als "0" gelesen
werden. Der Ausdruck in der Klammer der if-Anweisung ist also nur dann
wahr, wenn das Bit xRC5 in xRC5_in (also der Pin 2 in PIND) sich
gegenüber dem in rc5_bit gesicherten vorherigen Zustand geändert hat,
wobei durch das EXOR (und das anschließende toggeln von rc5_bit) die
Richtung der Änderung (Low->High oder High->Low) keine Rolle spielt.
ich habe den code umgeschrieben um die ausgabe auf dem lcd zu machen:
i ist vom typ uint
1
lcd_putc((i>>11&1)+'0');
2
lcd_putc(' ');
3
itoa(i>>6&0x1F,s,10);// Device address
4
lcd_puts(s);
5
lcd_putc(' ');
6
itoa((i&0x3F)|(~i>>7&0x40),s,10);// Key Code
7
lcd_puts(s);
8
lcd_puts(" ");
9
lcd_gotoxy(0,1);
kann mir mal bitte jemand die Selektion der einzelnen Device bzw. Key
Code Adressen mittels der oben beschriebenen "Masken" erklären
angenommen i ist 1
dann ist doch z.b: i & 0x3F
00000001
&00111111
---------
00000001
also wie das mit dem UND bzw. ODER funktioniert versteh ich glaub ich,
aber das mit dem "schieben" ist mir noch unklar
@Peter:
Sieh dir das mal durch. Ich denke das ist ein Fehler drinn
@Lutz:
Weil da eine etwas 'trickreiche' Code Sequenz drinnen ist,
mach ich dir das mal.
>
1
>lcd_putc((i>>11&1)+'0');
2
>lcd_putc(' ');
3
>itoa(i>>6&0x1F,s,10);// Device address
4
>lcd_puts(s);
5
>lcd_putc(' ');
6
>itoa((i&0x3F)|(~i>>7&0x40),s,10);// Key Code
7
>lcd_puts(s);
8
>lcd_puts(" ");
9
>lcd_gotoxy(0,1);
10
>
Das Format ist
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 1 |-C6| T | A4| A3| A2| A1| A0| C5| C4| C3| C2| C1| C0|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
C0 bis C5 PLUS -C6 ergeben das Kommando
A0 bis A4 ergeben die Adresse
(Ich borg mir von Sprut die Notation aus, dass ein - vor einem
Bit ein invertiertes Bit bedeutet)
> lcd_putc(( i >> 11 & 1) + '0');
Das verschiebt die Bitsequenz um 11 Stellen nach rechts
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |-C6| T |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
danach wird mit einer 1 geundet (und somit werden alle Bits
ausser dem Bit 0b00000000000001 zu 0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | T |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
anschliessend wird noch '0' addiert. War T eine binäre 0,
dann kommt bei der Addition '0' heraus, war T 1 dann ergibt
die Addition '1'. -> Ausgabe aufs Display
> itoa( i >> 6 & 0x1F, s, 10); // Device address
Wieder: Die original empfangene Bitsequenz um 6 Stellen nach
rechts verschieben
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 1 |-C6| T | A4| A3| A2| A1| A0|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
danach mit 0x1F verunden
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 1 |-C6| T | A4| A3| A2| A1| A0|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
& 0 0 0 0 0 0 0 0 0 1 1 1 1 1
---------------------------------------------------------
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | A4| A3| A2| A1| A0|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
und die Adresse steht fertig da zur Ausgabe (vorher die
Binärzahl noch mittels itoa in einen String verwandeln)
> itoa((i & 0x3F) | (~i >> 7 & 0x40), s, 10); // Key Code
Jetzt kommt der 'tricky' Teil
Fang wieder beim Original an:
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 1 |-C6| T | A4| A3| A2| A1| A0| C5| C4| C3| C2| C1| C0|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
mit 0x3F verunden
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 1 |-C6| T | A4| A3| A2| A1| A0| C5| C4| C3| C2| C1| C0|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
& 0 0 0 0 0 0 0 0 1 1 1 1 1 1
----------------------------------------------------------
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | C5| C4| C3| C2| C1| C0|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Dieses Ergebnis wird mit 'etwas' verodert. Was ist dieses
'etwas'
(~i >> 7 & 0x40),
Also, wieder i hernehmen
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 1 |-C6| T | A4| A3| A2| A1| A0| C5| C4| C3| C2| C1| C0|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
und mal alle Bits umdrehen (für die Tilde ~)
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 0 | C6|-T |-A4|-A3|-A2|-A1|-A0|-C5|-C4|-C3|-C2|-C1|-C0|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
danach um 7 Stellen nach rechts schieben:
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | C6|-T |-A4|-A3|-A2|-A1|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
jetzt mit 0x40 verunden
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | C6|-T |-A4|-A3|-A2|-A1|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
& 0 0 0 0 0 0 0 1 0 0 0 0 0 0
----------------------------------------------------------
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Damit ist der rechte Ausdruck vom | berechnet und die beiden
Teilausdrücke können zusammenge-oder-t werden
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | C5| C4| C3| C2| C1| C0|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
-----------------------------------------------------------
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | C5| C4| C3| C2| C1| C0|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Tja. Und jetzt sieht man, das C6 um 1 Stelle zu weit nach
rechts geschoben wurde (wenn ich mich nicht vertan habe).
Eigentlich sollte C6 an Position 0x40 zu liegen kommen.
Dazu muss die Bitsequenz aber nur um 6 Stellen nach
rechts verschoben werden.
Peter: Kannst du das nochmal kontrollieren?
Hab ich einen Fehler gemacht oder hast du dich verhaut?
Ich denke deas müsste
(~i >> 6 & 0x40),
lauten.
Damit auf der Ausgabe auch eine '0' oder eine '1' erscheint.
Damit das LCD eine 0 hinmalt, muss man ihm das Zeichen '0'
schicken. Du hast aber nur eine Ziffer. Also muss man diese
Ziffer in das korrespondierende Zeichen verwandeln (ASCII
Code studieren).