|
Gestire i
Telecomandi di apparecchiature Sony con il micro PIC16F84
|
 |
Applicazione per la demo-board presente su questo sito.
Come
ricevitore ho utilizzato un rivelatore ad infrarossi recuperato
da un
vecchio videoregistratore (va bene anche TV e di qualsiasi marca )
come
visibile da figura.
Alla
pressione di qualsiasi tasto , vedrete apparire sul display il
corrispondente
codice numerico.
Come telecomando ho utilizzato un tipo
universale da 8 € impostato sulle
frequenze Sony.
La piedinatura del sensore è la seguente:
|
Il mio
telecomando è un IMEX IM-1010 impostato sul codice TV 199 .
Non c'è uno schema visto che occorre
solo alimentare il sensore "IR" e collegare la sua uscita alla porta
RA0 del PIC .(nb.
con alcuni sensori occorre inserire una resistenza di pullup da 10 k
sull'out )
Il codice è rappresentato con 12 bit
che saranno ricevuti nel seguente modo:
|
HEADER |
BIT0 |
BIT1 |
BIT2 |
BIT3 |
BIT4 |
BIT5 |
BIT6 |
BIT7 |
BIT8 |
BIT9 |
BIT10 |
BIT11 |
I bit da 0 a
6 rappresentano il pulsante mentre , i bit da 7 a 12 il device .
L'header ha una
durata di 2200 uS (1-->0) mentre ogni singolo bit è codificato nel seguente
modo:
bit=1
bit=0
Esempio di pressione pulsante 1
comando 0 :
header
bit0=1 bit1=0 bit2=0
bit3=0 bit4=0 bit5=0 bit6=0
bit7=0 bit8=0 bit9=0 bit10=0
bit11=0 end
Di seguito il software per tesstare
il tutto.
/***************************************************************************/
/* Gestione telecomandi TV-VCR.... Sony per DEMO_BOARD */
/* Author : toniobr Date : 03-11-2003 --- www.toniobr.altervista.org */
/* NB. Con un quarzo superiore a 4Mhz non è garantito il funzionamente,se */
/* dovessero insorgere problemi , basterà aumentare progressivamente i */
/* valori di HEADER_MAX , HEADER_MIN e HIGH_VALUE */
/***************************************************************************/
#define XTAL_FREQ 4MHZ /* Crystal frequency in MHz */
#include <pic.h>
#include "lcd.h"
#include "delay.h"
#include "stdio.h"
#define PORTBIT(adr,bit) ((unsigned)(&adr)*8+(bit))
//Configuration bit
__CONFIG(XT & WDTDIS & PWRTEN );
static bit Button_A @ PORTBIT(PORTB,0);
static bit IR_PIN @ PORTBIT(PORTA,0);
static bit LED @ PORTBIT(PORTA,1);
extern void itoa(int,char[]);
#define HEADER_MAX 210
#define HEADER_MIN 130
#define HIGH_VALUE 74 //l'impulso con valore superiore a HIGH_VALUE viene considerato 1
/*--------------------------------------------------------------------------*/
/* Calcola la durata dell'impulso negativo in passi di 10 mSec */
/* Ritorna 0 se non viene generato un impulso entro 1000uS */
/*--------------------------------------------------------------------------*/
int pulsin()
{
int i=0;
int x=0;
while(IR_PIN){
DelayUs(1);
x++;
if(x>=10000)
return 0;
}
while(!IR_PIN){
DelayUs(10);
++i;
}
return i;
}
/*---------------------------------------------------------------------------*/
/*Ritorna il valore del pulsante premuto su 12 bit */
/*---------------------------------------------------------------------------*/
int ir_rx()
{
int header=0;
int packet=0;
char i;
header=pulsin(); // header vale circa 77 con fosc 4 Mhz
if (header<HEADER_MIN || header>HEADER_MAX)
return -1;
for(i=1;i<=12;i++){ //pulsin circa= 42 --> 1 , pulsin circa= 24 --> 0
if (pulsin()>=HIGH_VALUE)
packet|=0b100000000000;
if (i<12) packet=packet>>1;
}
return packet;
}
/*----------------------------------------------------------------------------*/
/* Converte un numero da intero in stringa di caratteri */
/*----------------------------------------------------------------------------*/
void itoa(int n,char s[])
{
int i,a ;
if (n/10000)
a=4;
else if (n/1000)
a=3;
else if (n/100)
a=2;
else if (n/10)
a=1;
else
a=0;
i=a;
do
{
s[i--]= n%10 + '0';
}while ((n/=10)>0);
s[a+1]='\0';
}
/*----------------------------------------------------------------------------*/
/* MAIN PROGRAM */
/*----------------------------------------------------------------------------*/
main(void)
{
/* Elenco menu ciclo */
const char *MNUA11=" start ";
int i;
char ir_but , ir_dev ;
char str[5];
TRISB = 0b00000011; /* portb.0 e portb.1 = ingressi */
TRISA = 0b00000001;
PORTB=0;
PORTA=0;
lcd_init();
lcd_puts(MNUA11);
while(1){
LED=1;
if (!IR_PIN)
{
i=ir_rx();
if(i==-1){
lcd_puts("ERROR");
}
lcd_clear();
ir_dev=i>>7;
ir_but=(i & 0b000001111111)+1; // i primi 7bit (LSB) rappresentano il pulsante premuto
switch(ir_dev) // mentre i restanti 5 bit il device (TV=1 , VCR=2 ...)
{
case 1: lcd_puts("TV");
break;
case 2: lcd_puts("VCR");
break;
default : lcd_puts("?");
}
itoa(ir_but,str);
lcd_puts(" Button:");
lcd_puts(str);
}
}
}
Scarica l'intero progetto
|
|