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();
}
-
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\$Chris Stratton– Chris Stratton2016年06月08日 19:01:10 +00:00Commented Jun 8, 2016 at 19:01
1 Answer 1
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.
Explore related questions
See similar questions with these tags.