image.png
资料包括芯片手册、IIC寄存器控制手册、IIC通信例程、PCB demo板PCB文件。除了可以实现基本功能,还可以可以利用单片机模拟IIC通信扩展其他功能。
单片机源程序如下:

#include "CSU32P10.h"
  • //#include "define_data.h"
  • #include "define_function.h"
  • #include "my_define.h"
  • #define SDA PT3_1                           //定义SDA所对应的GPIO接口编号P1.4  
  • #define SCL PT3_0                           //定义SCL所对应的GPIO接口编号P1.5
  • #define SDAEN PT3EN_1                           //定义SDA所对应的GPIO接口编号P1.4  
  • #define SCLEN PT3EN_0                           //定义SCL所对应的GPIO接口编号P1.5
  • #define I2C_ADDR 0x3c
  • #define somenop asm("nop");asm("nop");asm("nop");asm("nop");
  • //#define I2C_ADDR 0x3c
  • unsigned char buf0;
  • unsigned char buf1;
  • unsigned char i2c_step;
  • //短delay
  • /* I2C起始条件 */  
  • void i2c_start()  
  • {  
  •         //初始化GPIO口
  •         SDAEN = 1;                                //设置SDA方向为输出
  •         SCLEN = 1;                                //设置SCL方向为输出
  •         SDA = 1;                //设置SDA为高电平
  •         asm("nop");
  •         SCL = 1;                //设置SCL为高电平   
  •         somenop
  •         somenop
  •         SDA = 0;                //SCL为高电平时,SDA由高变低  
  •         somenop
  •         somenop
  •         somenop
  •         somenop
  •         somenop
  •         somenop
  •         SCL = 0;
  • }  
  • /* I2C终止条件 */  
  • void i2c_stop()  
  • {  
  •         somenop
  •         SDA = 0;      
  •         SDAEN = 1;   
  •         somenop
  •         SCL = 1;
  •         somenop
  •         somenop
  •         somenop
  •         somenop
  •         somenop
  •         somenop
  •         SDA = 1;            //SCL高电平时,SDA由低变高
  •         somenop      
  •         SDAEN = 0;
  • //        SCL = 0;
  • }  
  • /*   
  • I2C读取ACK信号(写数据时使用)  
  • 返回值 :0表示ACK信号有效;非0表示ACK信号无效  
  • */  
  • void i2c_read_ack()  
  • {   
  •         SCL = 0;               // SCL变低
  •         SDAEN = 0;                                 //设置SDA方向为输入
  •         somenop      
  •         SCL = 1;              // SCL变高  
  •         somenop
  •         if(SDA)
  •         {
  •                 i2c_step = 0xff;
  •                 return;
  •         }
  •         SCL = 0;
  •         asm("nop");
  •         asm("nop");
  •         asm("nop");
  •         asm("nop");
  • }  
  • /* I2C发出ACK信号(读数据时使用) */  
  • void i2c_send_ack()  
  • {
  •         SCL = 0;              // SCL变低
  •         somenop
  •         SDA = 1;              //发出ACK信号
  •         SDAEN = 1;              //设置SDA方向为输出      
  •         asm("nop");
  •         asm("nop");
  •         asm("nop");      
  •         SCL = 1;             // SCL变高  
  •         somenop
  •         SCL = 0;
  • //        SDAEN = 1;
  •         asm("nop");
  •         asm("nop");
  • }  
  • /* I2C字节写 */
  • void i2c_resume()
  • {
  •         GIE = 0;
  •         delay_1s();
  •         delay_1s();
  •         i2c_read_ack();
  •         i2c_read_ack();
  •         i2c_read_ack();
  •         i2c_read_ack();
  •         i2c_read_ack();
  •         i2c_read_ack();
  •         i2c_read_ack();
  •         i2c_read_ack();
  •         GIE = 1;
  • }
  • void i2c_write_byte(unsigned char b)  
  • {   
  •         SDAEN = 1;    //设置SDA方向为输出  
  •         SCL = 0;
  •         for (i2c_step = 8; i2c_step > 0; i2c_step --)
  •         {  
  •                 SCL = 0;             // SCL变低
  •                 asm("nop");
  •                 if( b & (1 << (i2c_step - 1)))
  •                         SDA = 1;
  •                 else
  •                         SDA = 0;
  •                 asm("nop");
  •                 SCL = 1;             // SCL变高  
  •                 somenop
  •                 SCL = 0;
  •         }  
  •         i2c_read_ack();
  • }
  • /* I2C字节读 */  
  • void i2c_read_byte()  
  • {   
  •         buf1 = 0;
  •         SDAEN = 0;                                //设置SDA方向为输入
  •         for(i2c_step = 8; i2c_step > 0; i2c_step --)
  •         {  
  •                 SCL = 0;         // SCL变低  
  •                 asm("nop");
  •                 asm("nop");
  •                 SCL = 1;
  •                 //i2c_result = (i2c_result << 1) | SDA;
  •                 buf1 = (buf1 << 1) | SDA;
  •                                                         // SCL变高  
  • //                asm("nop");
  • //                asm("nop");
  •                 SCL = 0;
  •         }
  •         i2c_send_ack();                                                //向目标设备发送ACK信号
  • }  
  • /*  
  • I2C读操作  
  • addr:目标设备地址  
  • buf:读缓冲区  
  • len:读入字节的长度  
  • */  
  • void i2c_read()  
  • {  
  •         i2c_start();                                                        //起始条件,开始数据通信  
  •                                                                         //发送地址和数据读写方向  
  •         i2c_write_byte(I2C_ADDR<<1);        //I2C ADDR
  •         asm("nop");
  •         if(i2c_step == 0xff)
  •         {
  •                 i2c_resume();
  •                 return;
  •         }      
  •         i2c_write_byte(buf0);                        //Reg ADDR
  •         asm("nop");
  •         if(i2c_step == 0xff)
  •         {
  •                 i2c_resume();
  •                 return;
  •         }      
  •         //asm("nop");
  •         i2c_start();//restart
  •         i2c_write_byte((I2C_ADDR<<1) +1);        //Reg ADDR
  •         asm("nop");
  •         if(i2c_step == 0xff)
  •         {
  •                 i2c_resume();
  •                 return;
  •         }
  •         //读入数据  
  •         i2c_read_byte();
  •         i2c_stop();
  •         //终止条件,结束数据通信  
  • }  
  • /*  
  • I2C写操作  
  • addr:目标设备地址  
  • buf:写缓冲区  
  • len:写入字节的长度  
  • */  
  • void i2c_write()  
  • {  
  •         i2c_start();                                                        //起始条件,开始数据通信  
  •         //发送地址和数据读写方向
  •         i2c_write_byte(I2C_ADDR<<1);
  •         asm("nop");
  •         if(i2c_step == 0xff)
  •         {
  •                 i2c_resume();
  •                 return;
  •         }      
  •       
  •         //写入数据
  •         i2c_write_byte(buf0);
  •         asm("nop");
  •         if(i2c_step == 0xff)
  •         {
  •                 i2c_resume();
  •                 return;
  •         }
  •         i2c_write_byte(buf1);
  •         asm("nop");
  •         if(i2c_step == 0xff)
  •         {
  •                 i2c_resume();
  •                 return;
  •         }
  •         i2c_stop();                     //终止条件,结束数据通信  
  • }
  • 复制代码