Codificación Manchester incorrecta desde el microcontrolador PIC

0

He escrito un programa en C para el PIC18F4620. Mi PIC funciona como un codificador, que codifica un flujo de datos en el código de Manchester. Mi salida es rd7, donde debería aparecer el código de Manchester, pero solo aparece de 0 a 1 transiciones. Alguien puede ayudarme? Aquí está mi código:

#define MAX_BITS 12
#define MANCHESTER_BIT 1



sbit ENCODER_OUT at RD7_bit;

sbit DATA_OUT at RD6_bit;

sbit LED1 at RD0_bit;
sbit LED2 at RD1_bit;

unsigned int Encode_val;
unsigned char Encode_State;

unsigned int Encode_Count;

const unsigned char START_SYNCH = 0;
const unsigned char SYNCH = 0;
const unsigned char END_SYNCH = 0;
const unsigned char SETUP = 0 ;
const unsigned char TRANSITION = 0  ;
const unsigned char COMPLETE = 0 ;
const unsigned char IDLE = 0;
void Start_Transmission(unsigned int ) ;


void InitTimer0(){
  T0CON         = 0x88;
  TMR0H         = 0xFE;
  TMR0L         = 0x0C;
  GIE_bit         = 1;
  TMR0IE_bit         = 1;
  TMR0IF_bit = 0;
}

void InitTimer1()
{
  T1CON  = 0x01;
  TMR1IF_bit     = 0;
  TMR1H  = 0xFF;
  TMR1L  = 0x06;
  TMR1IE_bit     = 1;
  INTCON     = 0xC0;
}

void Interrupt(){

  if (TMR1IF_bit)
  {
      TMR1IF_bit = 0;
      TMR1H  = 0xFF;
      TMR1L  = 0x06;
      DATA_OUT = ~DATA_OUT;

  }


  if (TMR0IF_bit){
    TMR0IF_bit = 0;
    TMR0H      = 0xFE;    //5 Khz interrupts   0.2 ms  
    TMR0L      = 0x0C;
    LED2 = ~LED2;


 switch(Encode_State){

        case START_SYNCH:
            ENCODER_OUT ^= MANCHESTER_BIT; //bring line low, start synch pulse
            Encode_State = SYNCH;
            break;
        case SYNCH:
            Encode_State = END_SYNCH; // synch pulse needs to be twice the interrupt rate
            break;
        case END_SYNCH:
            ENCODER_OUT |= MANCHESTER_BIT; //bring the line high, end synch pulse
            Encode_Count =0;
            Encode_State = SETUP;
            break;
        case SETUP:
            if((Encode_val & 0x01))
                ENCODER_OUT = ((Encode_val & 0x01) | (ENCODER_OUT & MANCHESTER_BIT)); //next bit to transmit "1"
            else
                ENCODER_OUT = ((Encode_val & 0x01) & (ENCODER_OUT & MANCHESTER_BIT)); //next bit to transmit "0"
            Encode_State = TRANSITION;
            break;
        case TRANSITION:
            ENCODER_OUT = (Encode_val & 0x01) ^ MANCHESTER_BIT; //set the line for transition
            if(Encode_Count++ < MAX_BITS){
                Encode_val = (Encode_val >> 1);
                Encode_State = SETUP;
            }
            else
                Encode_State = COMPLETE;
            break;
        case COMPLETE:
            ENCODER_OUT |= MANCHESTER_BIT; //transition done, bring the line high
            Encode_state = IDLE;
        case IDLE:
        default:
            break;
 }
 }
}




void Start_Transmission(unsigned int val)
{
   int i, parity_bit_count =0;

    for(i=0; i < MAX_BITS; i++)
        if(((val >> i) & 0x0001) == 1)
            parity_bit_count++;

    if((parity_bit_count & 0x0001) == 1)
        val |= 0x8000;

    Encode_val = val;
    Encode_State = START_SYNCH;
}


void main() {
  TRISD = 0;         
  PORTD = 0;
  LED1 = 1;

  Start_Transmission(0);
  InitTimer0();
  InitTimer1();
}
    
pregunta J. Devero

1 respuesta

2

Necesitas volver a verificar tus operaciones lógicas.
Su código:

if((Encode_val & 0x01))
  ENCODER_OUT = ((Encode_val & 0x01) | (ENCODER_OUT & MANCHESTER_BIT)); //next bit to transmit "1"
else
  ENCODER_OUT = ((Encode_val & 0x01) & (ENCODER_OUT & MANCHESTER_BIT)); //next bit to transmit "0"  

evaluará a:

if(Encode_val & 0x01)
  ENCODER_OUT = 1;
else
  ENCODER_OUT = 0;  

porque, si (Encode_val & 0x01) es verdadero,
entonces ENCODER_OUT = ((Encode_val & 0x01) | (ENCODER_OUT & MANCHESTER_BIT))
se convierte en ENCODER_OUT = (1 | (ENCODER_OUT & MANCHESTER_BIT))
y (1 | cualquier cosa) == 1
de manera similar, si (Encode_val & 0x01) es falso,
entonces ENCODER_OUT = ((Encode_val & 0x01) & (ENCODER_OUT & MANCHESTER_BIT))
se convierte en (0 & (ENCODER_OUT & MANCHESTER_BIT))
y (0 & cualquier cosa) == 0

También está utilizando una función xor en ENCODER_OUT ^= MANCHESTER_BIT y espera que el resultado siempre sea 0, pero en realidad dependerá del valor anterior de ENCODER_OUT.
Preferiría hacer algo como ENCODER_OUT = !MANCHESTER_BIT allí.

    
respondido por el brhans

Lea otras preguntas en las etiquetas