匿名
未登录
登录
百问网嵌入式Linux wiki
搜索
查看“第019课 I2C”的源代码
来自百问网嵌入式Linux wiki
名字空间
页面
讨论
更多
更多
页面选项
Read
查看源代码
历史
←
第019课 I2C
因为以下原因,您没有权限编辑本页:
您所请求的操作仅限于该用户组的用户使用:
用户
该页面已被保护以防止编辑和其他操作。
您可以查看与复制此页面的源代码。
= 第001节_I2C协议与EEPROM = == I2C协议 == I2C在硬件上的接法如下(图19-1)所示,主控芯片引出两条线SCL,SDA线,在一条I2C总线上可以接很多I2C设备,我们还会放一个上拉电阻(放一个上拉电阻的原因以后我们再说)。 [[File:chapter19_lesson1_001.jpg|800px]] 我们怎么传输数据,我们需要发数据从主设备发送到从设备上去,也需要把数据从从设备传送到主设备上去,数据涉及到双向传输。举个例子: [[File:chapter19_lesson1_002.jpg|800px]] 体育老师:可以把球发给学生,也可以把球从学生中接过来。 1,发球:a,老师说:注意了(start) b,老师对A学生说我要球发给你(地址)。 c,老师就把球发出去了(传输)。 d,A收到球之后,应该告诉老师一声(回应)。 e,老师说下课(停止) 2,接球: a,老师说注意了(start), b,老师说:B把球发给我(地址) c,B就把球发给老师(传输) d,老师收到球之后,给B说一声,表示收到球了(回应)。 e,老师说下课(停止) 我们就使用这个简单的例子,来解释一下IIC的传输协议。 老师说注意了,表示开始信号(start) 老师告诉某个学生,表示发送地址(address) 老师发球/接球,表示数据的传输 老师/学生收到球,回应表示:回应信号(ACK) 老师说下课,表示IIC传输接受(P) == IIC传输数据的格式 == '''1,写操作:''' 刚开始主芯片要发出一个start信号,然后发出一个设备地址(用来确定是往哪一个芯片写数据),方向(读/写,0表示写,1表示读)。 回应(用来确定这个设备是否存在),然后就可以传输数据,传输数据之后,要有一个回应信号(确定数据是否接受完成),然后再传输下一个数据。 每传输一个数据,接受方都会有一个回应信号,数据发送完之后,主芯片就会发送一个停止信号。 白色背景:主→从灰色背景:从→主 [[File:chapter19_lesson1_003.jpg|800px]] '''2,读操作:''' 刚开始主芯片要发出一个start信号,然后发出一个设备地址(用来确定是从哪一个芯片读取数据),方向(读/写,0表示写,1表示读)。 回应(用来确定这个设备是否存在),然后就可以传输数据,传输数据之后,要有一个回应信号(确定数据是否接受完成),然后在传输下一个数据。 每传输一个数据,接受方都会有一个回应信号,数据发送完之后,主芯片就会发送一个停止信号。 白色背景:主→从灰色背景:从→主 [[File:chapter19_lesson1_004.jpg|800px]] 传输是以8位为单元数据传输的,先传输最高位(MSB),主芯片发出start信号之后,然后发出9个时钟传输数据。 (1)开始信号(S):SCL为高电平时,SDA山高电平向低电平跳变,开始传送数据。 (2)结束信号(P):SCL为电平时,sDA由低电平向高电平跳变,结束传送数据。 (3)响应信号(ACK):接收器在接收到8位数据后,在第9个时钟周期,拉低SDA SDA上传输的数据必须在SCL为高电平期间保持稳定,SDA上的数据只能在SCL为低电平期间变化。如图 [[File:chapter19_lesson1_005.jpg|800px]] 1,问题:如何在SDA上实现双向传输? 答:主芯片通过一根SDA线既可以把数据发给从设备,也可以从SDA上读取数据,连接SDA线的引脚里面必然有两个引脚(发送引脚/接受引脚)。 2,问题:主设备(从设备)发送数据时,从设备(主设备)的发送引脚,不影响数据的发送,怎么做到呢? 答:里面放一个三极管,使用开极(极电集开发出去作为输出)电路,如下图 [[File:chapter19_lesson1_006.jpg|800px]] 下面画一个真值表: [[File:chapter19_lesson1_007.jpg]] * 从真值表和电路图我们可以知道,当某一个芯片不行影响SDA线时,那就不驱动这个三极管。 * 想输出高电平时;都不驱动(高电平就由上拉电阻决定)。 * 想输出低电平,就驱动三极管。 从下面的例子可以看看数据是怎么传的(实现双向传输), 比如:主设备发送(8bit)给从设备 1, 前8个clk * 从设备不要影响,从设备不驱动三极管; * 主设备决定数据; 2, 第9个clk,由从设备决定数据 * 主设备不驱动三极管; * 从设备决定数据; 从上面的例子,就可以知道,怎样在一条线上实现,双向传输的办法。这就是为什么在SDA,SCL上放上拉电阻的原因。 在第9个时钟之后,如果有某一方处于繁忙状态,它可以一直把SCL拉低当SCL为低电平时候,大家都不应该使用IIC总线,只有当SCL从低电平变为高电平的时候,IIC总线才能被使用。 从图1-6和图1-7我们也可以知道ACK信号应该是低电平。主设备不驱动 三极管,如果从设备不驱动三极端的化SDA应该是高电平,当从设备接收数据之后,发出回应信号的时候,就会驱动三极管,让SDA变为低电平。所以说:ACK信号是低电平。 对于IIC协议它只能规定怎么传输数据,数据什么含义它完全不能够控制,数据的含义有从设备决定。 = 第002节_S3C2440的I2C控制器 = 在嵌入式系统里面的主控芯片一般都会有I2C控制器,要是没有可以根据I2C协议用GPIO管脚模拟,但是非常麻烦,我们要发送数据时,可以把数据放到某个寄存器,它就会自动的发出时钟,并且把数据发送给从设备,同时会等待从设备会返回回应信号。当我们想发送一个数据的时候,要设置某个寄存器启动传输,它也一样会产生时钟,然后从设备就会把数据通过SDA传到I2C控制器里面,组装进某个寄存器里面,最终寄存器会把接收到的8位数据返回给我们的程序,从这里可以看到I2C控制器简化了I2C的操作。简短电路连接图,如图: [[File:chapter19_lesson2_001.jpg|800px]] [[File:chapter19_lesson2_002.jpg|800px]] 根据上图,我们首先设置IICCON(来设置时钟),时钟源是PCLK(是50MHZ)太快了我们需要设置这个分频系数,把时钟降低,降低到我们想要的SCL,然后我们要发出start信号,我们需要设置寄存器发出start信号,之后我们需要发出数据啊,我们的程序可以把数据写入到IICDS寄存器,一写入就会自动的发出时钟,并且把这8位数据从SDA发送给从设备,数据发送之后,在第九个时钟会收到回应信号,可以查询IICSTAT是否有ACK(有ACK表示数据发送成功了),可以继续发送数据,等发完数据之后,再来设置IICSTAT让它发出P信号。 在第九个CLK,就会产生一个中断,在中断处理过程中SCL被拉为低电平,谁都不能再使用IIC总线,等待中断处理完成. '''怎样处理中断?''' * 写操作: 若无ACK,出错,然后发出P信号结束, 若有ACK信号表示上一个字节成功发送出去 若仍有数据,写入IICDS寄存器,然后清中断,一清中断就会释放SCL信号,继续发出时钟,把数据再次发送出去。 若没有数据了,发出P信号结束。 * 读操作: 读到8位数时,应该回应一个ACK信号。 还想读数据,清中断,启动传输。等它再次发生中断时,再来读取IICDS寄存器,得到数据。不想读取数据,发出P信号结束。 '''重点:''' 发生中断时,我们的IIC控制器会把SCL拉低,阻止任何设备再使用IIC总线,清中断之后才能继续使用,这种机制就给我们中断服务程序的执行提供了时间。 '''读-写操作''' * 在发送模式: 1,往寄存器IICDS寄存器放入一个val值。 2,发完,产生中断,并且会把 SCL拉低。 3,在中断程序里,判断状态,然后往IICDS里面写入下一个数据,一旦写入下一个数据IIC继续操作,若再次发完,就会再次产生中断。 * 在接受模式: 1,我的程序发起传输,接受数据。 2,接收到数据之后,产生中断,SCL被拉低。 3,中断程序里,判断数据是否要继续接受等,如果还有继续接受的话,再次设置,设置好之后读IICDS寄存器,一但读出来IIC。 继续接受下一个数据,收到新数据之后,又会产生一个中断(就是这样循环操作)。 = 第003节_程序框架 = = 第004节_I2C控制器编程_框架 = = 第005节_I2C控制器编程_中断 = = 第006节_EEPROM编程和测试代码 = = 第007节_测试 = ='''《《所有章节目录》》'''= <categorytree mode=all background*color:white;">ARM裸机加强版</categorytree> [[Category:ARM裸机加强版 ]]
返回至
第019课 I2C
。
导航
导航
WIKI首页
官方店铺
资料下载
交流社区
所有页面
所有产品
MPU-Linux开发板
MCU-单片机开发板
Linux开发系列视频
单片机开发系列视频
所有模块配件
Wiki工具
Wiki工具
特殊页面
页面工具
页面工具
用户页面工具
更多
链入页面
相关更改
页面信息
页面日志