IIC通信 MCU移植 有手就能行(0基础)

前言

本章节主要针对一些做硬件的朋友,需要了解一些软件知识从而提升自己职场的竞争力。或者一些想要了解的同学。
本章节针对国产的MCU去做的一些移植操作。牛逼人士请绕行。

IIC的基础知识

首先IIC是半双工,半双工是什么的,就是说同一时间只能朝一个方向传输数据,分时复用。要么是主机给从机传数据,要么从机给主机,不能同时。
另外IIC是开漏输出,它必须把俩条线上拉(一般上拉到VCC),总线电阻不得低于2K。

另外那些时序还有其他的东西大家了解就好,这里主要移植。并实现功能,当然代码我给你准备好了。

但是希望能记住一点,软件的所有通信都有一个相同的特点,那就是A端发出消息,B端必须有所响应,这才是一次完整的通信过程。

下面我们开搞:

1、在建好的工程中新建一个iic.h(头文件,作为定义一些引脚名称、声明、和简单操作)和iic.c(具体程序)文件;如图
在这里插入图片描述
我使用的编译器就是按照三个箭头新建.c/.h文件的。
2、找到电路图中MCU的IIC引脚。并宏定义一下方便后面用,我们要知道一个东西就是,宏定义#define是纯粹的文本替换。如图:
在这里插入图片描述
在这里插入图片描述
这俩张图就是我的IIC引脚,分别是数据线PT1.1和时钟线PT1.2。能看到我们将这俩条线要做的操作都在iic.h中定义好了。
3、开始iic,c文件的工作。上代码:
static void IIC_Start(void)
{
SDADirectionOUT();
SDASet1();
SclSet1();
DelayUs(IIC_DELAY);
SDASet0();
DelayUs(IIC_DELAY);
SclSet0();
}
static void IIC_Stop(void)
{
SDADirectionOUT();
SclSet0();
SDASet0();
DelayUs(IIC_DELAY);
SclSet1();
SDASet1();
DelayUs(IIC_DELAY);
}

static u8 IIC_Wait_Ack(void)
{
u16 ucErrTime=0;
SDADirectionIN();
SDASet1();DelayUs(IIC_DELAY);
SclSet1();DelayUs(IIC_DELAY);
while(ReadSDA())
{
ucErrTime++;
if(ucErrTime>500)
{
IIC_Stop();
return 1;
}
}
SclSet0();
return 0;
}

static void IIC_Ack(void)
{
SclSet0();
SDADirectionOUT();
SDASet0();
DelayUs(IIC_DELAY);
SclSet1();
DelayUs(IIC_DELAY);
SclSet0();
}
static void IIC_NAck(void)
{
SclSet0();
SDADirectionOUT();
SDASet1();
DelayUs(IIC_DELAY);
SclSet1();
DelayUs(IIC_DELAY);
SclSet0();
}

static void IIC_Send_Byte(u8 txd)
{
u8 t;
SDADirectionOUT();
SclSet0();
for(t=0;t<8;t++)
{
if((txd&0x80)>>7)
{
SDASet1();
}
else
{
SDASet0();
}
txd<<=1;
DelayUs(IIC_DELAY);
SclSet1();
DelayUs(IIC_DELAY);
SclSet0();
DelayUs(IIC_DELAY);
}
}
static u8 IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
SDADirectionIN();
for(i=0;i<8;i++ )
{
SclSet0();
DelayUs(IIC_DELAY);
SclSet1();
receive<<=1;
if(ReadSDA())receive++;
DelayUs(IIC_DELAY);
}
if (!ack)
IIC_NAck();
else
IIC_Ack();
return receive;
}
u8 I2cRead(u8 DevAddr, u8 ReadAddr)
{
u8 data = 0;
IIC_Start();
IIC_Send_Byte(DevAddr<<1);
if(IIC_Wait_Ack())
{
return FALSE;
}
IIC_Send_Byte(ReadAddr&0xFF);
if(IIC_Wait_Ack())
{
return FALSE;
}
IIC_Start();
IIC_Send_Byte((DevAddr<<1)|1);
if(IIC_Wait_Ack())
{
return FALSE;
}
data=IIC_Read_Byte(0);
IIC_Stop();
DelayUs(IIC_DELAY_BYTE);
return data;
}
u8 I2cWrite(u8 Devaddr, u8 WriteAddr,u8 DataToWrite)
{
IIC_Start();
IIC_Send_Byte(Devaddr<<1);
if(IIC_Wait_Ack())
{
return FALSE;
}
IIC_Send_Byte(WriteAddr&0xFF);
if(IIC_Wait_Ack())
{
return FALSE;
}
IIC_Send_Byte(DataToWrite);
if(IIC_Wait_Ack())
{
return FALSE;
}
IIC_Stop();
DelayUs(IIC_DELAY_BYTE);
return TRUE;
}

我们在这里要注意哦,为了防止同学们直接抄代码,我在代码里的和宏定义的略有不同哦,直接不看接搞的兄弟,你就慢慢调吧,自认为牛逼的就不说了。

接下里就是要用iic,h的东西,把上面的代码里面的东西一一替换掉。
比如说把SDASet0()替换为SDA0_SET0
大家自己琢磨一下,实在不想搞,关注点赞私聊我,我都给你,你就直接干。
4、iic,c要包含iic,h文件哦;具体见下图
在这里插入图片描述
iic.h文件也有它的规矩哦:
在这里插入图片描述
iic,h要包含上图的东西哦。
首先是宏定义IIC的接口
另外下面u8开头的就是声明IIC的读写程序。
基本上现在就可以用了,不过各位可以调试一下,看看有没有问题。不想调试的关注私聊我,给你全套Guan式服务.

5、主程序调用。
主程序首先把IIC这俩个引脚的方向还有高低电平给上,就是宏定义那些东西。然后就可以用了。见下图
在这里插入图片描述
现在可以你们调试运行一下。想干嘛干嘛。
想要深入的,关注私聊哦,或者去搜相关的知识,然后自己去实验测试。

这就是IIC的移植操作了,希望能帮助到一些人。觉得有帮助,可以点个赞哦。。。

猜你喜欢

转载自blog.csdn.net/qq_27854611/article/details/108425257