Datenübertragung über die Infrarotschnittstelle
(EN google-translate)
(PL google-translate)
Als Testfall werden zyklisch die Großbuchstaben A bis Z gesendet:
//Bei diesem Testprogramm
//wird auf OC1A (PD5, Pin 19) ein Rechtecksignal von 32kHz gegeben,
//um eine LD274-3 IR-Diode daran zu betreiben.
//TXD (PD1, Pin 15) sendet Zahlen, die von 0 auf 255 ansteigen und dann von 255 auf 0 abfallen.
//Die IR-Diode ist über einen Vorwiderstand von 220Ohm wischen PD7 und PD1 angeschlossen.
//
//Achtung: Der TXD-Ausgang des Mikrocontrollers muss hier vom Programmierer abgekoppelt werden.
//
//Definition von Taktfrequenz und Bausrate als Konstanten
#define TAKTFREQUENZ 1000000
//#define BAUDRATE 38400
#define BAUDRATE 2400
#include <avr/io.h>
int main(void)
{
unsigned char zahl = 'A';
int richtung = 1;
long pause;
DDRD |= 0b00100000; //PD5 als Ausgang schalten, PD1 in Ruhe lassen.
//serielle Schnittstelle aktivieren:
//Merken des in UBRR zu speichernden Wertes.
unsigned int baudregister = TAKTFREQUENZ/8/BAUDRATE-1; //1MHz: 1000000/8/2400 - 1 = 51,08 (o.k., kleiner Fehler)
//setzen der Baudrate
UBRRH = (unsigned char) (baudregister>>8); //Setzen des HIGH-Bytes des Baudraten-Registers
UBRRL = (unsigned char) baudregister; //Setzen des LOW -Bytes des Baudraten-Registers
//Einschalten des Senders und des Empfängers
//UCSRB = (1<<TXEN) | (1<<RXEN);
//Nur Einschalten des Senders
UCSRB = (1<<TXEN);
//Setzen des Nachrichtenformats: 8 Datenbits, 1 Stopbits
UCSRC = (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);
UCSRA = (1<<U2X);
//N CS12 CS11 CS10
//1 0 0 1
//8 0 1 0
//64 0 1 1
//256 1 0 0
//1024 1 0 1
//fclk = 2457600 (Quarzfrequenz)
//Datenblatt S. 107:
//PWM-Modus Nr. 10:
//TOP = ICR1
//16 Bit
//Phasenkorrekt
//WGM13..10: 1010
//fpwm = fclk / (2*N*TOP)
//29970,73 = 2457600 / (2*1*41)
//1MHz
//30000 = 1000000 / (2*1*TOP)
//TOP = 1000000/(2*1*30000) = 16,6666
//29411,764705882 = 1000000 / (2*1*17)
// ICR1 = 41;
ICR1 = 17; //für 1MHz
TCCR1A = (1<<COM1A1) | (0<<COM1A0) | (1<<COM1B1) | (0<<COM1B0)
| (0<<FOC1A) | (0<<FOC1B) | (1<<WGM11) | (0<<WGM10);
TCCR1B = (0<<ICNC1) | (0<<ICES1) | (1<<WGM13) | (0<<WGM12)
| (0<<CS12) | (0<<CS11) | (1<<CS10);
OCR1A = 8; //PWM-Breite auf 50% setzen.
// OCR1A = 4; //PWM-Breite auf 10% setzen.
// OCR1A = 1; //PWM-Breite auf 2,5% setzen.
while(1)
{
while( !(UCSRA & (1<<UDRE)) ); //Warten bis der Uebertragungspuffer leer ist
UDR = zahl; //Daten in den Puffer schreiben und übertragen
zahl+=richtung;
if(zahl=='A' || zahl=='Z')
{
richtung = -richtung;
}
for(pause=0;pause<10000;pause++)
DDRB = 0;
}
}
Code 0-1: Quelltext 02a_daten_seriell_sender.
Auf der Empfängerseite werden die empfangenen Buchstaben als PWM-Werte für das Dimmen der blauen LED benutzt:
//PD0 wird als Eingang geschaltet.
//Dies entspricht in Zweitfunktion RXD.
//Später sollen hier die seriellen Daten über
//Infrarot empfangen werden.
#include <avr/io.h>
//Definition von Taktfrequenz und Bausrate als Konstanten
#define TAKTFREQUENZ 1000000
#define BAUDRATE 2400
int main(void)
{
unsigned char akku = 0;
long pause = 0;
//Kontroll-LED an PD7 anschließen.
//Hier wird über OC2 eine Helligkeitseinstellung je nach
//empfangenen Daten realisiert.
//s.u.
//serielle Schnittstelle aktivieren:
//Merken des in UBRR zu speichernden Wertes.
unsigned int baudregister = TAKTFREQUENZ/8/BAUDRATE-1;
//setzen der Baudrate
UBRRH = (unsigned char) (baudregister>>8); //Setzen des HIGH-Bytes des Baudraten-Registers
UBRRL = (unsigned char) baudregister; //Setzen des LOW -Bytes des Baudraten-Registers
//Einschalten des Senders und des Empfängers
//UCSRB = (1<<TXEN) | (1<<RXEN);
//Nur Einschalten des Empfängers
UCSRB = (1<<RXEN);
//Setzen des Nachrichtenformats: 8 Datenbits, 1 Stopbits
UCSRC = (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);
UCSRA = (1<<U2X);
//Das PWM-Signal von Timer2 geht über Pin 21 (PD7, OC2) auf blau2
//und wird hier auch für das Dimmen konfiguriert:
TCCR2 = (0<<FOC2) | (1<<WGM20) | (1<<COM21) | (0<<COM20) | (0<<WGM21) | (0<<CS22) | (0<<CS21) | (1<<CS20);
OCR2 = 0; //Pulsbreite 0..255, 255==maximale Helligkeit, 0==dunkel.
//hier ist es o.k., wenn PC1 auf 0 gesetzt ist.
//blau2: Pin21,23
DDRC |= 0b00000010; //PC1
DDRD |= 0b10000000; //PD7
while(1)
{
while( !(UCSRA & (1<<RXC)) ); //Warten bis der Uebertragungspuffer ein Zeichen empfangen hat
akku = UDR; //Zeichen aus dem Puffer holen
OCR2 = (akku-65)*9;
}
}
Code 0-2: Quelltext 02b_daten_seriell_empfaenger.