MAX32630/MAX32625学习:类似STM32F4的模拟I2C协议驱动(KEIL平台开发)

MAX32630自带I2C协议,可直接调用相应的库函数,我们知道,STM32F4的库函数典型的I2C协议用SCK和SDA的输出高低电平建立握手机制。今天,我们将这种方式应用于MAX32630

(1)以MAX30100血氧传感器为例
其实将STM32F4的模拟I2C协议移植过来非常简单,主要是管脚输出输入的配置,代码如下:
  1. /*-------------------------------------------------------------------------------
  2. 文件名称:myiic.c
  3. 文件描述:模拟IIC时序控制,
  4. 编写整理:Justice
  5. ---------------------------------------------------------------------------------*/
  6. #include "Com.h"


  7. gpio_cfg_t GPIO_I2C_Control;
  8. const gpio_cfg_t I2C_COL_Pin[] = {
  9.     { PORT_3, PIN_4, GPIO_FUNC_GPIO, GPIO_PAD_OPEN_DRAIN_PULLUP },
  10.     { PORT_3, PIN_4, GPIO_FUNC_GPIO, GPIO_PAD_OPEN_DRAIN_PULLUP },
  11.                 { PORT_3, PIN_4, GPIO_FUNC_GPIO, GPIO_PAD_INPUT_PULLUP },
  12.                 { PORT_3, PIN_6, GPIO_FUNC_GPIO, GPIO_PAD_OPEN_DRAIN_PULLUP },
  13. };
  14. #define I2C_Speed        1
  15. //初始化IIC
  16. void IIC_Init(void)
  17. {                                             
  18.         GPIO_Config(&I2C_COL_Pin[0]);
  19.         GPIO_Config(&I2C_COL_Pin[1]);
  20.         //GPIO_Config(&I2C_COL_Pin[3]);
  21.         GPIO_OutSet(&I2C_COL_Pin[0]); 
  22.         GPIO_OutSet(&I2C_COL_Pin[1]);         
  23. //        GPIO_OutSet(&I2C_COL_Pin[3]); 
  24. }
  25. void SDA_OUT(void)
  26. {
  27.         GPIO_Config(&        I2C_COL_Pin[0]);        
  28. }

  29. void SDA_IN(void)
  30. {
  31.         GPIO_Config(&        I2C_COL_Pin[2]);
  32. }
  33. //产生IIC起始信号
  34. void IIC_Start(void)
  35. {
  36.         SDA_OUT();     //sda线输出
  37.         GPIO_OutSet(&I2C_COL_Pin[0]);         //IIC_SDA=1;           
  38.         GPIO_OutSet(&I2C_COL_Pin[1]);         //IIC_SCL=1;
  39.         delay_us(4);
  40.         GPIO_OutClr(&I2C_COL_Pin[0]); //IIC_SDA=0      START:when CLK is high,DATA change form high to low 
  41.         delay_us(4);
  42.         GPIO_OutClr(&I2C_COL_Pin[1]);////IIC_SCL=0;钳住I2C总线,准备发送或接收数据 
  43. }          
  44. //产生IIC停止信号
  45. void IIC_Stop(void)
  46. {
  47.         SDA_OUT();//sda线输出
  48.         GPIO_OutClr(&I2C_COL_Pin[1]);//IIC_SCL=0;
  49.         GPIO_OutClr(&I2C_COL_Pin[0]); //IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
  50.         delay_us(4);
  51.         GPIO_OutSet(&I2C_COL_Pin[1]);         //IIC_SCL=1; 
  52.         GPIO_OutSet(&I2C_COL_Pin[0]);         //IIC_SDA=1;//发送I2C总线结束信号
  53.         delay_us(4);                                                           
  54. }
  55. //等待应答信号到来
  56. //返回值:1,接收应答失败
  57. //        0,接收应答成功
  58. uint8_t IIC_Wait_Ack(void)
  59. {
  60.         uint8_t ucErrTime=0;
  61.         SDA_IN();      //SDA设置为输入  
  62.         GPIO_OutSet(&I2C_COL_Pin[0]);         //IIC_SDA=1;
  63.         delay_us(1);           
  64.         GPIO_OutSet(&I2C_COL_Pin[1]);         //IIC_SCL=1;
  65.   delay_us(1);         
  66.         while(GPIO_InGet(&I2C_COL_Pin[2]))
  67.         {
  68.                 ucErrTime++;
  69.                 if(ucErrTime>250)
  70.                 {
  71.                         IIC_Stop();
  72.                         return 1;
  73.                 }
  74.         }
  75.         GPIO_OutClr(&I2C_COL_Pin[1]);//IIC_SCL=0;//时钟输出0            
  76.         return 0;  

  77. //产生ACK应答
  78. void IIC_Ack(void)
  79. {
  80.         GPIO_OutClr(&I2C_COL_Pin[1]);//IIC_SCL=0;
  81.         SDA_OUT();
  82.         GPIO_OutClr(&I2C_COL_Pin[0]); //IIC_SDA=0;
  83.         delay_us(2);
  84.         GPIO_OutSet(&I2C_COL_Pin[1]);//IIC_SCL=1;
  85.         delay_us(2);
  86.         GPIO_OutClr(&I2C_COL_Pin[1]);//IIC_SCL=0;
  87. }
  88. //不产生ACK应答                    
  89. void IIC_NAck(void)
  90. {
  91.         GPIO_OutClr(&I2C_COL_Pin[1]);//IIC_SCL=0;
  92.         SDA_OUT();
  93.         GPIO_OutSet(&I2C_COL_Pin[0]);//IIC_SDA=1;
  94.         delay_us(2);
  95.         GPIO_OutSet(&I2C_COL_Pin[1]);//IIC_SCL=1;
  96.         delay_us(2);
  97.         GPIO_OutClr(&I2C_COL_Pin[1]);//IIC_SCL=0;
  98. }                                                                              
  99. //IIC发送一个字节
  100. //返回从机有无应答
  101. //1,有应答
  102. //0,无应答                          
  103. void IIC_Send_Byte(uint8_t txd)
  104. {                        
  105.     uint8_t t;   
  106.                 SDA_OUT();             
  107.     GPIO_OutClr(&I2C_COL_Pin[1]);//IIC_SCL=0;//拉低时钟开始数据传输
  108.     for(t=0;t<8;t++)
  109.     { 
  110.                         if((txd&0x80)>>7)        
  111.                         {
  112.                                 GPIO_OutSet(&I2C_COL_Pin[0]);
  113.                         }        
  114.                         else
  115.                         {
  116.                                 GPIO_OutClr(&I2C_COL_Pin[0]);
  117.                         }        
  118.       txd<<=1;           
  119.                         delay_us(I2C_Speed);   
  120.                         GPIO_OutSet(&I2C_COL_Pin[1]);//IIC_SCL=1;
  121.                         delay_us(I2C_Speed); 
  122.                         GPIO_OutClr(&I2C_COL_Pin[1]);//IIC_SCL=0;        
  123.                         delay_us(I2C_Speed);
  124.     }         
  125. }             
  126. //读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
  127. uint8_t IIC_Read_Byte(unsigned char ack)
  128. {
  129.         unsigned char i,receive=0;
  130.         SDA_IN();//SDA设置为输入
  131.   for(i=0;i<8;i++ )
  132.         {
  133.                 GPIO_OutClr(&I2C_COL_Pin[1]);//IIC_SCL=0; 
  134.                 delay_us(I2C_Speed);
  135.                 GPIO_OutSet(&I2C_COL_Pin[1]);//IIC_SCL=1;
  136.     receive<<=1;
  137.     if(GPIO_InGet(&I2C_COL_Pin[2]))receive++;   
  138.                 delay_us(1); 
  139.   }                                         
  140.   if (!ack)
  141.                 IIC_NAck();//发送nACK
  142.   else
  143.     IIC_Ack(); //发送ACK   
  144.   return receive;
  145. }
复制代码

是不是很简单,这个模拟I2C协议我已经测试过了,包括MAX30100血氧传感器和MPU6050都可以驱动。
头文件也提供给你们吧,代码如下:
  1. #ifndef __MYIIC_H
  2. #define __MYIIC_H
  3. #include "Com.h"

  4.                                  
  5. //IO方向设置
  6. void SDA_OUT(void);
  7. void SDA_IN(void);
  8. //IO操作函数         


  9. #define IIC_PORT PORT_5|PORT_6
  10. #define IIC_SCL PIN_0        
  11. #define IIC_SDA PIN_7        



  12. //IIC所有操作函数
  13. void IIC_Init(void);                //初始化IIC的IO口                                 
  14. void IIC_Start(void);                                //发送IIC开始信号
  15. void IIC_Stop(void);                                  //发送IIC停止信号
  16. void IIC_Send_Byte(uint8_t txd);                        //IIC发送一个字节
  17. uint8_t IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
  18. uint8_t IIC_Wait_Ack(void);                                 //IIC等待ACK信号
  19. void IIC_Ack(void);                                        //IIC发送ACK信号
  20. void IIC_NAck(void);                                //IIC不发送ACK信号

  21. void IIC_Write_One_Byte(uint8_t daddr,uint8_t addr,uint8_t data);
  22. uint8_t IIC_Read_One_Byte(uint8_t daddr,uint8_t addr);          
  23. #endif

猜你喜欢

转载自blog.csdn.net/jdsnpgxj/article/details/79752108