📄 i2cmsu.c
字号:
#ifndef I2CMSU_C#define I2CMSU_C/* I2C lib R. Reese MSU July 2003 Delay routines are from samples provided with PICC subroutines */#include "i2cmsu.h"#include "delay.h"#define bitset(var,bitno) ((var) |= (1 << (bitno)))#define bitclr(var,bitno) ((var) &= ~(1 << (bitno)))#define bittst(var,bitno) (var & (1 << (bitno)))#define I2C_IDLE_ERR 1#define I2C_START_ERR 2#define I2C_RSTART_ERR 3#define I2C_STOP_ERR 4#define I2C_GET_ERR 5#define I2C_PUT_ERR 6#define I2C_MISSACK_ERR 7#define I2C_ACK_ERR 8#define I2C_NAK_ERR 9// error variable for acknowledge#if defined(HI_TECH_C)persistent char i2c_errstat;#endif #if defined(__18CXX)//assume MCC18 linking with startup code that only//does explicit variable initializationchar i2c_errstat;#endifvoid i2c_init(char bitrate){ // enable I2C Master Mode SSPM3 = 1; SSPM2 = 0;SSPM1 = 0; SSPM0 = 0; SSPADD = bitrate; // set bus clk SSPEN = 1; bitset(TRISC,3); bitset(TRISC,4); // SDA, SCL pins are inputs SSPIF = 0; // clear SPIF bit i2c_errstat = 0; // clear error status}void i2c_idle(void){ // wait for idle condition unsigned char byte1; unsigned char byte2; CLRWDT(); i2c_errstat = I2C_IDLE_ERR; do { // byte1 has R/W bit. byte1 = SSPSTAT & 0x04; byte2 = SSPCON2 & 0x1F; }while (byte1 | byte2); CLRWDT(); i2c_errstat = 0; return;}void i2c_start(void){ i2c_idle(); i2c_errstat = I2C_START_ERR; SEN = 1; // initiate start // wait until start finished while (SEN); CLRWDT(); i2c_errstat = 0;}void i2c_rstart(void){// repeated start i2c_idle(); i2c_errstat = I2C_RSTART_ERR; RSEN = 1; // initiate start // wait until start finished while (RSEN); CLRWDT(); i2c_errstat = 0;}void i2c_stop(void) { i2c_idle(); i2c_errstat = I2C_STOP_ERR; PEN=1; // initiate stop, PEN=1 //wait until stop finished while (PEN); CLRWDT(); i2c_errstat = 0;}unsigned char i2c_put(unsigned char byte ) { i2c_errstat = I2C_PUT_ERR; SSPIF = 0; //clear interrupt flag SSPBUF = byte; // write byte while(!SSPIF); // wait for finish an ack i2c_errstat = 0; CLRWDT(); if (ACKSTAT) { //no acknowledge returned, so reset i2c_errstat = I2C_MISSACK_ERR; RESET(); //asm("reset") } return(0); }unsigned char i2c_put_noerr(unsigned char byte ) { i2c_errstat = I2C_PUT_ERR; SSPIF = 0; //clear interrupt flag SSPBUF = byte; // write byte while(!SSPIF); // wait for finish an ack i2c_errstat = 0; CLRWDT(); if (ACKSTAT) return(1); return(0); }unsigned char i2c_putbyte(unsigned char byte) { i2c_idle(); return(i2c_put(byte));}void i2c_ack(unsigned char ackbit){ // send acknowledge CLRWDT(); ACKDT = ackbit; if (ackbit) i2c_errstat = I2C_NAK_ERR; else i2c_errstat = I2C_ACK_ERR; //initiate acknowlege cycle ACKEN = 1; // wait until acknowledge cycle finished while(ACKEN); CLRWDT(); i2c_errstat = 0;}unsigned char i2c_get(unsigned char ackbit) { unsigned char byte; i2c_errstat = I2C_GET_ERR; RCEN = 1; //initiate read event while(RCEN); // wait until finished CLRWDT(); while (!BF); //also check buffer full CLRWDT(); byte = SSPBUF; // read data i2c_errstat = 0; i2c_ack(ackbit); return(byte);}unsigned char i2c_getbyte(unsigned char ackbit) { i2c_idle(); return(i2c_get(ackbit));}void i2c_print_err(void){ pcrlf(); printf((char * const)"I2C bus error is "); switch (i2c_errstat) { case 0: printf((char * const)"None");break; case I2C_IDLE_ERR : printf((char * const)"Idle");break; case I2C_START_ERR : printf((char * const)"Start");break; case I2C_STOP_ERR : printf((char * const)"Stop");break; case I2C_GET_ERR : printf((char * const)"Get");break; case I2C_PUT_ERR : printf((char * const)"Put");break; case I2C_MISSACK_ERR : printf((char * const)"Missing Ack");break; case I2C_ACK_ERR : printf((char * const)"Ack");break; case I2C_NAK_ERR : printf((char * const)"Nak");break; default: printf((char * const)"Unknown"); } pcrlf();}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -