3086|0

98

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

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

是不是很简单,这个模拟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


  24. 后面的驱动如何调用你们就自己解决吧,洗洗睡啦,还有一个月就要提交作品了,大家加油








复制代码

点赞 关注
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表