  | 
	  | 
		 
	 
	
		| 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
  
		 |