打印

I2C软件模拟程序库

[复制链接]
454|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
小蘭|  楼主 | 2018-7-11 16:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
今天我给大家分享一下我写的I2C软件模拟程序库的用法,写的不好不要见谅呀。

因为大家每次为写I2C协议都很麻烦,尤其是多个总线I2C,协议重复写还要重命名,IO底层也要全部复制改写。每次还要考虑拉还是不拉,搞得头晕!!!

这个IC2软件优点有一下几点:
1. 它可以实现一个你不知道I2C协议是什么的也可以灵活运用。
2,它只需配置很少底层就可以完成所有操作。
3. 它可以实现多个总线自动切换功能。
4,他有多处检测判断总线异常报警。


I2C库分为两大部分,
i2c协议.
i2c协议头文件.
i2c外设配置(配置相应单片机).
i2c外设配置头文件(配置相应单片机引导头文件).

第一部分我们是不用动的,第二部分是要配置的,
基本每种单片机我们只需要修改一次(i2c_config.c)这个文件

以后再用时只需修改i2c_config.h 即可
下面我说一下关键的配置i2c_config.h的几个定义;

<1> #define I2C_AUTU_WAIT    1          /*屏蔽此宏定义自动等待应答信号关闭*/
<2>#define I2C_WAIT_MAX_CLOCK 200      /*I2C检测应答等待最大时钟*/
<3>#define I2C_SHORT_DELAY  168*3      /*通讯时短暂延时(根据IC协议修改(一般为2.5us~10us))*/

<1> 这个是ACK用的,如果它没有屏蔽表示ACK等待I2C从设发送应答信号,等待到退出;
<2>I2C检测应答等待最大时钟,如果<1>没有屏蔽它为最大等待周期,如果屏蔽它为等待200约两百个时钟,在读ACK;

<3>这个为最重要的一步了,因为上边两个参数可以不修改,但这个必须修改,根据每个平台不一样就要修改大概计算方法近似值
一般I2C为400K-100K 那么每个周期应该为(2.5us~10us);这个定义I2C_SHORT_DELAY值约表示最小周期值;我们来计算一下F4=168M
168次为1us,所以168*3=3us 其实实际CPU要比计算要大,就是说CPU运行后肯定时间比3us长,这个我们就不用管了,只要满足I2C工作就可以了。

呵呵,说了这么多我们来个实战演习
本次I2C库以F4为例,做一用法介绍;24C02读写一个或多个字节

开始,
1。上面的参数我已配好
2。配置IO口(i2c_config.c)程序我也已配好
3.大家现在在F4上只需配置这个

#define I2C1_CHANNEL  1
#define I2C2_CHANNEL  2
#define I2C3_CHANNEL  3

#define I2C1_SCL_PIN                 GPIO_Pin_8
#define I2C1_SCL_GPIO         GPIOB
#define I2C1_SCL_CLOCK  RCC_AHB1Periph_GPIOB
#define I2C1_SDA_PIN                GPIO_Pin_9
#define I2C1_SDA_GPIO         GPIOB
#define I2C1_SDA_CLOCK  RCC_AHB1Periph_GPIOB

#define I2C2_SCL_PIN                 GPIO_Pin_6
#define I2C2_SCL_GPIO         GPIOF
#define I2C2_SCL_CLOCK  RCC_AHB1Periph_GPIOF
#define I2C2_SDA_PIN                GPIO_Pin_7
#define I2C2_SDA_GPIO         GPIOF
#define I2C2_SDA_CLOCK  RCC_AHB1Periph_GPIOF

#define I2C3_SCL_PIN                 GPIO_Pin_2
#define I2C3_SCL_GPIO         GPIOC
#define I2C3_SCL_CLOCK  RCC_AHB1Periph_GPIOC
#define I2C3_SDA_PIN                GPIO_Pin_3
#define I2C3_SDA_GPIO         GPIOC
#define I2C3_SDA_CLOCK  RCC_AHB1Periph_GPIOC

我已经帮大家写了3个总线了,已经可以满足常用的了
如果我们的系统中没有3个总线怎么办?

解决的办法,如果只有一个那我们把它3个写一样,如果是2个我们把后两个写一样,如果三个那正好。
配置好上面3个接口后我们现在就可以用了,用之前我们先要执行
I2C_Initialization();  /*I2C初始化*/程序,它来初始化我们的IO口的。下来看程序

int main(void)
{
  unsigned char i=0;
  unsigned char data[2]={1,2};
  unsigned char buf[8]={0,1,2,3,4,5,6,7};
  unsigned char tbuf[8];

I2C_write_data(0,&data[0],1);写一个字节
I2C_read_ndata(0,&data[1],1);读一个字节

if(data[0]==data[1])
{
  //ok;
}
else
{
   //error;
}

I2C_write_data(0,buf,8);写8个字节
Delayms(10);//根据E2ROM规定他要延时等E2PROM烧写完毕。
I2C_read_ndata(0,tbuf,8);读8个字节
}

呵呵自动切换在哪里呀,I2C_write_data,I2C_read_ndata
这两个程序在哪里呀;
大家看下面就是24C02内部程序了,自动切换在读写程序里了,呵呵
#include "i2c.h"

#define E2_ADDR  0xA0
//**I2C写数据**//
void I2C_write_data(unsigned int addr,unsigned char *buffer,unsigned char n)
{
        unsigned char r;
        I2C_ChannelSelection(I2C1_CHANNEL);

        while(I2C_CheckBusBusy()!=0);  //检查总线忙碌 //

        I2C_Start();
        I2C_SendByte(E2_ADDR);
        while(I2C_CheckAck()!=0);
        I2C_SendByte(addr);
        while(I2C_CheckAck()!=0);         
        for(r=0 ; r<n ; r++)
        {        
           I2C_SendByte(buffer[r]);
           while(I2C_CheckAck()!=0);
        }
        I2C_Stop();
}
//**I2C读数据**//
void I2C_read_ndata(unsigned int addr,unsigned char *buffer,unsigned char count)
{
        unsigned char i;
        I2C_ChannelSelection(I2C1_CHANNEL);

        while(I2C_CheckBusBusy()!=0);  //检查总线忙碌 //

        I2C_Start();
        I2C_SendByte(E2_ADDR);
        while(I2C_CheckAck()!=0);
        I2C_SendByte(addr);
        while(I2C_CheckAck()!=0);         
        I2C_Start();
        I2C_SendByte(E2_ADDR+1);
        while(I2C_CheckAck()!=0);
        for(i=0 ; i<count ; i++)
        {
                buffer = I2C_ReadByte();
                if(i<count-1)
                I2C_ReadAck();
        }
        I2C_NoAck();
        I2C_Stop();
}

呵呵看到了吧只需在读写前加

I2C_ChannelSelection(I2C1_CHANNEL);这个函数就可以啦
I2C1_CHANNEL就是我们开始填写的总线通道了,呵呵讲到这里我估计大家也迷糊,不如你们把附件带入你们的F4移植看看,就明白啦。


今天就讲到这里不会的可以提问,呵呵我写的程序如果大家发现有什么错误可要多多提醒呀,谢谢。!!!!!!

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

451

主题

463

帖子

1

粉丝