Autor Tema: Problema Decodificador MANCHESTER con PIC16f628A  (Leído 1533 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado ThePIC-GUY

  • PIC10
  • *
  • Mensajes: 19
Problema Decodificador MANCHESTER con PIC16f628A
« en: 13 de Agosto de 2014, 19:07:25 »
Que tal amigos.
Desde hace una semana tengo un problema que me esta haciendo querer golpear mi cabeza contra del escritorio XD, y despues de probar muchas cosas y buscar por tods lados sin encontrar la respuesta decidi poner esto aqui.

Estoy trabajando en un receptor RF, mas bien en el decodificador para el receptor, no tengo ningun problema de hardware, lo que envio es lo que recibo, el problema es al momento de interpretar los datos recibidos. El formato de codificacion que usa es manchester.
La codificación manchester consiste en que cada bit de la informacion a enviar se represente por una transición en mitad del periodo, de tal modo que un "0" es representado por una transicion de "ALTO" a "BAJO" y un "1" es representado por una transición de "BAJO" a "ALTO".
partiendo de esta parte de la teoría se me ocurrió lo siguiente:
Si se tiene un periodo "T" con un cambio justo en la mitad del periodo, la distancia (el tiempo) entre cambio y cambio sera de T/2 cuando el dato siguiente sea el mismo que el dato anterior pero cuando el dato sea diferente se tendrá el periodo completo. sin embargo, la distancia entre "cambio significativos" sera siempre de un periodo "T", por lo que se puede ignorar la primer parte del dato y en la segunda mitad(después de la transición) tenemos el dato real. (Ver imagen1.PNG).

Para la codificación en manchester utilizo un periodo de 272uS, lo que da un tiempo de 136uS para la transición significativa. Para detectar los datos utilizo la "int-on-change" de RB7, ademas al principio de la trama de datos envió un pulso en "ALTO" durante aprox. 5mS para indicar un inicio de trama correcto(esto es parte solo prueba, muchos de los transmisores que usamos no envían este pulso). Después de recibir correctamente el inicio de la trama se va a recibir los datos, El primer cambio se ignora, para solo tomar los cambios significativos.
Al detectar una cambio de estado se inicia el timer0 para temporizar 200uS, si se desborda el timer se considera como un cambio de dato(dato recibido 0, siguiente 1 o viceversa), todos los desbordes de timer son inicio de dato por lo que se ignoran y se toma el dato al siguiente cambio.

Para muestrear los datos lo que hago es que: si RB7=1 lo guardo en un buffer y despues lo recorro a la izquierda, si RB7=0 solo recorro el buffer. es en esta parte donde tengo el problema, lo que sucede es que despues de tomar todas las muestras de los datos (las cuales se supone estan correctas), al leer los datos en buffer estan mal. En la igamen senales,jpg se puede ver la sincronizacion de cada una de las acciones, por lo que el problema solo se me ocurre que sea en la parte del codigo que aumenta el buffer, ya lo puse de formas diferentes e incluso en ensamblador.

El programa tiene 4 estados
   RFRESET: espera detectar incio de trama
   RFLISTEN: se detecto inicio de trama, espera que se detecte primer dato o que pase tiempo de timeout por falsa activacion
   RFDECOD: detecta los datos y los almacena en buffer
   RFDECRYPT: en este estado se debe procesar los datos (aun esta icompleto)
El Compilado que uso es PICC 7.90 version PRO de HI-TECH
Dejo en comentario las diferentes formas en las que tomo la muestra por si alguna de ellas les parece mas correcta

Código: [Seleccionar]
****************************************Librerias***********************************************/
#include <htc.h>
#include <math.h>
/*************************************configuracion*********************************************/
__CONFIG(UNPROTECT & UNPROTECT & LVPDIS & BORDIS & MCLRDIS & PWRTEN & WDTDIS & INTIO);
/****************************************#DEFINE************************************************/
#define RFRESET 0
#define RFLISTEN 1
#define RFDECOD 2
#define RFDECRYPT 3


/**************************************PROTOTIPOS***********************************************/
void inicia(void);

/***********************************VARIABLES GLOBALES******************************************/
unsigned char buffer[8]; //bufer de recepcion de datos
unsigned char buflast[8]; //guarda el ultimo dato valido recivido
bit rfbit, RFFULL;
unsigned char RFSTATE,rfbitc,bitc,bufc,btemp;
unsigned int curm;
unsigned char pre1, pre2, serieh, seriem, seriel, estado, chks1, chks2; //componentes de datos

#define nnnn estado,0
#define mode estado,1
#define tmpr estado,2
#define blvl estado,3
#define lzo3 estado,4
#define lzo2 estado,5
#define lzo4 estado,6
#define lzo1 estado,7

/*************************************INTERRUPCIONES********************************************/
void interrupt ISR(void)
{ //RA3=1;
//int timer 0
if(T0IF){
T0IF=0;
switch(RFSTATE){
case RFLISTEN: //condicion de timeout
RFSTATE=0; //paso tiempo de guarda, y no se detectaron datos
T0IE=0; //DESACTIVAR INTERRUPCION TIMER 0
T0IF=0;
break;
//fin RFLISTEN
case RFDECOD:
RB0=RB7;
RB4=~RB4;
rfbit=RB7; //tomar muestra del valor
rfbitc++; //numero del bit del buffer[x]
if(bufc==8){T0IE=0; RFSTATE++;} //recibido ultimo dato del ultimo byte
TMR0=144;
//TMR0=156;
T0IF=0;
break;
//fin RFDECOD
default: T0IF=0; break;
}//fin switch
}//Fin T0IF
//int RB7
else if (RBIF) {
RB0=RB7;
RBIF=0;
switch(RFSTATE){
case RFRESET:    rfbit=RB7; //leer puerto para cambiar condicion
OPTION=0x04; //PRESCALES AL TIMER0 A 32
//TMR0=131; //SE CARGA TMR0 PARA RETARDO DE 4mS
TMR0=162; //SE CARGA TMR0 PARA RETARDO DE 3mS
T0IF=0; //SE ACTIVA TMR0INT
while(RB7==1&&T0IF==0){} //esperar a que se desborde el timer
if(T0IF==1){RFSTATE++; T0IF=0;} //header correcto, ir al siguiente estado
else RFSTATE==0; //no se cumplio la condicion, pasar a estado inicial
break;
//fin RFRESET
case RFLISTEN: //se detecto primer dato
rfbit=RB7;
RFSTATE++; //CAMBIAR AL SIGUIENTE ESTADO
// #asm
// MOVLW   _buffer //se obtiene la direccion de buffer.
// MOVWF _curm //direccion actual a la que se apunta
// //MOVWF   _FSR            //cargar memoria en el apuntador
// MOVLW   8 //CONTADOR DE BITS POR REGISTRO.
// MOVWF   _bitc
// #endasm
bitc=0;
bufc=0;
rfbitc=0;
OPTION=0x08; //timer 0 prescaler a 2
//buffer[bufc]=rfbit; //el primer dato, siempre 0, se ignora
rfbitc++;
TMR0=144;
//TMR0=156; //PARA RETARDO DE 200uS
T0IF=0;
break;
//fin RFLISTEN
case RFDECOD:
//rfbit=RB7; //tomar muestra del valor
if(rfbitc%2==1){

// #asm
// MOVF _curm,w //direccion actual a la que se apunta
// MOVWF   _FSR            //cargar memoria en el apuntador
// MOVF _INDF,W
// MOVWF _btemp
// BTFSC _PORTB,7 //revisar estado de RB7
// INCF _btemp,F //RB7=1; aumentar 1 el registro apuntado y despues roar a la izquierda
// RLF _btemp,W
// RLF _btemp,F //RB7=0; solo rotar a la izquierda
// MOVWF _INDF

// DECFSZ  _bitc,F //drecrementar 1, si no es cero se sigue en el mismo registro
// GOTO    FINT //ir al final de la rutina
// INCF    _curm,F //si bitc=0, pasamos al siguiente registro
// MOVLW   _buffer+8 //cargar la ultima direccion de buffer + 1
// XORWF   _curm,W //XOR CON EL REGISTRO ACTUAL APUNTADO.
// FINT:
// #endasm

// buffer[bufc]=buffer[bufc]+RB7;//rfbit; //se agrega el nuevo dato
if(RB7==1){buffer[bufc]++;}
buffer[bufc]=buffer[bufc]<<1; //se rota a la izquierda, para el siguiente dato
RA3=RB7;
bitc++; RB3=~RB3;
} //numero del bit del buffer[x]
rfbitc++;
if(bitc==8){bitc=0; bufc++;} //se recibio el ultimo bit, se pasa al siguiente buffer
if(bufc==8){T0IE=0; RFSTATE++;} //recibido ultimo dato del ultimo byte
TMR0=144;
//TMR0=156;
T0IF=0;
break;
//finRFDECOD
default: break;
}//fin switch
}//fin if RBIF
//
else  {/*RA3=0;*/  return;}
//RA3=0;
}//fin ISR
/**************************************PROGRAMA PRINCIPAL****************************************/
void main(void)
{ unsigned char x=0,i=0,y=0;
inicia();
   while(1)
   {
switch(RFSTATE){
//estado RFRESET
case RFRESET:
// T0IE=0;
// bitc=0;
// bufc=0;
// rfbitc=0;
#asm
CLRF _buffer // buffer 1, preambulo 1
CLRF _buffer+2
CLRF _buffer+3
CLRF _buffer+4
CLRF _buffer+5
CLRF _buffer+6
CLRF _buffer+7 //buffer 8, checksum 2
#endasm
break;
//estado RFLISTEN
case RFLISTEN: T0IE=1;

break;
//estado RFDECOD
case RFDECRYPT: //copiar buffer de recepcion
x=0;
RFFULL=1;
//
// for(x=0;x<8;x++)
// { estado=buffer[x];
// #asm
// CLRF _PORTA
// CLRF _PORTB
// BTFSC _estado,0
// BSF _PORTA,2
// BTFSC _estado,1
// BSF _PORTA,0
// BTFSC _estado,2
// BSF _PORTA,3
// BTFSC _estado,3
// BSF _PORTB,6
// BTFSC _estado,4
// BSF _PORTB,5
// BTFSC _estado,5
// BSF _PORTB,4
// BTFSC _estado,6
// BSF _PORTB,3
// BTFSC _estado,7
// BSF _PORTB,0
// #endasm
// //RA2=nnnn; RA0=mode; RA3=tmpr; RB6= blvl; RB5=lzo3; RB4=lzo2; RB3=lzo4; RB0=lzo1;
// //RA2=1; RA0=1; RA3=1; RB6=1; RB5=1; RB4=1; RB3=1; RB0=1;
// for(i=0;i<6;i++){
// TMR1L=0;
// TMR1H=0;
// TMR1IF=0;
// TMR1ON=1;
// while(TMR1IF==0);}
// RA2=0; RA0=0; RA3=0; RB6=0; RB5=0; RB4=0; RB3=0; RB0=0;
// }
// TMR1ON=0;



RFFULL=0;
RFSTATE=0; //volver a comenzar
break;
default: break;
}//fin switch
//
// if(RFFULL){
//
// for(x=0;x<8;x++)
// { estado=buffer[x];
// #asm
// CLRF _PORTA
// CLRF _PORTB
// BTFSC _estado,0
// BSF _PORTA,2
// BTFSC _estado,1
// BSF _PORTA,0
// BTFSC _estado,2
// BSF _PORTA,3
// BTFSC _estado,3
// BSF _PORTB,6
// BTFSC _estado,4
// BSF _PORTB,5
// BTFSC _estado,5
// BSF _PORTB,4
// BTFSC _estado,6
// BSF _PORTB,3
// BTFSC _estado,7
// BSF _PORTB,0
// #endasm
// //RA2=nnnn; RA0=mode; RA3=tmpr; RB6= blvl; RB5=lzo3; RB4=lzo2; RB3=lzo4; RB0=lzo1;
// //RA2=1; RA0=1; RA3=1; RB6=1; RB5=1; RB4=1; RB3=1; RB0=1;
// for(i=0;i<2;i++){
// TMR1L=0;
// TMR1H=0;
// TMR1IF=0;
// TMR1ON=1;
// while(TMR1IF==0);}
// }
// RA2=0; RA0=0; RA3=0; RB6=0; RB5=0; RB4=0; RB3=0; RB0=0;
// RFFULL=0;
//
// }//fin if RFFULL


   }//fin while
}//fin main

/******************************************FUNCIONES**********************************************/
void inicia(void)
{unsigned char i;
//Entradas y salidas
CMCON=0x07;
VRCON=0x00;
TRISA=0x00; // RA2, RA1, RA0 SALIDAS PARA ZONAS(LEDS) RA6 Y RA7 PARA EEPROM
TRISB=0x82; //RB7 ENTRADA DE DATOS RF, RB1 Y 2 PARA PROGRAMACION SERIAL. LAS DEMAS SALIDAS PARA ZONAS
PORTB=0;
PORTA=0;
OPTION=0x88; //RESUSTENCIA DE PULL-UP desactiada, PRESCALER ASIGNADO AL WDT
//INTERRUPCIONES
INTCON=0xC8; //GIE=1,PEIE=1, RBIE=1  inttmr0 se activan al pasar a estado de escucha
//TIMER 1
T1CON=0x30;
//valores iniciales
RFSTATE=RFRESET; //
RFFULL=0;
}//fin inicia