Ok, danke euch beiden für die Ausführlichen Beiträge.
aber langsem steige ich aus , hab da grad gar keine Ahnung, wie das realisiert wird.
Kann mir das beschriebene mal jemand in Form eines Bsacom Codes zeigen?
vllt. steig ich dann wieder durch.
Atmega48 PWM
-
-
Pesi:
Bei der Manchester-Codierung des RC5-Protokolls würde man dann statt nur mit einer Flanke eben mit dem Pin-Change-Interrupt (bzw. beidflankig) arbeiten und in der ISR dann jeweils auch den Pin-Zustand speichern. Dann könnte man analog zu vorher die Zeiten bestimmen, nur jetzt eben für Low- und High-Pulsweiten getrennt. Mit dieser Information liesse sich dann auch ein RC5 dekodieren.
Bei HW-PWM sind nur die beiden Modi Phase-Correct und Phase-and-Frequency-Correct (bei beiden zählt der Timer rauf und wieder runter) für LED-Dimm-Anwendungen geeignet, da der Fast-PWM-Modus (hier zählt der Timer hoch und macht nen Überlauf) bei Compare-Wert = Bottom-Wert (= 0) immer noch einen ganz kurzen Spike von 1 Timer-Taktzyklus Länge produziert, also z.Bsp. eine LED eben nicht ganz ausschalten würde.
In den beiden anderen Modi ist es nun aber so, dass der Timer-Overflow nur beim 'unteren Überlauf' stattfindet. Eine Auswertung von beiden Zähl-Umdrehungen (also bei BOTTOM und bei TOP) ist nur mit Timer1 und auch nur dann möglich, wenn für TOP nicht die drei vordefinierten Bereiche (8, 9 und 10 Bit) sondern entweder das Register ICR1 oder aber OCR1A gewählt werden. Dann wird der dem jeweiligen Register zugehörige Interrupt Flag gesetzt, sobald Timer1 den eingetragenen Wert dieses Registers (dann der TOP-Wert des Timers) erreicht. Somit kann man dann bei beiden Extremen einen Interrupt erfassen und damit auch für die korrekte Anzahl-Takte-Ermittlung berücksichtigen.Gruss
Neni -
Ha,
habe mich geirrt es sind 2441 Hz PWM !
Als erstes hier mal die Datenstruktur:
'address' enthält die Geräteadresse der FB und kann beim Extended NEC Protokoll 16 Bit enthalten.'command' ist ja klar
'nrepeat' Zählt die Anzahl der Wiederholungen
'valid' ist 1 wenn die Daten korrekt sind 0, wenn ein Fehler auftrat.
Hier wird die IR/PWM routine initialisiert:
Code
Alles anzeigenvoid nec_ir_init() { // IR Timebase - TIMER1 // 10 BIT FAST - PWM // Clock Divided by 8 // @20MHz -> 20.000.000/1024/8 = 2441 Hz PWM // 0,0004096 seconds interval TCCR1A = (1 << WGM11) | (1 << WGM10); TCCR1B = (0 << WGM13) | (1 << WGM12) | (0 << CS12) | (1 << CS11) | (0 <<CS10); TCCR1A |= (1 << COM1A1) | (0 << COM1A0) | (1 < COM1B1) | (0 << COM1B0); DDRD |= (1 << PD4) | (1 << PD5); // OC1A,OC1B Output OCR1A = 0; OCR1B = 0; TIMSK1 = (1 << TOIE1); // Timer 1 overflow interrupt gesetzt // IR Remote Control: PC7/PCINT23 Interrupt // PCICR - Pin Change Interrupt Control Register PCICR = ( 1 << PCIE2 ); // PCINT23:16 enable PCMSK2 = ( 1 << PCINT23 ); // PCMSK2 - Pin Change Mask Register 2 // Enable IR input DDRC &= ~(1 << DDC7); PORTC |= 1 << PC7; PINC |= 1 << PC7; }
Timer overflow wird wie folgt behandelt, es werden in g_nTicks die Anzahl der 0.5ms gezählt, solange die < 255 sind ansonsten wurde kein korrekte Übertragung empfangen:
Code
Alles anzeigenvolatile uint8_t g_nTicks = 255; ISR(TIMER1_OVF_vect) { // IR TIME BASE uint8_t n = g_nTicks; if( n < 255 ) n++; else g_ir.valid = 0; g_nTicks = n; }
IR PIN Change Interrupt:
Code
Alles anzeigen#define IR_BAD_POS 32 volatile uint8_t g_npos = IR_BAD_POS; volatile uint8_t g_bRepeat = 0; volatile uint8_t g_irData[ 4 ]; volatile IR_DATA g_ir; ISR(PCINT2_vect) { if( PINC & (1 << PC7) ) { // --> LOW return; } // --> HI uint8_t n = g_nTicks; uint8_t npos = g_npos; uint8_t bit = 3; g_nTicks = 0; /**/ if( (n >= 31) && (n <= 34) ) // IR COMMAD START { npos = 0; g_bRepeat = 0; } else if( (n >= 26) && (n <= 29) ) // IR COMMAND REPEAT { if( g_ir.valid ) { if( g_bRepeat ) { g_event |= EVENT_IR_CMD; } g_bRepeat = 1; uint8_t n = g_ir.nrepeat; if( n < 255 ) n++; g_ir.nrepeat = n; } } else if( (n >= 5 ) && ( n <= 7) ) // logical '1' { bit = 0x80; } else if( n < 5 ) // logical '0' { bit = 0x00; } else { npos = IR_BAD_POS; } // // Check for valid bit // if( bit != 3 ) { if( npos < IR_BAD_POS ) { uint8_t* pir = (uint8_t*) g_irData + (npos >> 3); *pir = (*pir >> 1) | bit; if( ++npos == IR_BAD_POS ) { uint8_t lo = g_irData[0]; uint8_t hi = g_irData[1]; if( lo == (uint8_t) ~hi) g_ir.address = (uint8_t) lo; else g_ir.address = (hi << 8) | lo; lo = g_irData[2]; hi = g_irData[3]; if( lo == (uint8_t) ~hi ) { g_ir.command = lo; g_ir.valid = 1; g_ir.nrepeat = 0; g_event |= EVENT_IR_CMD; } } } } g_npos = npos; }
Ist zwar nicht das RC5 Protokoll und man könnte noch die Verbesserung von synvox einbauen, aber vielleicht eine hilfreiche Anregung .
Folgende Übersichten sind übrigens auch sehr Hilfreich und übersichtlich für PWM
lg. Sol
-
Hi,
was mir noch als Idee einfällt wäre es vielleicht einfach eine kleine Matrix zu bauen.
Dann werden nur 3 PWM Kanäle benötigt.
Ich hoffe das kann man so realisieren wie ich mir das denke Wenn nicht muss hier wieder einer dazwischengehen, habe mich ja schon mit RC5 getäuscht ...
Grüße Jakob
-
Nee, Matrix geht nicht. Die Module sind zum einen Örtlich weit voneinander getrennt und sollen unterschiedliche Sachen machen.