-
Hallo
Schön das es jetzt klappt. Da du jetzt einmal dabei bist, wäre es sehr nett, wenn du die Software noch ein wenig "verbessern" könntest.
Ich würde mir eine Funktion wünschen, in der Art etwa
void send_rc5( uint8_t commando, uint8_t befehl)
Auch könnt man die beiden Funktionen void SendBit1(void) & void SendBit0(void) etwas zusammen fassen, da ja doch fast dasselbe passiert, nur in umgekehrter Reihenfolge.
Dann hätte man eine gute RC5 Senden Funktion. Eine automatische Berechnung der Verweilzeiten bei unterschiedlichen Frequenzen wäre
auch eine feine Sache.
MFG
Dieter
-
hallo dino dieter, hier ist eine änderung,
setzen von bit0 und bit1 wurde zusammengefasst.
halbbit-routinen wurden geschaffen.
es kann der ganze code gesendet werden "send_code(toggle,addresse,commando)".
läuft auf dem avr16 8mhz 100%.
Code:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <string.h>
#include <stdint.h>
//89ms pause
void ms_89(void)
{
uint32_t zaehler;
for (zaehler=0; zaehler<118666; zaehler++)
asm volatile("nop");
}
void halbbit_high(void)
{
uint16_t i,zaehler;
//890us Impuls mit 36kHz senden
//Bei 28us Periodendauer ergibt das 32 Impulse
for(i=0; i<32; i++)
{
PORTB=1;
for (zaehler=0; zaehler<18; zaehler++)
asm volatile("nop");
PORTB=0;
for (zaehler=0; zaehler<18; zaehler++)
asm volatile("nop");
}
}
void halbbit_low(void)
{
uint16_t zaehler;
//890us Pause
for (zaehler=0; zaehler<1186; zaehler++)
asm volatile("nop");
}
//Eine 0 oder 1 senden
void Send_Bit(uint8_t code)
{
if (code==0)
{
halbbit_high();
halbbit_low();
}
else
{
halbbit_low();
halbbit_high();
}
}
void send_code(uint8_t toggle, uint8_t address, uint8_t command)
{
uint8_t mask,i;
Send_Bit(1); //Erstes Startbit=1
Send_Bit(1); //Zweites Startbit=1
//Togglebit
if(toggle==0)
{
Send_Bit(0);
}
else
{
Send_Bit(1);
}
//5 Bit Addresscode
mask=0x10; //Beginn bei MSB
for(i=0; i<5; i++)
{
if(address&mask) //Send 1
{
Send_Bit(1);
}
else //Send 0
{
Send_Bit(0);
}
mask>>=1; //Nächstes Bit
}
//6 Bit Kommandocode
mask=0x20; //Beginn bei MSB
for(i=0; i<6; i++)
{
if(command&mask) //Send 1
{
Send_Bit(1);
}
else //Send 0
{
Send_Bit(0);
}
mask>>=1; //Nächstes Bit
}
//Übertragung komplett
PORTB=0; //IR-LED abschalten
ms_89(); // warte 89ms
}
int main(void)
{
DDRB=1;
uint8_t command,i;
command=37;
for (i = 14; i < command; i++)
{
send_code(1,27,i); // toggle, addresse, commando
}
}
wer andere programmvorschläge für die erleichterung hat kann diese noch reinbringen.
-
hallo, habe oben das programm geändert mit halbbit-routinen.
mfg pebisoft
-
Hallo
Das sieht doch schon sehr gut aus. Hier noch ein paar Anregungen.
Code:
void halbbit_high(void)
{
uint16_t i,zaehler;
Sollte man ändern in uint8_t.
Was mir noch nicht so richtig gefällt, ist das direkte beschreiben der Port
in den Funktionen.
Code:
for(i=0; i<32; i++)
{
PORTB=1; //einaml hier
for (zaehler=0; zaehler<18; zaehler++)
asm volatile("nop");
PORTB=0; //und hier
for (zaehler=0; zaehler<18; zaehler++)
asm volatile("nop");
}
Du beschreibst den ganzen Port neu und nicht nur ein Bit. Zu zweiten
hast du bei einer Änderung der Port die freudige Aufgabe, den ganzen Code zu durchsuchen.
Ich würde oben ein paar #defines einbauen und dort die PIN / Port zuweisen.
In der Art etwa
Code:
#define IR_LED_PORT PORTB
#define IR_LED_PIN 0
#define IR_LED_DDR DDRB
#define IR_LED_ON IR_LED_PORT |= (1<<IR_LED_PIN)
#define IR_LED_OFF IR_LED_PORT &= ~(1<<IR_LED_PIN)
Und oben noch eine grobe Beschreibung, was gemacht wird und wie lange
die Funktion benötigt. Dann ist es fast optimal.
MFG
Dieter
-
hallo, wer diesen artikel von anfang an durchgelesen hat, weiss um was es geht. er will dann auch nur, das die ir-diode senden kann und fummelt das programm auf seine masstsäbe um. darum sollte man die beschreibungen fast weglassen, kostet nur energie. was ich für sehr wichtig fand, ist, das wir es geschafft haben zum ersten mal mit dem avr vernünftigen und fehlerfreien 14-bit-code zu senden ohne einen interrupt zu blockieren.
mfg pebisoft
-
hallo, zeitkritische routinen kann man auch mit
dem programm "AVRdelayloop.exe" ist freeware, berechenen lassen.
man gibt z.b. die mhz an und die zeit z.b. 0,000014 (14us).
dann wird ein kleines asm programm erstellt. dieses kann man
den mit "mfile" unter "Assembler source file(s)" eintragen
und schon hat man als unterprogramm eine routine.
das programm muss die endung "S" haben z.b. "zeit.S".
kann man dann in winavr mit :
extern void zeit14_us(void);
extern void zeit890_us(void);
extern void zeit89_ms(void);
bekanntmachen und mit "zeit89_ms();" z.b. aufrufen.
ein beispiel für die "rc5-send" mit dem programm "AVRdelay" :
Code:
.global zeit14_us
.global zeit890_us
.global zeit89_ms
zeit14_us:
ldi R18, 0x25
WGLOOP0:
dec R18
brne WGLOOP0
nop
ret
zeit890_us:
ldi R18, 0x0A
WGLOOP2:
ldi R19, 0xEC
WGLOOP1:
dec R19
brne WGLOOP1
dec R18
brne WGLOOP2
nop
nop
ret
zeit89_ms:
ldi R18, 0x12
WGLOOP3:
ldi R19, 0x40
WGLOOP4:
ldi R20, 0xCD
WGLOOP5:
dec R20
brne WGLOOP5
dec R19
brne WGLOOP4
dec R18
brne WGLOOP3
ldi R18, 0x03
WGLOOP6:
dec R18
brne WGLOOP6
nop
ret
.end
mfg pebisoft