Założyłem ten temat, bo chciałbym (i prawdę mówiąc muszę) zrozumieć program znaleziony, nawet chyba u Was na forum, dekodujący sygnał rc5.
Historia jest typowa: "projekt, którego nie chcę, a który muszę."
Dzięki z góry za pomoc. Nie besztajcie mnie zbyt mocno.
Wspomniany kod:
Mam (w schemacie tzn) 4Mhz(atmega16a), w kodzie determinuje to wartość makra TIMER_0_CNT, dzięki któremu wypracowany będzie czas 111us, co który przepełniać się będzie 8-bitowy licznik.
I rozumiem to tak: przychodzi przerwanie z dekodera IR(tsop1736), wywoływana jest procedura obsł. przerwania w której na początku wyłączane są przerwania zewnętrzne, żeby móc dalej zdekodować sygnał. (to jeszcze, jeszcze rozumiem).
Pierwszy bit jest startowy, ma zawsze wartość "1"(czyli w połowie bitu zmiana 0->1) więc w pętli:
czekamy dopóki wartość na PD3 to "0" lub do 1221us(czyli mniej niż 0.75 bitu) i za pętlą mamy niby zdekodowany ten pierwszy bit startu.
Ta pętla, wdł. mnie czeka do 1554us, co nawet nie jest drugim bitem, natomiast z komentarza wynika, że ma to być środek połowy drugiego bitu:(
Dalej jest niby odczytywanych 13 bitów(2gi bit startu, toggle bit, adres, komenda), tak że:
rc5data = 1 jest przesuwane z każdym przebiegiem pętli (1 bo ten drugi bit startu chyba?) w którym sprawdzany jest stan PD3, niby w chwili T/4. Jeśli "1" to jest ustawiana jedynka w rc5data jeśli "0" to 0.
I nawet tutaj mam wątpliwość, bo jeśli w pierwszej połowie bitu jest "1" to będzie zmiana z 1->0, czyli "0".
Rozpieprzyło mi się to w głowie - pomóżcie.
Historia jest typowa: "projekt, którego nie chcę, a który muszę."
Dzięki z góry za pomoc. Nie besztajcie mnie zbyt mocno.
Wspomniany kod:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#define RC5BitHigh() (bit_is_set(PIND,PD3))
#define RC5BitLow() (bit_is_clear(PIND,PD3))
#define WAITFORTIMER() { while ( timerflag == 0); timerflag = 0; }
// CLK = 4MHz
#define TIMER_0_CNT 0xC9 // 111us = 1/( (CLK/8)/(0xFF-0xC9) )
#define RC5BITREF1 6
#define RC5BITREF2 11
#define RC5BITREF3 14
#define IR_int_enable GIFR|=(1<<INT1);GICR|=(1<<INT1)
#define IR_int_disable GICR&=~(1<<INT1)
volatile uint8_t timerflag;
volatile unsigned int rc5data;
void rc5_init()
{
DDRD &= ~(1<<PD3); // konfiguracja PD3 jako wejście
PORTD |= (1<<PD3); // enable internal pull-up resistors
MCUCR|=_BV(ISC11); // ext. int. activated by falling edge
MCUCR&=~_BV(ISC10);
GIFR = (1<<INTF1); // clear ext. int. flag
GICR|=_BV(INT1); // enable ext. int.
}
SIGNAL(SIG_OVERFLOW0)
{
timerflag = 1; // set global variable
TCNT0 = TIMER_0_CNT; // reset counter to get this interrupt again
}
SIGNAL(SIG_INTERRUPT1)
{
IR_int_disable; //wylaczenie przerwan zewnetrznych
sei();
unsigned char timer, i;
// init timer/Counter2
TCCR0 = 0x02; // use CLK/8 prescale
TCNT0 = TIMER_0_CNT; // set timer T/16 = 111us
TIMSK |= (1<<TOIE0); // enable TCNT0 overflow interrupt
TIMSK &=~(1<<TOIE2); // disable TCNT2 overflow interrupt
// measure startbit
timerflag = 0; timer = 0;
while ( RC5BitLow() && (timer < RC5BITREF2) ) {
WAITFORTIMER();
timer++;
}
if ( (timer > RC5BITREF1) && (timer < RC5BITREF2) ) {
// startbit ok, decode
// wait T/4: synchronize in the middle of first half of second bit
while ( timer < RC5BITREF3 ) {
WAITFORTIMER();
timer++;
}
// read the remaining bits
rc5data = 1;
for (i=0; i<13; i++) {
rc5data <<= 1;
if ( RC5BitHigh() ) {
rc5data |= 0x0001;
// wait max T/2 for H->L transition (middle of next bit)
timer = 0;
while ( RC5BitHigh() && (timer < 16) ) {
WAITFORTIMER();
timer++;
}
}else{
rc5data &= ~0x00001;
// wait max T/2 for L->H transition (middle of next bit)
timer = 0;
while ( RC5BitLow() && (timer < 16) ) {
WAITFORTIMER();
timer++;
}
}
if ( timer == 16 ) {
rc5data = 0x0000; // error, next bit not found
return;
}
// wait 3/4 T: await next bit
for ( timer=0; timer < 12 ; timer++) WAITFORTIMER();
}
}else {
rc5data = 0x0000; // error, invalid RC-5 code
}
TCCR0=0;
TIMSK &=~(1<<TOIE0); // disable TCNT0 overflow interrupt
TIMSK |= (1<<TOIE2); // enable TCNT2 overflow interrupt
IR_int_enable;
}
int main()
{
DDRD=0;;//Porty D jako wejścia
rc5_init();
sei();
while(1)
{
if(rc5data)
{
PORTB=0x00;
}
}
}
Mam (w schemacie tzn) 4Mhz(atmega16a), w kodzie determinuje to wartość makra TIMER_0_CNT, dzięki któremu wypracowany będzie czas 111us, co który przepełniać się będzie 8-bitowy licznik.
I rozumiem to tak: przychodzi przerwanie z dekodera IR(tsop1736), wywoływana jest procedura obsł. przerwania w której na początku wyłączane są przerwania zewnętrzne, żeby móc dalej zdekodować sygnał. (to jeszcze, jeszcze rozumiem).
Pierwszy bit jest startowy, ma zawsze wartość "1"(czyli w połowie bitu zmiana 0->1) więc w pętli:
while ( RC5BitLow() && (timer < RC5BITREF2) ) {
WAITFORTIMER();
timer++;
}
czekamy dopóki wartość na PD3 to "0" lub do 1221us(czyli mniej niż 0.75 bitu) i za pętlą mamy niby zdekodowany ten pierwszy bit startu.
// wait T/4: synchronize in the middle of first half of second bit
while ( timer < RC5BITREF3 ) {
WAITFORTIMER();
timer++;
}
Ta pętla, wdł. mnie czeka do 1554us, co nawet nie jest drugim bitem, natomiast z komentarza wynika, że ma to być środek połowy drugiego bitu:(
Dalej jest niby odczytywanych 13 bitów(2gi bit startu, toggle bit, adres, komenda), tak że:
rc5data = 1 jest przesuwane z każdym przebiegiem pętli (1 bo ten drugi bit startu chyba?) w którym sprawdzany jest stan PD3, niby w chwili T/4. Jeśli "1" to jest ustawiana jedynka w rc5data jeśli "0" to 0.
I nawet tutaj mam wątpliwość, bo jeśli w pierwszej połowie bitu jest "1" to będzie zmiana z 1->0, czyli "0".
Rozpieprzyło mi się to w głowie - pomóżcie.