0
\$\begingroup\$

I have written a C program for the PIC18F4620. My PIC works as an encoder, which encodes a data stream in Manchester code. My output is rd7, where it should appear the Manchester code, but only appears 0 to 1 transitions. Can anybody help me? Here is my code:

#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();
}
uint128_t
8,7956 gold badges28 silver badges28 bronze badges
asked Jun 8, 2016 at 18:52
\$\endgroup\$
1
  • 2
    \$\begingroup\$ It would be best if you were clearer about exactly what output signal is being produced vs. the one expected. Consider porting the core of your algorithm into a program which you can build for a PC and run to print output on the terminal and see if it does what you expect. If not, it will likely be easier to debug there. \$\endgroup\$ Commented Jun 8, 2016 at 19:01

1 Answer 1

2
\$\begingroup\$

You need to recheck your logic operations.
Your code:

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" 

will evaluate to:

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

because, if (Encode_val & 0x01) is true,
then ENCODER_OUT = ((Encode_val & 0x01) | (ENCODER_OUT & MANCHESTER_BIT))
becomes ENCODER_OUT = (1 | (ENCODER_OUT & MANCHESTER_BIT))
and (1 | anything) == 1
similarly, if (Encode_val & 0x01) is false,
then ENCODER_OUT = ((Encode_val & 0x01) & (ENCODER_OUT & MANCHESTER_BIT))
becomes (0 & (ENCODER_OUT & MANCHESTER_BIT))
and (0 & anything) == 0

You're also using an xor function in ENCODER_OUT ^= MANCHESTER_BIT and expecting the result to always be 0, but it will actually depend on the previous value of ENCODER_OUT.
I would rather do something like ENCODER_OUT = !MANCHESTER_BIT there.

answered Jun 8, 2016 at 19:55
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.