嵌入式培训机构四个月实训课程笔记(完整版)-Linux ARM驱动编程第四天-ARM Linux编程之IIC与uart (物联技术666)

链接:https://pan.baidu.com/s/1V0E9IHSoLbpiWJsncmFgdA?pwd=1688
提取码:1688

教学内容:

1 I2C 总线:

I2C(Inter-Integrated Circuit),PHILIPS公司开发的两线式半双工同步串行总线;可以用来连接存储器(EEPROM、FLASH)、A/D、D/A转换器、LCD驱动器、传感器等等。

I2C总线有两根信号线:双向数据线(SDA)、时钟线(SCL)。均为双向I/O线,通过上拉电阻接正电源;I2C总线可以连接多个设备,各设备的数据和时钟线均连到SDA、SCL信号线上,主机通过设备地址来区分具体的设备,每个设备有唯一的地址(7位或10位)。

起始和终止信号:

SCL线为高电平期间,SDA线由高电平向低电平的变化表示起始信号;

SCL线为高电平期间,SDA线由低电平向高电平的变化表示终止信号。

起始和终止信号都是由主机发出的,在起始信号产生后,总线就处于被占用的状态;在终止信号产生后,总线就处于空闲状态。连接到I2C总线上的器件,若具有I2C总线的硬件接口,则很容易检测到起始和终止信号。对于不具备I2C总线硬件接口的有些单片机来说,为了检测起始和终止信号,必须保证在每个时钟周期内对数据线SDA采样两次。接收器件收到一个完整的数据字节后,有可能需要完成一些其它工作,如处理内部中断服务等,可能无法立刻接收下一个字节,这时接收器件可以将SCL线拉成低电平,从而使主机处于等待状态。直到接收器件准备好接收下一个字节时,再释放SCL线使之为高电平,从而使数据传送可以继续进行。

在起始信号后必须传送一个从机的地址(7位),第8位是数据的传送方向位(R/),用"0"表示主机发送数据(T),"1"表示主机接收数据(R)。每次数据传送总是由主机产生的终止信号结束。但是,若主机希望继续占用总线进行新的数据传送,则可以不产生终止信号,马上再次发出起始信号对另一从机进行寻址。

a、主机向从机发送数据,数据传送方向在整个传送过程中不变:

注:有阴影部分表示数据由主机向从机传送,无阴影部分则表示数据由从机向主机传送。

A表示应答, 表示非应答(高电平)。S表示起始信号,P表示终止信号。。

b、主机在第一个字节后,立即由从机读数据

c、在传送过程中,当需要改变传送方向时,起始信号和从机地址都被重复产生一次,但两次读/写方向位正好反相。

模拟过程:(以AT24C02为外接设备)

//*************************************************

#define IIC_CLK_SET()

#define IIC_CLK_CLR()

#define IIC_DAT_SET()

#define IIC_DAT_CLR()

#define IIC_DAT_GET()

//IIC启动信号,CLK为高电平的时,DAT由高变低

void I2CStart()

{

IIC_DAT_SET();

I2CDelay();

IIC_CLK_SET();

I2CDelay();

IIC_DAT_CLR();

I2CDelay();

IIC_CLK_CLR();

I2CDelay();

}

//停止信号,CLK为高电平时,DAT信号由低变高

void I2CStop()

{

IIC_DAT_CLR();

I2CDelay();

IIC_CLK_SET();

I2CDelay();

IIC_DAT_SET();

I2CDelay();

IIC_CLK_CLR();

I2CDelay();

}

//IIc初始化函数 CLK信号置低,发送停止信号

void I2CInit()

{

IIC_CLK_CLR();

I2CStop();

}

//在CLK为高电平时读取1位总线数据与应答信号

bit I2CClock() //return SDA while SCL is HIGH

{

unsigned char sample;

IIC_CLK_SET();

I2CDelay();

sample = IIC_DAT_GET();

IIC_CLK_CLR();

I2CDelay();

return sample;

}

// 发送一个字节的数据,并返回应答信号(1表示接收正常,0表示接收器件无应答或损坏)

unsigned int I2CSend(BYTE I2CData)

{

BYTE i;

for(i=0;i<8;i++)

{

if( (I2CData & 0x80) == 0x80 )

IIC_DAT_SET();

else

IIC_DAT_CLR();

I2CData=I2CData << 1;

IIC_CLK_SET();

I2C_Delay();

IIC_CLK_CLR();

I2C_Delay();

}

IIC_DAT_SET();

return (~I2CClock());

}

//主机应答信号,a=1时表示应答信号, a=0时表示非应答信号

void I2CAck(unsigned int a)

{

if(a==0)

IIC_DAT_CLR();

else

IIC_DAT_SET();

IIC_CLK_SET();

I2C_Delay();

IIC_CLK_CLR();

I2C_Delay();

}

//延时程序

void I2CDelay()

{

BYTE ll;

for(ll=0;ll<100;ll++)

{

;

}

}

//IIC总线器件接受一个字节的数据

BYTE I2CReceive()

{

BYTE I2CData=0;

BYTE kk;

for(kk=0;kk<8;kk++)

{

I2CData = I2CData <<1;

if(I2CClock())

{

I2CData= I2CData + 0x01;

}

}

return I2CData;

}

//向指定器件发送指定字节的数据,包含子设备地址

int SendByte(unsigned char sla,unsigned char c ,int num )

{

//启动IIC设备

//发送器件地址,

//检查应答信号

//发送一个字节数据

//结束总线

}

//想从指定的器件接收指定字节的数据,返回0代表失败,返回1代表成功

unsigned int RevByte(unsigned char sla, char *c ,int num)

{

//启动IIC设备

//发送器件地址

//检查应答信号

//接收一个字节数据

//发送应答信号

//结束总线

}

//***************************************************

相关推荐
xuanzdhc14 分钟前
Linux 基础IO
linux·运维·服务器
愚润求学19 分钟前
【Linux】网络基础
linux·运维·网络
bantinghy1 小时前
Linux进程单例模式运行
linux·服务器·单例模式
小和尚同志2 小时前
29.4k!使用 1Panel 来管理你的服务器吧
linux·运维
帽儿山的枪手2 小时前
为什么Linux需要3种NAT地址转换?一探究竟
linux·网络协议·安全
shadon1789 天前
回答 如何通过inode client的SSLVPN登录之后,访问需要通过域名才能打开的服务
linux
小米里的大麦9 天前
014 Linux 2.6内核进程调度队列(了解)
linux·运维·驱动开发
算法练习生9 天前
Linux文件元信息完全指南:权限、链接与时间属性
linux·运维·服务器
忘了ʷºᵇₐ9 天前
Linux系统能ping通ip但无法ping通域名的解决方法
linux·服务器·tcp/ip
浩浩测试一下9 天前
渗透测试指南(CS&&MSF):Windows 与 Linux 系统中的日志与文件痕迹清理
linux·运维·windows·安全·web安全·网络安全·系统安全