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

//发送器件地址

//检查应答信号

//接收一个字节数据

//发送应答信号

//结束总线

}

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

相关推荐
晨欣1 分钟前
Umi-OCR:Windows7和Linux上可免费离线使用的OCR应用!
linux·运维·ocr
ホロHoro17 分钟前
学习笔记:JavaScript(4)——DOM节点
javascript·笔记·学习
码畜也有梦想27 分钟前
springboot响应式编程笔记
java·spring boot·笔记
siriuuus1 小时前
Linux 网络配置解析、IP地址配置及常用网络命令
linux·网络
ZYMFZ1 小时前
Linux 防火墙 Iptables
linux·运维·服务器
没头脑的男大2 小时前
零碎的嵌入式笔记2
笔记
小龙2 小时前
图卷积神经网络(GCN)学习笔记
笔记·学习·cnn·gcn·图卷积神经网络·理论知识
口嗨农民工2 小时前
linux 时间相关的命令
linux·运维·服务器
evo-master3 小时前
网络编程-HTTP
linux·网络
轻松Ai享生活3 小时前
一文搞懂应用程序 core dump 和内核 core dump
linux