[软件资料] IIC通信

[复制链接]
864|4
 楼主| mickit 发表于 2024-6-17 22:16 | 显示全部楼层 |阅读模式


  1. #include "myiic.h"

  2. #define  I2C1_SCL_GPIO_PORT       CW_GPIOB
  3. #define  I2C1_SCL_GPIO_PIN        GPIO_PIN_10   
  4. #define  I2C1_SDA_GPIO_PORT       CW_GPIOB
  5. #define  I2C1_SDA_GPIO_PIN        GPIO_PIN_11  

  6. void delay_us(uint32_t us)
  7. {
  8.         while(us--)
  9.         {
  10.                 __nop();
  11.                 __nop();
  12.                 __nop();
  13.                 __nop();
  14.                 __nop();
  15.                 __nop();
  16.                 __nop();
  17.                 __nop();
  18.         }
  19.        
  20. }


  21. void IIC_Init(void)
  22. {
  23.           //配置PB10 为输出
  24.         //使能GPIOB时钟
  25.         CW_SYSCTRL->AHBEN_f.GPIOB  = 1;
  26.         //配置PB10 为输出
  27.         CW_GPIOB->ANALOG_f.PIN10 = 0; //设置 GPIOx_ANALOG.PINy 为 0,将端口配置为数字功能;
  28.         CW_GPIOB->DIR_f.PIN10 = 0;    //设置 GPIOx_DIR.PINy 为 0,将端口配置成输出;
  29.         CW_GPIOB->OPENDRAIN_f.PIN10 = 0;  //0:推挽输出
  30.         CW_GPIOB->ODR_f.PIN10 = 1;
  31.        
  32.         CW_GPIOB->ANALOG_f.PIN11 = 0; //设置 GPIOx_ANALOG.PINy 为 0,将端口配置为数字功能;
  33.         CW_GPIOB->DIR_f.PIN11 = 0;    //设置 GPIOx_DIR.PINy 为 0,将端口配置成输出;
  34.         CW_GPIOB->OPENDRAIN_f.PIN11 = 0;  //0:推挽输出
  35.         CW_GPIOB->ODR_f.PIN11 = 1;
  36.                
  37. }
  38.                                                                                                             
  39. //IO方向设置(SDA)
  40. /*********xxxxxxxxxxxxxx*************/
  41. void SDA_IN()  
  42. {
  43.         CW_GPIOB->DIR_f.PIN11 = 1;    //设置 GPIOx_DIR.PINy 为 0,将端口配置成输出;
  44. }

  45. void SDA_OUT()
  46. {
  47.   CW_GPIOB->DIR_f.PIN11 = 0;    //设置 GPIOx_DIR.PINy 为 0,将端口配置成输出;
  48.         CW_GPIOB->OPENDRAIN_f.PIN11 = 0;  //0:推挽输出
  49. }

  50. //产生IIC起始信号
  51. void IIC_Start(void)
  52. {
  53.         SDA_OUT();     //sda线输出
  54.         IIC_SDA=1;                    
  55.         IIC_SCL=1;
  56.         delay_us(4);
  57.         IIC_SDA=0;//START:when CLK is high,DATA change form high to low
  58.         delay_us(4);
  59.         IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
  60. }       

  61. //产生IIC停止信号
  62. void IIC_Stop(void)
  63. {
  64.         SDA_OUT();//sda线输出
  65.         IIC_SCL=0;
  66.         IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
  67.         delay_us(4);
  68.         IIC_SCL=1;
  69.         IIC_SDA=1;//发送I2C总线结束信号
  70.         delay_us(4);                                                                  
  71. }

  72. //等待应答信号到来
  73. //返回值:1,接收应答失败
  74. //        0,接收应答成功
  75. /*********xxxx修改超时时间************/
  76. uint8_t IIC_Wait_Ack(void)
  77. {
  78.         uint8_t ucErrTime=0;
  79.         SDA_IN();      //SDA设置为输入  
  80.         IIC_SDA=1;delay_us(3);          
  81.         IIC_SCL=1;delay_us(3);         
  82.         while(READ_SDA)
  83.         {
  84.                 ucErrTime++;
  85.                 if(ucErrTime>250)
  86.                 {
  87.                         //printf("超时\n");
  88.                         IIC_Stop();
  89.                         return 1;
  90.                 }
  91.         }
  92.         IIC_SCL=0;//时钟输出0           
  93.         return 0;  
  94. }

  95. //产生ACK应答
  96. void IIC_Ack(void)
  97. {
  98.         IIC_SCL=0;
  99.         SDA_OUT();
  100.         IIC_SDA=0;
  101.         delay_us(2);
  102.         IIC_SCL=1;
  103.         delay_us(2);
  104.         IIC_SCL=0;
  105. }

  106. //不产生ACK应答                    
  107. void IIC_NAck(void)
  108. {
  109.         IIC_SCL=0;
  110.         SDA_OUT();
  111.         IIC_SDA=1;
  112.         delay_us(2);
  113.         IIC_SCL=1;
  114.         delay_us(2);
  115.         IIC_SCL=0;
  116. }                       


  117. //IIC发送一个字节
  118. //返回从机有无应答
  119. //1,有应答
  120. //0,无应答                          
  121. void IIC_Send_Byte(uint8_t txd)
  122. {                        
  123.     uint8_t t;   
  124.                 SDA_OUT();             
  125.     IIC_SCL=0;//拉低时钟开始数据传输
  126.     for(t=0;t<8;t++)
  127.     {              
  128.                 if((txd&0x80)>>7)
  129.                         IIC_SDA=1;
  130.                 else
  131.                         IIC_SDA=0;
  132.                 txd<<=1;           
  133.                 delay_us(2);   //对TEA5767这三个延时都是必须的
  134.                 IIC_SCL=1;
  135.                 delay_us(2);
  136.                 IIC_SCL=0;       
  137.                 delay_us(2);
  138.     }         
  139. }           


  140. //读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
  141. uint8_t IIC_Read_Byte(unsigned char ack)
  142. {
  143.         unsigned char i,receive=0;
  144.         SDA_IN();//SDA设置为输入
  145.   for(i=0;i<8;i++ )
  146.         {
  147.         IIC_SCL=0;
  148.         delay_us(100);
  149.                     IIC_SCL=1;
  150.         receive<<=1;
  151.         if(READ_SDA)receive++;   
  152.                     delay_us(100);
  153.     }                                         
  154.     if (!ack)
  155.         IIC_NAck();//发送nACK
  156.     else
  157.         IIC_Ack(); //发送ACK   
  158.     return receive;
  159. }





田舍郎 发表于 2024-6-17 22:55 来自手机 | 显示全部楼层
io模拟的程序
OKAKAKO 发表于 2024-6-21 21:10 | 显示全部楼层
IIC通信需要有哪些注意事项
中国龙芯CDX 发表于 2024-6-26 16:41 | 显示全部楼层
IIC过程需要注意什么?
jf101 发表于 2024-6-27 16:51 | 显示全部楼层
硬件IIC与IO模拟有什么区别?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

89

主题

1561

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部