  | 
	  | 
		 
	 
	
		| View previous topic :: View next topic   | 
	 
	
	
		| Author | 
		Message | 
	 
	
		
			RHA
 
 
  Joined: 25 Apr 2006 Posts: 31 Location: Germany 
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				| Simple RS232 <--> I2C with very small protocol | 
			 
			
				 Posted: Tue Apr 25, 2006 5:07 am     | 
				     | 
			 
			
				
  | 
			 
			
				A simple RS232 <--> I2C Communication with very small protocol :
 
 
Sending 0x00 from PC to Hardware for Connect-Inquiry gets 0x00 as an answer from the hardware.
 
 
Then the first byte high-nibble are the number of bytes to send to I2C and the low-nibble are the numer of bytes to receive from I2C (leave 0 if not needed).
 
 
The next bytes are the bytes which would be sended  to I2C.
 
 
If all Data is collected the hardware sends a 0xe0 to the PC for confirmation.
 
 
At next the hardware sends/receives data to/from I2C and puts the received data to the RS232.
 
 
After all the hardware sends a 0xee to the PC.
 
 
 
Itīs a simple way to test some I2C-Hardware.
 
 
 
Greets
 
RHA
 
 
 
 
 	  | Code: | 	 		  
 
#include   <16F876.h>
 
#define      CLOCK_SPEED   8000000                  //   Hz
 
#use         delay(clock=CLOCK_SPEED, RESTART_WDT)
 
 
#fuses      HS,WDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP,NOCPD,NOWRT
 
#zero_ram
 
 
 
#byte   TMR0      =   0x01
 
#byte   PCL      =   0x02
 
#byte   STATUS   =   0x03
 
#byte   FSR      =   0x04
 
#byte   PortA      =   0x05
 
#byte   PortB      =   0x06
 
#byte   PortC      =   0x07
 
 
#bit   STAT_C   =   STATUS.0
 
 
 
//***************************************************************************************************************************
 
//***************************************************************************************************************************
 
//#bit         =   PortA.0                        //
 
//#bit         =   PortA.1                        //
 
//#bit         =   PortA.2                        //
 
//#bit         =   PortA.3                        //
 
//#bit         =   PortA.4                        //
 
//#bit         =   PortA.5                        //
 
 
#define   TrisA_Ini   0b11111111                  //   PortA Input/Output
 
#define   PortA_Ini   0b00000000                  //   PortA Output Init
 
//-----------------------------------------------------------------------------------
 
//#bit         =   PortB.0                        //
 
//#bit         =   PortB.1                        //
 
//#bit         =   PortB.2                        //
 
//#bit         =   PortB.3                        //
 
//#bit         =   PortB.4                        //
 
//#bit         =   PortB.5                        //
 
//#bit   PGC   =   PortB.6                        //
 
//#bit   PGD   =   PortB.7                        //
 
 
#define   TrisB_Ini   0b11111111                  //   PortB Input/Output
 
#define   PortB_Ini   0b00000000                  //   PortC Output Init
 
//-----------------------------------------------------------------------------------
 
//#bit         =   PortC.0                        //
 
//#bit         =   PortC.1                        //
 
//#bit         =   PortC.2                        //
 
//#bit   SCL   =   PortB.3                        //
 
//#bit   SDA   =   PortB.4                        //
 
//#bit         =   PortB.5                        //
 
//#bit   TX      =   PortC.6                        //
 
//#bit   RX      =   PortC.7                        //
 
 
#define   TrisC_Ini   0b11111111                  //   PortC Input/Output
 
#define   PortC_Ini   0b00000000                  //   PortC Output Init
 
//-----------------------------------------------------------------------------------
 
//      Variables for generate basic timers       //
 
 
int      Pre_01ms;                              //   Prescaler   1ms
 
int      Pre_50ms;                              //   Prescaler  50ms
 
int      Pre_01s;                                 //   Prescaler   1s
 
 
short      CLK_01ms;                              //   1ms ready
 
 
#define   Time_RTCC   0xc8                        //   RTCC     200us   (0.0002 / (((1 / 8MHz) * 4) * 2))
 
#define   Time_01ms   0x05                        //   Prescaler   1ms   (  5*Time_RTCC)
 
#define   Time_50ms   0x32                        //   Prescaler  50ms   ( 50*Time_01ms)
 
#define   Time_01s      0x14                        //   Prescaler   1s   ( 20*Time_50ms)
 
 
//-----------------------------------------------------------------------------------
 
