|
|
View previous topic :: View next topic |
Author |
Message |
viknes1985
Joined: 11 Nov 2008 Posts: 24
|
Read Manchester.... Where's the Problem? |
Posted: Sun Feb 01, 2009 3:33 am |
|
|
If using interrupt to read the code, it gives more problems. Since the pulses are in 90 us to 100 us... Better to use fast io
Last edited by viknes1985 on Fri Mar 20, 2009 12:29 pm; edited 1 time in total |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sun Feb 01, 2009 4:00 am |
|
|
Binary data can be printed e.g. in hexdecimal format, printf("%02x",STAC[k]);
I understand that your code is intended to receive one packet and stop then, cause there are no means to restart the reception.
It's hard to see, however, if the manchester receive algorithm as such is working correct. We don't even know the timing of the received waveform. |
|
|
viknes1985
Joined: 11 Nov 2008 Posts: 24
|
Interrupter |
Posted: Sun Feb 01, 2009 4:46 am |
|
|
Is My reader function (#int_RB) will function only once or everytime when there's a change port B4 to B7?
Code: |
program ManReceive6;
label do_sample, sync1; // a litle bit of unpopular labeling
var first_edge, // signalizes if the first rising edge pulse
data_bit, // points to current bit of incoming data
sync_mode, // flag to signalize if in sync mode
cnt, // auxiliary counter
cnt2, // auxiliary counter
data_ready, // signalizes that interrupt has finished measuring T1 and T2
char_count: byte; // counts received bytes
data_in, // incoming bits are stored here. Can be longint too
data1, // used for measuring T1 and T2
T1, // T1
T2, // T2
T3: word; // T3 = 0xFFFF - T2
tmr1: word; absolute 0x0E; // Here is a little trick how to make tmr1
// to be
// tmr1 = TMR1L or (TMR1H shl 8)
// without doing maths. 0xFCE is the address of
// the TMR1L register (for 16F628)
procedure interrupt;
begin
// This is TIMER1 interrupt
if (PIR1.0 = 1) and (T1CON.0 = 1) then // TMR1IF and TMR1IE should both be set
begin
if sync_mode = false then // do this only if in sync mode
begin
T1CON.0 := 0; // stop TIMER1
data_in := data_in shl 1;// shift data to the left
//***************************************************
if PORTB.0 = 1 then // sample the incoming signal
data_in.0 := 1; // no need to ask for zero, since data_in is initially
// set to zero.
// set the zeroth bit to 1 if input signal is logic high
//***************************************************
inc(data_bit); // increment counter of bits
tmr1 := T3; // preload TIMER1 with T3 = 0xFFFF-T2
T1CON.0 := 1; // start TIMER1
end;
PIR1.0 := 0; // clear TMR1IF
end
// This is RB0 interrupt
else if (INTCON.1 = 1) and (INTCON.4 = 1) then //INT0IF and INTOIE must both be set
begin
if first_edge = true then // only if the first edge is detected
begin
T1CON.0 := 0; // stop TIMER1
data1 := tmr1; // read the value of TIMER1
data_ready := true; // signalize the data is ready
TMR1H := 0; // clear TIMER1 (also tmr1 := 0);
TMR1L := 0;
T1CON.0 := 1; // start TIMER1
end
else
begin
first_edge := true; // the first rising edge is here
TMR1H := 0; // clear TIMER1 (also tmr1 := 0);
TMR1L := 0;
T1CON.0 := 1; // start TIMER1
end;
inc(cnt); // increment measurement count
INTCON.1 := 0; // clear INT0IF
end;
end;
//** main program
begin
Lcd_Init(PORTB); // Initialize LCD on PORTB
Lcd_Cmd(LCD_CLEAR); // clear LCD
// start synchronizing (measure T1 and T2)
sync1:
char_count := 0; // initialize globals
sync_mode := true; // indicate sync mode
data1 := 0; // clear data1
T2 := $FFFF; // initialize T2
cnt := 0; // clear cnt
tmr1 := 0; // clear TIMER1
first_edge := false; // initialize first_edge
data_ready := false; // initialize data_ready
//** setup interrupts
OPTION_REG.6 := 1; // Interrupt on rising edge on RB0
INTCON.1 := 0; // Clear INT0IF
TRISB.0 := 1; // RB0 is input
T1CON.0 := 0; // stop TIMER1
T1CON.5 := 0; // TIMER1 prescaler 1:2
T1CON.4 := 1; // TIMER1 prescaler 1:2
PIR1.0 := 0; // clear TMR1IF
INTCON := $D0; // enable GIE, PEIE and RBIE
cnt2 := 0; // clear sync counter
while true do // infinite loop
begin
if data_ready = true then // wait until interrupt informs us that data is ready
begin
if T2 > data1 then // find the minimum value of T2
T2 := data1;
data_ready := false; // signalize we processed the data
INTCON.4 := 0; // stop INT0
first_edge := false; // initilaize again
inc(cnt2); // increment sync counter
if cnt2 >= 10 then // we detected 10 values of T2, can stop now
begin
T1CON.0 := 0; // stop TIMER1
INTCON.4 := 0; // stop INT0
break; // get out of sync loop
end;
data1 := 0; // clear data
INTCON.1 := 0; // clear INT0IF
INTCON.4 := 1; // start INT0
INTCON.GIE := 1; // enable all interrupts
end;
end;
//** sync ended, get the data.
begin
Lcd_Cmd(lcd_first_row); // put LCD cursor in first row
sync_mode := false; // signalize we are not synchronizing anymore
T1 := T2 shr 1; // calculate times
T3 := $FFFF - T2; // more correct: T3 = 0x0000 - T2
do_sample:
data_bit := 0; // reset bit counter
data_in := 0; // reset incoming data
//** wait for the first rising edge
//** note that if there is no signal on RB0, the program will be stuck here
while portb.0 = 1 do begin end;
while portb.0 = 0 do begin end;
//~ end of wait, the rising edge of input signal has arrived
tmr1 := $FFFF - (T2 shr 2); // move sampling for (T2/4 = T1/2) seconds away from the first edge
T1CON.0 := 1; // start TIMER1
PIE1.0 := 1; // enable TIMER1 interrupt
INTCON.GIE := 1; // enable all interrupts
while true do // infinite loop
begin
if data_bit >= 11 then // 8 bit for data + 3 control bits (1-1-0)
// note that you can change this condition to 16 bits of data
begin
T1CON.0 := 0; // stop TIMER1
PIE1.0 := 0; // disable TIMER1 interrupt while processing data
INTCON.GIE := 0; // disable all interrupts
if Lo((data_in)) = 0x0B then // start marker has arrived
begin
Lcd_Cmd(lcd_first_row); // move to the first row
char_count := 0; // initialize char counter
end
else if Lo(data_in) <> 0x0E then // end marker is not here yet
begin
Lcd_Chr_CP(Lo(data_in)); // display lower byte of data on current cursor position
inc(char_count); // increment counter
if char_count > 40 then // too many chars arrived without error marker
begin
INTCON.GIE := 0; // stop all interrupts, error is detected
goto sync1; // synchronize again
end;
end
else // it must be that data_in is 0x0E <=> end marker => reset char counter
char_count := 0;
goto do_sample; // sample next byte
end;
end;
end;
end. |
I converted this code to be in c language. Did i miss anything here? |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sun Feb 01, 2009 9:54 am |
|
|
The new code doesn't work with CCS C. |
|
|
viknes1985
Joined: 11 Nov 2008 Posts: 24
|
Yes it is |
Posted: Sun Feb 01, 2009 10:07 am |
|
|
Yes I aware that it won't work in CCS. It's different language. Meant to say, i extract the c code from those code. Here, i wish to start over since alot of problems.
Code: | #include <16F877a.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
//The interrupt is automatically called ever 200us.
#INT_TIMER1
void wave_timer() {
set_timer1(0xFC4F); // sets timer to interrupt in 200us
output_bit( PIN_B0, input(PIN_B1) );
}
void main() {
set_tris_b(0x02);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); // setup interrupts
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
while(TRUE); // loop forever
} |
I wanted to sample the signal every 200us from Port B1. But there's no output. Why is't so? |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|