⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c.h

📁 I2C driver for PIC, PICC compiler - bitbanged. Needs pull-up resistor on SCK and SDA and ports set f
💻 H
字号:
/* I2C.H

  Implements shared buffer via I2C

  Wrapper (ex.):
  #define i2cbuflen 20
  #define i2c_addr 0xF0

  setup_i2c(); enable_interrupts(INT_SSP);

*/

// ------------ I2C Variables --------------------

#DEFINE __I2C__

#use i2c(slave,sda=PIN_C4,scl=PIN_C3,address=i2c_addr,NOFORCE_SW)

typedef enum {NOTHING, CONTROL_READ,
              ADDRESS_READ, READ_COMMAND_READ} I2C_STATE;

// I2C buffer is safe when fstate is NOTHING (at least)
#define wait_safe_i2c() while (fstate!=NOTHING) {} ;

I2C_STATE fState;        // State of I2C communication
byte i2cadr;             // I2c address and index in buffer

#IFNDEF exti2cbuf
byte i2cbuf[i2cbuflen];  // i2c buffer
#ENDIF

char* i2cidx;            // i2c driver internal buffer to idx

int16 i2cscllow;   // Count of i2c clock low - to avoid stuck i2c - call scl_stuck() in main loop.

#byte SSPCON  = 0x14
#byte SSPCON2 = 0x91
#byte SSPSTAT = 0x94

// Bits interesting for interrupt routine
#define i2c_rd     bit_test(SSPSTAT,2) /* Set when read operation */
#define i2c_s 	   bit_test(SSPSTAT,3) /* Set when s received last */
#define i2c_p 	   bit_test(SSPSTAT,4) /* Set when p received last */
#define i2c_ckp    bit_test(SSPCON,4)  /* reset when hw holds clk low */
#define i2c_data   bit_test(SSPSTAT,5) /* Set when data (not address) operation */



#int_ssp
ssp_isr() {
   char incoming;

   i2cscllow=0; // Something received, scl did something, do not time out.
   if (!i2c_poll()) { //i2c_poll() returns false on  rw=1, read
	if (i2c_ckp) fstate=NOTHING; else { i2c_write(*(i2cidx++)); fstate=ADDRESS_READ; }; // NAK - end or read more
   } else {
     incoming=i2c_read(); if (!i2c_data) fstate=NOTHING; // Here an address (write) was read.
     if (fState == ADDRESS_READ) { *(i2cidx++) = incoming; return; } 		                 // More data to store
     if (fState == NOTHING     ) { i2cadr=incoming; fState = CONTROL_READ; return; }            // The address of the PIC was read.
     if (fState == CONTROL_READ) { i2cidx=&i2cbuf[0]+incoming; fState = ADDRESS_READ; return; } // Address to buffer in i2cidx
   }
}


void setup_i2c() { // Initialize the I2c bus.
   fState = NOTHING;
   memset(i2cbuf,0,sizeof(i2cbuf));    // Start all zero
   i2cscllow=0;
}

int16 scl_stuck() { // returns number of calls of itself with scl found low and no chars received
      if (input(PIN_C3)) i2cscllow=0; else i2cscllow++; // Poll I2c to see if stuck
      return i2cscllow;
}


void i2c_flush() { // Clears the i2c input buffer. Should be called before mainloop to prevent stuck interrupts.
   if (i2c_poll()) i2c_read();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -