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

  1. #include "CSU32P10.h"
  2. //#include "define_data.h"
  3. #include "define_function.h"
  4. #include "my_define.h"
  5. #define SDA PT3_1                           //定义SDA所对应的GPIO接口编号P1.4  
  6. #define SCL PT3_0                           //定义SCL所对应的GPIO接口编号P1.5
  7. #define SDAEN PT3EN_1                           //定义SDA所对应的GPIO接口编号P1.4  
  8. #define SCLEN PT3EN_0                           //定义SCL所对应的GPIO接口编号P1.5
  9. #define I2C_ADDR 0x3c
  10. #define somenop asm("nop");asm("nop");asm("nop");asm("nop");
  11. //#define I2C_ADDR 0x3c
  12. unsigned char buf0;
  13. unsigned char buf1;
  14. unsigned char i2c_step;
  15. //短delay
  16. /* I2C起始条件 */  
  17. void i2c_start()  
  18. {  
  19.         //初始化GPIO口
  20.         SDAEN = 1;                                //设置SDA方向为输出
  21.         SCLEN = 1;                                //设置SCL方向为输出
  22.         SDA = 1;                //设置SDA为高电平
  23.         asm("nop");
  24.         SCL = 1;                //设置SCL为高电平   
  25.         somenop
  26.         somenop
  27.         SDA = 0;                //SCL为高电平时,SDA由高变低  
  28.         somenop
  29.         somenop
  30.         somenop
  31.         somenop
  32.         somenop
  33.         somenop
  34.         SCL = 0;
  35. }  
  36. /* I2C终止条件 */  
  37. void i2c_stop()  
  38. {  
  39.         somenop
  40.         SDA = 0;      
  41.         SDAEN = 1;   
  42.         somenop
  43.         SCL = 1;
  44.         somenop
  45.         somenop
  46.         somenop
  47.         somenop
  48.         somenop
  49.         somenop
  50.         SDA = 1;            //SCL高电平时,SDA由低变高
  51.         somenop      
  52.         SDAEN = 0;
  53. //        SCL = 0;
  54. }  
  55. /*   
  56. I2C读取ACK信号(写数据时使用)  
  57. 返回值 :0表示ACK信号有效;非0表示ACK信号无效  
  58. */  
  59. void i2c_read_ack()  
  60. {   
  61.         SCL = 0;               // SCL变低
  62.         SDAEN = 0;                                 //设置SDA方向为输入
  63.         somenop      
  64.         SCL = 1;              // SCL变高  
  65.         somenop
  66.         if(SDA)
  67.         {
  68.                 i2c_step = 0xff;
  69.                 return;
  70.         }
  71.         SCL = 0;
  72.         asm("nop");
  73.         asm("nop");
  74.         asm("nop");
  75.         asm("nop");
  76. }  
  77. /* I2C发出ACK信号(读数据时使用) */  
  78. void i2c_send_ack()  
  79. {
  80.         SCL = 0;              // SCL变低
  81.         somenop
  82.         SDA = 1;              //发出ACK信号
  83.         SDAEN = 1;              //设置SDA方向为输出      
  84.         asm("nop");
  85.         asm("nop");
  86.         asm("nop");      
  87.         SCL = 1;             // SCL变高  
  88.         somenop
  89.         SCL = 0;
  90. //        SDAEN = 1;
  91.         asm("nop");
  92.         asm("nop");
  93. }  
  94. /* I2C字节写 */
  95. void i2c_resume()
  96. {
  97.         GIE = 0;
  98.         delay_1s();
  99.         delay_1s();
  100.         i2c_read_ack();
  101.         i2c_read_ack();
  102.         i2c_read_ack();
  103.         i2c_read_ack();
  104.         i2c_read_ack();
  105.         i2c_read_ack();
  106.         i2c_read_ack();
  107.         i2c_read_ack();
  108.         GIE = 1;
  109. }
  110. void i2c_write_byte(unsigned char b)  
  111. {   
  112.         SDAEN = 1;    //设置SDA方向为输出  
  113.         SCL = 0;
  114.         for (i2c_step = 8; i2c_step > 0; i2c_step --)
  115.         {  
  116.                 SCL = 0;             // SCL变低
  117.                 asm("nop");
  118.                 if( b & (1 << (i2c_step - 1)))
  119.                         SDA = 1;
  120.                 else
  121.                         SDA = 0;
  122.                 asm("nop");
  123.                 SCL = 1;             // SCL变高  
  124.                 somenop
  125.                 SCL = 0;
  126.         }  
  127.         i2c_read_ack();
  128. }
  129. /* I2C字节读 */  
  130. void i2c_read_byte()  
  131. {   
  132.         buf1 = 0;
  133.         SDAEN = 0;                                //设置SDA方向为输入
  134.         for(i2c_step = 8; i2c_step > 0; i2c_step --)
  135.         {  
  136.                 SCL = 0;         // SCL变低  
  137.                 asm("nop");
  138.                 asm("nop");
  139.                 SCL = 1;
  140.                 //i2c_result = (i2c_result << 1) | SDA;
  141.                 buf1 = (buf1 << 1) | SDA;
  142.                                                         // SCL变高  
  143. //                asm("nop");
  144. //                asm("nop");
  145.                 SCL = 0;
  146.         }
  147.         i2c_send_ack();                                                //向目标设备发送ACK信号
  148. }  
  149. /*  
  150. I2C读操作  
  151. addr:目标设备地址  
  152. buf:读缓冲区  
  153. len:读入字节的长度  
  154. */  
  155. void i2c_read()  
  156. {  
  157.         i2c_start();                                                        //起始条件,开始数据通信  
  158.                                                                         //发送地址和数据读写方向  
  159.         i2c_write_byte(I2C_ADDR<<1);        //I2C ADDR
  160.         asm("nop");
  161.         if(i2c_step == 0xff)
  162.         {
  163.                 i2c_resume();
  164.                 return;
  165.         }      
  166.         i2c_write_byte(buf0);                        //Reg ADDR
  167.         asm("nop");
  168.         if(i2c_step == 0xff)
  169.         {
  170.                 i2c_resume();
  171.                 return;
  172.         }      
  173.         //asm("nop");
  174.         i2c_start();//restart
  175.         i2c_write_byte((I2C_ADDR<<1) +1);        //Reg ADDR
  176.         asm("nop");
  177.         if(i2c_step == 0xff)
  178.         {
  179.                 i2c_resume();
  180.                 return;
  181.         }
  182.         //读入数据  
  183.         i2c_read_byte();
  184.         i2c_stop();
  185.         //终止条件,结束数据通信  
  186. }  
  187. /*  
  188. I2C写操作  
  189. addr:目标设备地址  
  190. buf:写缓冲区  
  191. len:写入字节的长度  
  192. */  
  193. void i2c_write()  
  194. {  
  195.         i2c_start();                                                        //起始条件,开始数据通信  
  196.         //发送地址和数据读写方向
  197.         i2c_write_byte(I2C_ADDR<<1);
  198.         asm("nop");
  199.         if(i2c_step == 0xff)
  200.         {
  201.                 i2c_resume();
  202.                 return;
  203.         }      
  204.       
  205.         //写入数据
  206.         i2c_write_byte(buf0);
  207.         asm("nop");
  208.         if(i2c_step == 0xff)
  209.         {
  210.                 i2c_resume();
  211.                 return;
  212.         }
  213.         i2c_write_byte(buf1);
  214.         asm("nop");
  215.         if(i2c_step == 0xff)
  216.         {
  217.                 i2c_resume();
  218.                 return;
  219.         }
  220.         i2c_stop();                     //终止条件,结束数据通信  
  221. }