注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
Justice_Gao的个人空间 https://home.eeworld.com.cn/space-uid-784175.html [收藏] [复制] [分享] [RSS]
日志

【GD32F350开发分享七】GPIO模拟I2C驱动

已有 2276 次阅读2018-10-9 19:58 |个人分类:GD32系列学习

我的作品没有用到I2C,有空的时候改了一下,仅供大家才考一下

  1. #include "I2C.h"

  2. #define SDA_HIGH  gpio_bit_set(GPIOC, GPIO_PIN_13)  
  3. #define SDA_LOW  gpio_bit_reset(GPIOC, GPIO_PIN_13)   

  4. #define SCL_HIGH  gpio_bit_set(GPIOC, GPIO_PIN_10)  
  5. #define SCL_LOW  gpio_bit_reset(GPIOC, GPIO_PIN_10)  

  6. #define RESET_HIGH  gpio_bit_set(GPIOC, GPIO_PIN_11)  
  7. #define RESET_LOW  gpio_bit_reset(GPIOC, GPIO_PIN_11)  

  8. #define POWERDOWN_HIGH  gpio_bit_set(GPIOC, GPIO_PIN_12)  
  9. #define POWERDOWN_LOW  gpio_bit_reset(GPIOC, GPIO_PIN_12)

  10. //在开漏输出模式下,对端口输入状态寄存器的读访问将返回I/O的状态,因此 不需要为了读取数据,专门将I/0由输出设为输入
  11. #define  SDA_READ           gpio_input_bit_get(GPIOC, GPIO_PIN_13)


  12. void I2C_delay(void)                        
  13. {
  14.     uint32_t t=300*13.5;                     
  15.    
  16.          while(t--);
  17.        
  18. }

  19. void nops1ms(void) //1ms
  20. {
  21.     uint32_t t=8000*13.5;   
  22.           while(t--);
  23. }

  24. void delay_50ms(void) //50ms
  25. {
  26.   uint t=50;   
  27.         for(t=0;t<50;t++)
  28.         nops1ms();
  29. }


  30. void init_camera(void)
  31. {  
  32.          uint i;
  33.          RESET_LOW;
  34.          POWERDOWN_HIGH;
  35.          for(i=0;i<10;i++)
  36.          nops1ms();
  37.          POWERDOWN_LOW;            
  38.          for(i=0;i<10;i++)
  39.          nops1ms();
  40.          RESET_HIGH;
  41. }

  42. void I2C_Initializes(void)
  43. {
  44.   I2C_GPIO_Configuration();
  45.         init_camera();
  46.         delay_50ms();
  47.   SCL_HIGH;                                 
  48.   SDA_HIGH;
  49.         nops1ms();
  50. }

  51. void Delay(void)                        
  52. {                                       
  53.    nops1ms();
  54.    nops1ms();
  55. }

  56. int I2C_Start(void)
  57. {
  58.        
  59.         SDA_HIGH;
  60.         SCL_HIGH;//高电平有效
  61.         I2C_delay();//延时
  62.         if(!SDA_READ)
  63.         {
  64.                 return DISABLE;//SDA总线忙,退出
  65.         }
  66.         SDA_LOW;
  67.         I2C_delay();
  68.         //查看此时SDA已经变为低电平
  69.         if(SDA_READ)
  70.                 return DISABLE;//SDA总线忙,退出
  71.         }
  72.         SCL_LOW;
  73.         return ENABLE;
  74. }

  75. void I2C_Stop(void)
  76. {
  77.        
  78.         SCL_LOW;
  79.         //制造一个上升沿,上升沿是结束的标志
  80.         SDA_LOW;       
  81.         SCL_HIGH;//高电平有效
  82.         I2C_delay();//延时
  83.         SDA_HIGH;
  84.         I2C_delay();
  85. }

  86. void I2C_Ack()
  87. {
  88.         SCL_LOW;
  89.         SDA_LOW;//置低
  90.         I2C_delay();   //注意延时时间应该大于4微秒,其他位置也是如此
  91.         SCL_HIGH;
  92.         I2C_delay();
  93.         SCL_LOW;
  94. }

  95. void I2C_NoAck()
  96. {
  97.         SCL_LOW;
  98.         I2C_delay();
  99.         SDA_HIGH;//置高
  100.         I2C_delay();
  101.         SCL_HIGH;
  102.         I2C_delay();
  103.         SCL_LOW;
  104. }

  105. uint8_t I2C_GetAck(void)
  106. {
  107.   uint8_t time = 0;
  108.        
  109.         SDA_HIGH;
  110.         I2C_delay();
  111.         SCL_HIGH;
  112.         I2C_delay();
  113.         while(SDA_READ)
  114.         {
  115.                 time++;
  116.                 if(time > 250)
  117.                 {
  118.                        
  119.                         SCL_LOW;
  120.                         return DISABLE;
  121.                 }
  122.         }
  123.         SCL_LOW;
  124.         return ENABLE;
  125. }

  126. //I2C写一个字节
  127. void I2C_SendByte(uint8_t Data)
  128. {
  129.   uint8_t cnt;

  130.   for(cnt=0; cnt<8; cnt++)
  131.   {
  132.     SCL_LOW;                                 //SCL低(SCL低时,变化SDA)
  133.     I2C_delay();

  134.     if(Data & 0x80)
  135.     {
  136.       SDA_HIGH;                              //SDA高,从最低位开始写起
  137.     }
  138.     else
  139.     {
  140.       SDA_LOW;                               //SDA低
  141.     }
  142.     Data <<= 1;
  143.     SCL_HIGH;                                //SCL高(发送数据)
  144.     I2C_delay();
  145.   }
  146.   SCL_LOW;                                   //SCL低(等待应答信号)
  147.   I2C_delay();
  148. }

  149. //I2C读取一个字节
  150. uint8_t I2C_ReadByte(uint8_t ack)
  151. {
  152.   uint8_t cnt;
  153.   uint8_t data;
  154.        
  155.   for(cnt=0; cnt<8; cnt++)
  156.   {
  157.     SCL_LOW;                                 //SCL低
  158.     I2C_delay();
  159.                
  160.     SCL_HIGH;                                //SCL高(读取数据)
  161.     data <<= 1;
  162.     if(SDA_READ)
  163.     {
  164.       data |= 0x01;                              //SDA高(数据有效)
  165.     }
  166.     I2C_delay();
  167.   }
  168.   //发送应答信号,为低代表应答,高代表非应答
  169.   if(ack == 1)
  170.   {
  171.      I2C_NoAck();
  172.   }
  173.   else
  174.   {
  175.      I2C_Ack();
  176.   }
  177.   return data;                                   //返回数据
  178. }

复制代码



本文来自论坛,点击查看完整帖子内容。

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章