//      Variables for the RS232-Connection        //
 
 
int      RS232_Rx;                              //   Inputbyte
 
int      RS232_Tx[15];                           //   Outputbytes
 
int      RS232_TxCount;                           //   Counter for Outputbytes
 
 
//-----------------------------------------------------------------------------------
 
//      Variablen für die RS232-Schnittstelle      //
 
 
int      I2C_Rx;                                 //   Inputbyte
 
int      I2C_RxCount;                           //   Counter for Inputbytes
 
int      I2C_Tx[5];                              //   Outputbytes
 
int      I2C_TxCount;                           //   Counter for Outputbytes
 
int      I2C_TxPtr;                              //   Pointer for Outputbytes
 
 
//-----------------------------------------------------------------------------------
 
 
#use   rs232   (baud=9600,xmit=PIN_C6,rcv=PIN_C7, RESTART_WDT)
 
#use   i2c      (master,slow,sda=PIN_C4,scl=PIN_C3,force_HW,RESTART_WDT)
 
 
//***************************************************************************************************************************
 
//***************************************************************************************************************************
 
#int_rtcc                                       //   Serviceroutine for RTCC
 
rtcc_isr() {
 
 
   TMR0      =   TMR0 - Time_RTCC;                  //   Restart Counter (Overflow would be considered)
 
 
   if   (!--Pre_01ms) {                           //   1ms ready ?
 
      CLK_01ms = True;                           //     Yes  -->   Set Indicator
 
      Pre_01ms = Time_01ms;                     //            Reset Prescaler
 
   }
 
}
 
 
 
//***************************************************************************************************************************
 
//***************************************************************************************************************************
 
void   send_RS232(int Tx_Byte) {                  //   Send a Byte over RS232
 
 
   if (RS232_TxCount < 15) {                     //   Another free byte in buffer ?
 
      RS232_Tx[RS232_TxCount]   =   Tx_Byte;         //   Write byte in buffer
 
      ++RS232_TxCount;                           //   Increment Buffer-Counter
 
      enable_interrupts(INT_TBE);               //   Enable RS232-Transmit
 
   }
 
}
 
 
 
//***************************************************************************************************************************
 
//***************************************************************************************************************************
 
void   I2C_TxRx() {                              //   Send/Receive at I2C
 
 
   if   (I2C_TxCount && (I2C_TxCount == I2C_TxPtr)) {   //   Data for sending collected?
 
 
      send_RS232(0xe0);                           //   Send confirmation on RS232
 
 
      I2C_TxPtr   =   0;                           //   Reset pointer from I2C-Sendingbuffer
 
 
      i2c_start();                              //   Start I2C-Communication
 
 
      while   (I2C_TxCount) {                     //   Send data on I2C-Bus
 
         i2c_write(I2C_Tx[I2C_TxPtr]);            //
 
         --I2C_TxCount;                           //
 
         ++I2C_TxPtr;                           //
 
      }
 
 
      while   (I2C_RxCount) {                     //   Receive data from I2C-Bus
 
         I2C_Rx   =   i2c_read();                  //
 
         send_RS232(I2C_Rx);                     //
 
         --I2C_RxCount;                           //
 
      }
 
 
      i2c_stop();                                 //   Stop I2C-Communication
 
 
      I2C_TxPtr   =   0;                           //   Reset pointer from I2C-Receivebuffer
 
 
      send_RS232(0xee);                           //   Send End-Code on RS232
 
   }
 
}
 
 
 
//***************************************************************************************************************************
 
//***************************************************************************************************************************
 
#int_rda                                          //   Serviceroutine for RS232 Receive
 
rda_isr() {
 
 
   RS232_Rx   =   getc();                           //  Read-Out received byte
 
 
   if   (!I2C_TxCount) {                           //   Starting protocol (first byte) ?
 
 
      if   (RS232_Rx == 0x00) {                     //  Connect-Inquiry ?
 
         send_RS232(0x00);                        //    Yes  --> Answer
 
      }
 
      else {                                    //     No   --> Load counter for protocol
 
         I2C_RxCount   =   RS232_Rx & 0x0f   ;      //              (Receive-Counter)
 
         I2C_TxCount   =   swap(RS232_Rx) & 0x0f;   //              (Send-Counter)
 
      }
 
   }
 
   else {                                       //   Collect I2C-Sendingdata ?
 
 
      I2C_Tx[I2C_TxPtr]   =   RS232_Rx;            //   Put received byte in I2C-Sendingbuffer
 
      ++I2C_TxPtr;                              //   Increment pointer on I2C-Sendingbuffer
 
   }
 
}
 
 
 
