Décodage d'une trame RC5 (télécommande TV) en langage C

Ou comment utiliser une télécommande infra-rouge pour piloter un microcontrôleur.

J'ai écrit cette fonction en langage C que j'utilise, une fois compilée avec avr-gcc sur des uC AVR ATmega
On suppose que le module récepteur IR est relié au pin7 du port D
Sommaire :
1 - Code C

1 Code C

CODE SOURCE en avr C
  1. int RecvRC5 (void)
  2. /* recepteur RC5 bas niveau qui scrute le port relie au capteur et decode le signal
  3.  
  4. 2 bits de start
  5. 1 bit de basculement
  6. 5 bits d adressage (type d appareil, TV, VCR etc...)
  7. 6 bits de commande (touches)
  8. */
  9. {
  10. uint32_t t;
  11. uint8_t niv_entree, niv1, niv2; /* booleens - niveaux des deux demi plateaux constituant un bit */
  12. uint8_t n;
  13. uint16_t data;
  14.  
  15. t=0;
  16. niv1=0;
  17. niv2=0;
  18. data = 0;
  19.  
  20. niv_entree=1;
  21. /* attente pendant la duree d une trame d un front descendant (le signal issu du capteur est a 1 au repos) */
  22.  
  23. const unsigned long int tmax = 14*1778; //24892us = duree de 1 trame (environ 25ms donc)
  24.  
  25. while ( (niv_entree == 1) && (t<= tmax) )
  26. {
  27. if ( (PINC & 0b10000000) > 0) { niv_entree=1; } else { niv_entree=0; }
  28. _delay_us(1);
  29. t++;
  30. }
  31. /* si le signal parvient trop vite (< 2 bits) on en deduit qu on a pris le train en marche et on saute,
  32. puisque lecture impossible de la trame en cours */
  33.  
  34. if (t < (889 * 2)) return t;
  35.  
  36. if (t > tmax) return 2; /* temps maxi ecoule, pas de signal reçu */
  37.  
  38. /* ici on se trouve juste un epsilon apres le basculement a 0 du premier bit de start (milieu de bit) */
  39.  
  40. _delay_us(444); /* duree de 1/4 bit */
  41.  
  42. for (n=1; n<=13; n++)
  43. {
  44. _delay_us(889); // duree de 1/2 bit
  45. /* ici on se trouve au milieu du niveau du plateau du demi bit */
  46. if ( (PINC & 0b10000000) == 0) { niv1 = 0; } else { niv1 = 1; }
  47. _delay_us(889); // duree de 1/2 bit
  48. /* ici on se trouve au milieu du second plateau du demi bit */
  49. if ( (PINC & 0b10000000) == 0) { niv2 = 0; } else { niv2 = 1; }
  50. /* ici on connait les valeurs des deux niveaux, on en deduit le sens de la transition (front montant ou descendant)*/
  51. if (niv1 == niv2) { return 3; } // erreur de lecture, bit non valide
  52. if ((niv1 == 1 ) && (niv2 == 0)) { data |= 0b00000001; }
  53. data = data << 1;
  54. }
  55. data = data >> 1; // on rejette le dernier decallage (sans perte de bit puisque largeur data = 16 bits > )
  56.  
  57. rxCmd_IR = data & 0b0000000000111111;
  58. rxAdr_IR = (data & 0b0000011111000000) >> 6;
  59. bit_bascul_IR = (data & 0b0000100000000000) >> 11;
  60. return 0;
  61. }
  62.  

2 -



19851