Forum: Compiler & IDEs RC5 Char mit uint vergleichen


von Richard B. (rbrose)


Lesenswert?

Hallo,

Ich benutze die RC5 Funktion von Peter Dannegger.
1
#include "main.h"
2
3
#define RC5TIME   1.778e-3    // 1.778msec
4
#define PULSE_MIN  (uchar)(XTAL / 512 * RC5TIME * 0.4 + 0.5)
5
#define PULSE_1_2  (uchar)(XTAL / 512 * RC5TIME * 0.8 + 0.5)
6
#define PULSE_MAX  (uchar)(XTAL / 512 * RC5TIME * 1.2 + 0.5)
7
8
9
uchar  rc5_bit;        // bit value
10
uchar  rc5_time;        // count bit time
11
uint  rc5_tmp;        // shift bits in
12
volatile uint  rc5_data;        // store result
13
14
15
ISR (TIMER0_OVF_vect)
16
{
17
  uint tmp = rc5_tmp;        // for faster access
18
19
  TCNT0 = -2;          // 2 * 256 = 512 cycle
20
21
  if( ++rc5_time > PULSE_MAX ){      // count pulse time
22
    if( !(tmp & 0x4000) && tmp & 0x2000 )  // only if 14 bits received
23
      rc5_data = tmp;
24
    tmp = 0;  
25
  }
26
27
  if( (rc5_bit ^ xRC5_IN) & 1<<xRC5 ){    // change detect
28
    rc5_bit = ~rc5_bit;        // 0x00 -> 0xFF -> 0x00  
29
30
    if( rc5_time < PULSE_MIN )
31
  {      // to short
32
      tmp = 0;    
33
  }
34
35
    if( !tmp || rc5_time > PULSE_1_2 ){    // start or long pulse time
36
      if( !(tmp & 0x4000) )      // not to many bits
37
        tmp <<= 1;        // shift
38
      if( !(rc5_bit & 1<<xRC5) )    // inverted bit
39
        tmp |= 1;        // insert new bit
40
      rc5_time = 0;        // count next pulse time
41
    }
42
  }
43
44
  rc5_tmp = tmp;
45
}

Jetzt will ich in meiner Main Schleife eine Abfrage bauen ob - und
welche Taste bedrückt wurde.
1
  while(1) 
2
  {
3
    for (unsigned char i=0; i<20; i++)
4
            _delay_ms(10);
5
6
    if( get_key_press(1) )
7
    {  
8
      couterZ++;
9
    }      
10
    if( get_key_press(2) )
11
    {  
12
      couterZ--;
13
    }      
14
    
15
    if(couterZ == 11)
16
      couterZ = 0;
17
18
    currentSeg1 = pgm_read_byte(&c_led[couterZ]);
19
    currentSeg2 = pgm_read_byte(&c_led[couterZ]);
20
    currentSeg3 = pgm_read_byte(&c_led[couterZ]);        
21
  }

Hier ein Beispiel mit get_key_press(1) und get_key_press(2)
Also wird hier abgefragt ob die Taste 1 oder 2 auf der Fernbedienung
gedrückt wurden.

Und hier kommt der Knackpunkt:
1
uint8_t get_key_press( uint8_t key_mask )
2
{
3
  uint8_t i;
4
  char key[30];
5
6
  cli();
7
        i = rc5_data;      // read two bytes from interrupt !
8
  rc5_data = 0;
9
        sei();
10
11
  itoa((i & 0x3F) | (~i >> 7 & 0x40), key, 10); // Key Code
12
13
    return key_mask;
14
}
Wie muss ich hier den vergleich machen? Damit ich den Key Code mit dem
Int Wert vergleichen kann?

Ist das überhaupt so sinnvoll? Weil bei jeder Abfrage für jede Taste
rc5_data neu geholt wird? Oder mache ich das anders?

von Richard B. (rbrose)


Lesenswert?

Kann mir den wirklich keiner helfen? Oder ist etwas unklar?

von ernst (Gast)


