Hallo,
habe deine Einwände zum Teil beseitig und Kommentare im Code ergänzt.
Die Werte für TCNT0 errechnen sich folgendermaßen:
1/(16000000/256) = 1.6exp-5
Das erste Intervall soll bis zur Mitte des low-Pegels vom Togglebit dauern, also 1.778ms/2->55.5 Timersteps
Danach sollen die Intervalle jeweils 1.778ms dauern, so dass immer die das 2. Halbbit erfasst wird.
Selbst wenn meine Timings nicht ganz stimmen würden, dürfte rc5.code doch nicht immer 0 sein??
Ich meine doch, ich habe hier den OpenCollector berücksichtigt, und wenn nicht, wäre das Signal halt invertiert.
Code:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <math.h>
struct rc5_parts
{
volatile char s_bit;
volatile int8_t addresse;
volatile int8_t code;
volatile char rdy;
} rc5;
char mid;
volatile uint8_t bitnummer = 0;
void init_rc5()
{
MCUCR |= (1<<ISC11) | (1<<ISC10);
GICR |= (1<<INT1);
TCCR0 |= (1<<CS02);
}
//****************************************************USART******************************
void init_usart(void)
{
UBRRL |= 0b01100111;
UCSRB = (1<<TXEN) | (1<<RXEN);
UCSRC = (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0);
}
void send_char(unsigned char s)
{
while (!(UCSRA & (1<<UDRE)));
UDR = s;
}
void send_string(char *s)
{
while(*s != '\0')
{
send_char(*s);
s++;
}
}
//**********************************************************USART-ENDE********************
SIGNAL(SIG_OVERFLOW0)
{
bitnummer++;
TCNT0 = 145; //Timer soll nach 1.778ms Overflow haben
if(bitnummer == 12)
{
TIMSK &= ~(1<<TOIE0); //Wenn die 11 Bits davor erfasst wurden, TimerIRQ deaktivieren
rc5.rdy = 1;
rc5.s_bit = 0;
bitnummer = 13;
}
if(bitnummer<6) //Wenn i<6, werden die ausgelesenen Bits zu Addresse hinzugefügr
{
if((PORTD & (1<<3)) != 0)
{
rc5.addresse |= (1<<(-1)*(bitnummer-6));
}
else
{
rc5.addresse &= ~(1<<(-1)*(bitnummer-6));
}
}
if((bitnummer>=6 && bitnummer<=11)) //6 - 11 werden zu rc5.code hinzugefügt
{
if((PORTD & (1<<3)) != 0)
{
rc5.code |= (1<<(-1)*(bitnummer-7));
}
else
{
rc5.code &= ~(1<<(-1)*(bitnummer-7));
}
}
}
SIGNAL(SIG_INTERRUPT1)
{
if(rc5.s_bit<4)
{
rc5.s_bit++;
}
if(rc5.s_bit == 4)
{
TIMSK |= (1<<TOIE0); // Timer0 Interrupts enablen
TCNT0 = 200; //Timer so vorladen, dass er zur Mitte des 2. Halbbits den ersten Timeroverflow hat
GICR &= ~(1<<INT1); //Int1 disablen
}
}
int main(void)
{
init_usart();
init_rc5();
char i = 1;
sei();
char result[10];
char hello[15] = "Hallo Martin";
send_string(hello);
for(;;)
{
if(rc5.rdy == 1)
{
itoa(rc5.code,result,10);
char hello2[15] = "RC5-Code: ";
send_string(hello2);
send_string(result);
rc5.rdy = 0;
GICR |= (1<<INT1); // ext. Interrupt wieder aktivieren
}
}
}
Lesezeichen