CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Read Manchester.... Where's the Problem?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
viknes1985



Joined: 11 Nov 2008
Posts: 24

View user's profile Send private message Send e-mail Yahoo Messenger MSN Messenger

Read Manchester.... Where's the Problem?
PostPosted: Sun Feb 01, 2009 3:33 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Feb 01, 2009 4:00 am     Reply with quote

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

View user's profile Send private message Send e-mail Yahoo Messenger MSN Messenger

Interrupter
PostPosted: Sun Feb 01, 2009 4:46 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Feb 01, 2009 9:54 am     Reply with quote

The new code doesn't work with CCS C.
viknes1985



Joined: 11 Nov 2008
Posts: 24

View user's profile Send private message Send e-mail Yahoo Messenger MSN Messenger

Yes it is
PostPosted: Sun Feb 01, 2009 10:07 am     Reply with quote

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?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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