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.