Lesenswert?

Hallo,

guck dir doch mal die Zeile an:
1
itoa((i & 0x3F) | (~i >> 7 & 0x40), key, 10); // Key Code

So sollte der Key Code in einer int Variable landen (nicht probiert, es 
reicht bestimmt auch eine 8 Bit Variable):
1
unsigned int keyCode = (i & 0x3F) | (~i >> 7 & 0x40)

ernst

von Richard B. (rbrose)


Lesenswert?

Vielen Dank es funktioniert!

Aber habe jetzt das nächste Problem:

Hier wird Taste 16 erkannt ... aber Taste 17 nicht :-(
1
  while(1) 
2
  {
3
      
4
    if( get_key_press(16) )
5
    {  
6
      couterZ++;
7
    }
8
    
9
    if( get_key_press(17) )
10
    {  
11
      couterZ--;
12
    }    
13
14
  
15
    for (unsigned char i=0; i<20; i++)
16
      _delay_ms(10);
17
    
18
    if(couterZ == 11)
19
      couterZ = 0;
20
21
  //  PORTD = pgm_read_byte(&c_led[couterZ]);
22
23
    currentSeg1 = pgm_read_byte(&c_led[couterZ]);
24
    currentSeg2 = pgm_read_byte(&c_led[couterZ]);
25
    currentSeg3 = pgm_read_byte(&c_led[couterZ]);
26
        
27
  }

Wenn ich aber die Abfrage umtausche wird Taste 17 erkannt und Taste 16 
nicht. Wieso ist das so?
1
  while(1) 
2
  {      
3
    if( get_key_press(17) )
4
    {  
5
      couterZ--;
6
    }
7
8
    if( get_key_press(16) )
9
    {  
10
      couterZ++;
11
    }
12
        
13
  
14
    for (unsigned char i=0; i<20; i++)
15
      _delay_ms(10);
16
    
17
    if(couterZ == 11)
18
      couterZ = 0;
19
20
  //  PORTD = pgm_read_byte(&c_led[couterZ]);
21
22
    currentSeg1 = pgm_read_byte(&c_led[couterZ]);
23
    currentSeg2 = pgm_read_byte(&c_led[couterZ]);
24
    currentSeg3 = pgm_read_byte(&c_led[couterZ]);
25
        
26
  }

von Bastler (Gast)


Lesenswert?

Vieleicht den return value von get_key_press() in einer variable 
speichern und erst danach testen?

Cheers

von Richard B. (rbrose)


Lesenswert?

Ahh Logisch, wenn ich die "get_key_press" Methode Aufrufe wird rc5_data 
auf 0 gesetzt und die nächste Überprüfung stimmt schon nicht mehr.

Habe das so geändert:
1
while(1) 
2
{
3
  uint8_t key_tmp;
4
5
  cli();
6
      i = rc5_data;      // read two bytes from interrupt !
7
  rc5_data = 0;
8
      sei();    
9
10
      key_tmp  = (i & 0x3F) | (~i >> 7 & 0x40);
11
12
      
13
  if( get_key_press(i, 16) )
14
  {  
15
    couterZ++;
16
  }
17
    
18
  if( get_key_press(i, 17) )
19
  {  
20
    couterZ--;
21
  }    
22
23
  
24
  for (unsigned char i=0; i<20; i++)
25
    _delay_ms(10);
26
    
27
  if(couterZ == 11)
28
    couterZ = 0;
29
30
31
  currentSeg1 = pgm_read_byte(&c_led[couterZ]);
32
  currentSeg2 = pgm_read_byte(&c_led[couterZ]);
33
  currentSeg3 = pgm_read_byte(&c_led[couterZ]);        
34
}
35
36
37
uint8_t get_key_press( uint8_t key, uint8_t key_mask )
38
{
39
  if(key == key_mask)
40
  {
41
    return 1;
42
  }
43
  else
44
  {
45
    return 0;
46
  }    
47
}

Und schon funktioniert es.

Danke!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.