Witam. Na zlecenie piszę pewien projekt, którego częścią jest dekodowanie sygnału z pilota Rc5. Z początku zrobiłem to na mojej eksperymentalnej płytce z układem
ATmega32, gdzie dolutowałem czujnik w powietrzu. Ustawiłem procka na wewnętrzny rezonator 4 MHz, gdyż taki udało mi się znaleźć na internecie działający przykład dekodowania Rc5, no i ruszyło, i działało prawidłowo. Rozbudowałem projekt o wszystko inne co zlecił mi zleceniodawca, aż w końcu wykonałem końcową płytkę ze wszystkimi niezbędnymi bajerami na ATmega8, którego taktowanie ustawiłem tak samo jak ATmegę32 - na 4 MHz Int RC Osc. Program skompilował się bez żadnych przeróbek - co najwyżej zmiana pinu na którym był podłączony czujnik IR, reszta bez zmian. Efekt - na Atmega8 nie działa za nic w świecie. Wypuściłem na terminal UART aby cokolwiek obserwować co dzieje się w procku ale nic. po prostu nie dekoduje. Pytanie : Czy jest jakaś różnica między tymi prockami o której nie wiem, która może mieć wpływ na niepoprawne/brak dekodowania Rc5, mimo tej samej częstotliwości oscylatora? Może kwestia jakichś innych fuse-bitów ? A może wewnętrzny oscylator ma pewną odchyłkę i z timerów nie wychodzi właściwa częstotliwość do dekodowania.
Dla jasności załączam kod
Plik uart.h pominę gdyż transmisja szeregowa działa prawidłowo.
test.c :
rc5.h :
ATmega32, gdzie dolutowałem czujnik w powietrzu. Ustawiłem procka na wewnętrzny rezonator 4 MHz, gdyż taki udało mi się znaleźć na internecie działający przykład dekodowania Rc5, no i ruszyło, i działało prawidłowo. Rozbudowałem projekt o wszystko inne co zlecił mi zleceniodawca, aż w końcu wykonałem końcową płytkę ze wszystkimi niezbędnymi bajerami na ATmega8, którego taktowanie ustawiłem tak samo jak ATmegę32 - na 4 MHz Int RC Osc. Program skompilował się bez żadnych przeróbek - co najwyżej zmiana pinu na którym był podłączony czujnik IR, reszta bez zmian. Efekt - na Atmega8 nie działa za nic w świecie. Wypuściłem na terminal UART aby cokolwiek obserwować co dzieje się w procku ale nic. po prostu nie dekoduje. Pytanie : Czy jest jakaś różnica między tymi prockami o której nie wiem, która może mieć wpływ na niepoprawne/brak dekodowania Rc5, mimo tej samej częstotliwości oscylatora? Może kwestia jakichś innych fuse-bitów ? A może wewnętrzny oscylator ma pewną odchyłkę i z timerów nie wychodzi właściwa częstotliwość do dekodowania.
Dla jasności załączam kod
Plik uart.h pominę gdyż transmisja szeregowa działa prawidłowo.
test.c :
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include "uart.h"
#include "rc5.h"
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#define cbi(port, bit) (port) &= ~(1 << (bit))
#define tbi(port,bit) port ^= _BV(bit);
unsigned int rc5data;
uint8_t kod,buffer[14];
int main(void)
{
uart_init(UART_CONST);
uart_puts("DZIENDOBRY\n");
while(1)
{
rc5data = rc5decode();
if ( rc5data & 0x2000 ) {
kod = (rc5data & 0x003f); // output command bits of RC5 command
uart_puts(itoa(kod,10,buffer));
}
}}
rc5.h :
#define RC5BitHigh() (bit_is_set(PIND,PD2))
#define RC5BitLow() (bit_is_clear(PIND,PD2))
#define WAITFORTIMER() { while ( timerflag == 0); timerflag = 0; }
#define TIMER_0_CNT 0xCA // 111us with CLK/8 prescale
#define RC5BITREF1 6
#define RC5BITREF2 11
#define RC5BITREF3 14
#define TMC8_STOP 0
#define TMC8_CK8 _BV(CS01)
unsigned int rc5decode( void );
static volatile uint8_t timerflag; //must be volatile because modified by interrupt handler
SIGNAL(SIG_OVERFLOW0)
/*
** signal handler for timer0 overflow interrupt
*/
{
timerflag = 1; // set global variable
TCNT0 = TIMER_0_CNT; // reset counter to get this interrupt again
}
unsigned int rc5decode( void )
/*
** decoded RC5 data is returned, or 0x0000 if RC5 data not recognized
*/
{
unsigned int rc5data;
unsigned char timer, i;
// init timer/Counter0
TCCR0 = TMC8_CK8; // use CLK/8 prescale
TCNT0 = TIMER_0_CNT; // set timer T/16 = 111us
TIMSK = _BV(TOIE0); // enable TCNT0 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
break;
}
// wait 3/4 T: await next bit
for ( timer=0; timer < 12 ; timer++) WAITFORTIMER();
}
}else {
rc5data = 0x0000; // error, invalid RC-5 code
}
TCCR0 = TMC8_STOP; // stop timer0
return (rc5data);
}//rc5decode
