嵌入式培训机构四个月实训课程笔记(完整版)-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设备

//发送器件地址

//检查应答信号

//接收一个字节数据

//发送应答信号

//结束总线

}

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

相关推荐
Bearnaise20 分钟前
PointMamba: A Simple State Space Model for Point Cloud Analysis——点云论文阅读(10)
论文阅读·笔记·python·深度学习·机器学习·计算机视觉·3d
Zfox_20 分钟前
【Linux】进程信号全攻略(二)
linux·运维·c语言·c++
安於宿命25 分钟前
【Linux】简易版shell
linux·运维·服务器
CYRUS STUDIO32 分钟前
ARM64汇编寻址、汇编指令、指令编码方式
android·汇编·arm开发·arm·arm64
黄小耶@37 分钟前
linux常见命令
linux·运维·服务器
叫我龙翔38 分钟前
【计网】实现reactor反应堆模型 --- 框架搭建
linux·运维·网络
古驿幽情40 分钟前
CentOS AppStream 8 手动更新 yum源
linux·运维·centos·yum
BillKu41 分钟前
Linux(CentOS)安装 Nginx
linux·运维·nginx·centos
BillKu44 分钟前
Linux(CentOS)yum update -y 事故
linux·运维·centos
a266378961 小时前
解决yum命令报错“Could not resolve host: mirrorlist.centos.org
linux·运维·centos