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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章