//************************************************ //主应答(包含ack:SDA=0和no_ack:SDA=0) void IIC_ack_main(unsigned char ack_main){ SCL0(); if(ack_main) SDA0(); //ack主应答 else SDA1(); //no_ack无需应答 iicdelay(); SCL1(); iicdelay(); SCL0(); }
//nop指令个数定义 //#define iicdelay() {asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");} void IIC_start(void){ SCL0(); SDA1(); iicdelay(); SCL1(); iicdelay(); SDA0(); iicdelay(); SCL0(); }
static uint8_t i2c_soft_receive_bit(void) { // SDA = 1 // SCL = 1 // wait SCL low // bit = SDA // SCL = 0 uint8_t bit; SDA(1); waitSomeTimeInUs(1); SCL1(); waitSomeTimeInUs(1); while( GET_SCL() == 0); bit = GET_SDA(); SCL0(); SDA_OUTPUT(); waitSomeTimeInUs(1); return bit; }
//************************************************* //字节发送程序 //发送c(可以是数据也可是地址),送完后接收从应答 //不考虑从应答位 void send_ch(unsigned char c){ unsigned char i; for(i=0;i<8;i++){ SCL0(); if((c<<i) & 0x80)SDA1(); //判断发送位 else SDA0(); iicdelay(); SCL1(); iicdelay(); SCL0(); } iicdelay(); SDA1(); //发送完8bit,释放总线准备接收应答位 iicdelay(); SCL1(); iicdelay(); //sda上数据即是从应答位 SCL0(); //不考虑从应答位|但要控制好时序 }
//************************************************** //字节接收程序 //接收器件传来的数据,此程序应配合|主应答函数|IIC_ack_main()使用 //return: uchar型1字节 unsigned char read_ch(void) { unsigned char i; unsigned char c; c=0; SCL0(); iicdelay(); SDA1(); //置数据线为输入方式 DIR_IN(); for(i=0;i<8;i++){ iicdelay(); SCL0(); //置时钟线为低,准备接收数据位 iicdelay(); SCL1(); //置时钟线为高,使数据线上数据有效 iicdelay(); c<<=1; if(SDA) c+=1; //读数据位,将接收的数据存c } SCL0(); DIR_OUT(); return c; }
static void i2c_soft_send_bit(uint8_t bit) { // set bit on SDA // NOP // SCL = 1 // wait SCL low // then SCL = 0 SDA((bit&0x1)); waitSomeTimeInUs(1); SCL1(); waitSomeTimeInUs(2); SCL0(); waitSomeTimeInUs(1); }
static void i2c_soft_start(void) { SDA(0); SCL0(); waitSomeTimeInUs(1); }