//***************************************************************************************************************************
 
//***************************************************************************************************************************
 
#int_tbe                                          //   Serviceroutine for RS232 Transmit
 
tbe_isr() {
 
 
   if   (RS232_TxCount != 0) {                     //  Another Byte ?
 
 
      putc(RS232_Tx[0]);                        //  Send first byte in buffer
 
      --RS232_TxCount;                           //   Decrement counter
 
      memcpy(RS232_Tx,RS232_Tx+1,14);            //   Shift buffer
 
   }
 
   else {                                       //   Last byte transmitted ?
 
      disable_interrupts(INT_TBE);               //   Disable RS232-Transmit
 
   }
 
}
 
 
 
//***************************************************************************************************************************
 
//***************************************************************************************************************************
 
void   timer() {                                 //   Softwaretimer
 
 
   if   (CLK_01ms) {                              //   1ms ready ?
 
 
      CLK_01ms   =   False;                        //   Reset statusbit
 
 
      if   (!--Pre_50ms) {                        //   Decrement Counter for 50ms
 
         Pre_50ms   =   Time_50ms;                  //   Reset Counter
 
 
         if   (!--Pre_01s) {                        //   Decrement Counter for 1s
 
            Pre_01s   =   Time_01s;               //   Reset Counter
 
 
         }
 
      }
 
   }
 
}
 
 
 
//***************************************************************************************************************************
 
//***************************************************************************************************************************
 
void   init() {                                    //   Initialisation
 
 
   PortA   =   PortA_Ini;                           //   Preset Outputs
 
   PortB   =   PortB_Ini;                           //
 
   PortC   =   PortC_Ini;                           //
 
 
   set_tris_a   (TrisA_Ini);                     //   Set Inputs/Outputs
 
   set_tris_b   (TrisB_Ini);                     //
 
   set_tris_c   (TrisC_Ini);                     //
 
 
   port_b_pullups(TRUE);                        //   Switch on PortB - Pullups
 
 
   setup_adc_ports(NO_ANALOGS);                  //   No Analoginputs
 
   setup_adc(ADC_CLOCK_DIV_2);                  //
 
 
   Pre_01ms = Time_01ms;                        //   Preset Prescaler
 
   Pre_50ms = Time_50ms;                        //
 
   Pre_01s    = Time_01s;                        //
 
 
//   setup_ccp1(CCP_PWM);                           //   Setup PWM
 
//   set_pwm1_duty(MOT_DISABLE);                  //
 
//   out_PWM   =   MOT_DISABLE;                     //
 
 
//   setup_timer_3(T3_DISABLED);                  //   Timer3 (not needed)
 
   setup_timer_2(T2_DISABLED,0,1);               //   Timer2 (not needed)
 
   setup_timer_1(T1_DISABLED);                  //   Timer1 (not needed)
 
   setup_counters(RTCC_INTERNAL,RTCC_DIV_2);      //   Timer0 for RTCC
 
 
   set_rtcc(-Time_RTCC);                        //   Set RTCC-Initialvalue
 
 
   enable_interrupts(INT_RTCC);                  //   Enable RTCC-Interrupt
 
   enable_interrupts(INT_RDA);                  //   Enable RS232-Receive
 
   enable_interrupts(GLOBAL);                     //   Enable Interrupts global
 
}
 
 
 
//***************************************************************************************************************************
 
//***************************************************************************************************************************
 
void   main() {                                    //   Main loop
 
 
   init();                                       //   Initialise Program
 
 
   while(true) {
 
      restart_WDT();                              //   Reset Watchdog
 
 
      timer();                                    //   Softwaretimer
 
      I2C_TxRx();                               //  Send/Receive on I2C
 
 
   }
 
}
 
 | 	 
  | 
			 
		  | 
	 
	
		  | 
	 
	
		
			kender
 
 
  Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley 
			
			 
			 
			 
			 
			
			 
			
			
			
  
		  | 
		 | 
	 
	
		  | 
	 
	
		
			RHA
 
 
  Joined: 25 Apr 2006 Posts: 31 Location: Germany 
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Tue Apr 25, 2006 2:43 pm     | 
				     | 
			 
			
				
  | 
			 
			
				Pretty cool,
 
 
but i think for most persons itīs easier to work with a standard terminal program and a RS232 connection then with the parallel port.
 
 
 
ciao
 
RHA | 
			 
		  | 
	 
	
		  | 
	 
	
		 | 
	 
 
  
	 
	    
	   | 
	
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
  
		 |