1.IIC总线概述
IIC总线全称:Inter-Integrated Circuit,是由飞利浦公司开发出来的一种串行总线协议,它是一种多主机的总线,当发生主机竞争时,有总线仲裁机制。
<ignore_js_op>
图片16.png (29.82 KB, 下载次数: 0)
下载附件 保存到相册
2016-4-9 14:23 上传
IIC总线只有2根信号线,一根是数据线SDA,一根是时钟线SCL。SDA和SCL均为双向信号线,通过上拉电阻接正电源。当总线空闲时,两根线都是高电平。连接到总线上的任一器件,输出低电平,都将使总线的信号变低。
连接总线的器件输出级必须是集电极或漏极开路,以形成线“与”功能。
每个具有IIC接口的设备都有一个唯一的地址,也叫做设备地址。
数据位的有效性定义:
IIC总线在进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定。只有在时钟信号为低电平期间,数据线上的数据才允许变化。
<ignore_js_op>
图片17.png (19.09 KB, 下载次数: 0)
下载附件 保存到相册
2016-4-9 14:23 上传
2. IIC总线数据传输规范
在数据的传输过程中,必须确认数据传送的开始和结束。在IIC总线规范中,规定了起始信号和停止信号。
<ignore_js_op>
图片18.png (19.01 KB, 下载次数: 0)
下载附件 保存到相册
2016-4-9 14:26 上传
起始信号:当SCL为高电平时,SDA由高变低。
停止信号:当SCL为高电平时,SDA由低变高。
在起始信号以后,IIC总线就被认为是处于忙状态,直到停止信号以后的几个时钟周期,IIC总线才被认为重新处于空闲状态。
在起始信号之后,必须是器件的控制字节,也即是设备地址,其中高4位是器件的类型识别符(EEPROM的识别符为1010),接着3位是片选信号,最后1位是读写控制位,读操作为1,写操作为0。
对于EEPROM器件来说,如果片选信号为000,则:
读操作的设备地址为:0xA1。
写操作的设备地址为:0xA0。
IIC总线每次传送的数据字节不限,每一个字节必须是8位。数据传送时,必须先送最高位(MSB),每个数据字节后面都有一个确认位,也就是应答(ACK)。
<ignore_js_op>
图片19.png (33.39 KB, 下载次数: 0)
下载附件 保存到相册
2016-4-9 14:26 上传
应答位是用来结束一个字节的传输,它由接受方在数据开始后的第9个时钟周期发送,也就是说,一帧完整的数据共有9位。
注意:当主机接收数据(也就是在读数据状态)时,它收到最后一个字节后,必须向从机发出一个结束传送的信号。这个信号是通过对从机的“非应答”来实现的,然后从机会释放SDA线,从而允许主机产生一个停止信号。
3. IIC总线数据帧的传输方式
在总线的一次数据传送中,可以有以下几种组合方式:
(1)主机向从机发送数据,数据传送方向在整个传送过程中不变:
<ignore_js_op>
图片20.png (9.82 KB, 下载次数: 0)
下载附件 保存到相册
2016-4-9 14:29 上传
(2)主机在第一个字节后,立即从从机读数据。
<ignore_js_op>
图片21.png (9.28 KB, 下载次数: 0)
下载附件 保存到相册
2016-4-9 14:29 上传
在读数据的过程中,一定要注意,当读完最后一个字节数据的时候,主机不能产生“应答”信号,而应该产生一个“非应答”信号。
(3)在传送过程中,当需要改变传送方向时,起始信号和从机地址都被重复产生一次,但两次读写方向位正好反相。
<ignore_js_op>
图片22.png (12.1 KB, 下载次数: 0)
下载附件 保存到相册
2016-4-9 14:29 上传
注:阴影部分表示数据从主机向从机传送,无阴影部分表示数据由从机向主机传送。
4. EEPROM存储器24C02的概述
24C02是一个2K Bit的串行EEPROM存储器,内部含有256个字节。在24C02里面有一个8字节的页写缓冲器。该设备的工作电压为1.8V到6.0V,芯片的第7引脚WP为写保护引脚,将该引脚接地允许正常的读写。
<ignore_js_op>
图片23.png (16.46 KB, 下载次数: 0)
下载附件 保存到相册
2016-4-9 14:30 上传
5. EEPROM存储器24C02的读写规范
5.1 应答信号
IIC总线数据传送时,每成功传送一个字节后,接收器必须产生一个应答信号,应答的器件在第9个时钟周期将SDA拉低,表示其已收到一个8位数据。
在写操作中,24C02每接收到一个8位数据后,响应一个应答信号。
在读操作中,24C02在发送完一个8位数据后,释放SDA线并监视一个应答信号,一旦收到应答信号,它将继续发送数据。如果主机没有 发出应答信号,即主机发送了一个“非应答”信号,24C02则停止传输数据,且等待一个停止信号。
5.2 字节写
24C02在设备地址接收完成之后,应答主机,然后接收一个8位的字节地址。接收完字节地址后,应答主机,然后开始接收一个8位的数据。在接收完8位数据后,应答主机。24C02的停止信号,必须有主机发出。
5.3 页写
页写的初始化过程与字节写相同,只是主机不会在第一个数据之后发生停止信号,而是在24C02应答主机后,接着发送7个数据。24C02收到每个数据后都会应答,最后由主机发送停止信号。
接收到每个数据后,24C02字节地址的低3位内部会自动加1,高位地址不变,维持在当前页内。当内部产生的字节地址达到该页边界时,随后的数据将写入该页的页首,而先前的字节将会被覆盖。为什么会这样?
因为24C02内部的页写缓冲器是8个字节的。每一个写入24C02中的数据都不是直接写入EEPROM内,而是先写到页写缓冲器,待数据传送结束后再一次写入EEPROM内部。
5.4 当前地址读
24C02内部地址寄存器保存着上次读/写操作最后一个地址加1的值。只要该芯片有电,该地址就一直保存着。若上次读/写的操作地址为N,则当前读地址从N+1开始。当读到最后页的最后字节(即255地址处),地址会回转到0地址。
5.5 字节读
主机首先通过发送起始信号,接着发送24C02的设备地址和它想要读取的数据所在的字节地址,执行一个伪写操作。
在24C02应答主机之后,主机重新发送起始信号和从设备地址,进行读操作,24C02响应并发送应答信号,然后输出所要求的一个8位字节数据。主机接收完这个8位数据后,不发送应答信号,而是产生一个“非应答”信号,然后发送一个停止条件。
5.6 连续读
在24C02发送完一个8位字节数据之后,主机产生一个应答信号来响应,告知24C02要求读取更多的数据,直到读完最后一个数据后,向24C02发送一个“非应答”信号,然后发送一个停止信号,结束此操作。
6.瑞萨单片机RL78/G13系列单片机IIC接口开发技术
本应用案例采用瑞萨的RL78/G13系列单片机R5F100BE,该单片机有32个引脚,内部外设功能较多,有多路IIC接口,本例选用了IICA0通道,也就是P6.0用做SCL,P6.1用做SDA。
开发环境为CubeCuite+,仿真器为EZ-CUBE,目标板为:瑞萨入门套件HRF100BS-V2.0。
<ignore_js_op>
图片24.png (47.4 KB, 下载次数: 0)
下载附件 保存到相册
2016-4-9 14:33 上传
<ignore_js_op>
图片25.png (113.39 KB, 下载次数: 0)
下载附件 保存到相册
2016-4-9 14:33 上传
6.1 IIC接口的参数配置
使用CubeSuite+自带的Code Generator(Design Tool)功能,生产程序框架及接口驱动程序。首先双击“Clock Genneral”设置“PIOR register”,在右侧的工作窗口中选择“Pin assignment”选项卡,直接点击下方的“Fix settings”设置PIOR = 0x00。注意,该值一旦设定,就不能再进行更改了。
<ignore_js_op>
图片26.png (58.03 KB, 下载次数: 0)
下载附件 保存到相册
2016-4-9 14:35 上传
设置Clock setting,该参数采用默认设置,使用内部的32MHz振荡器,将On-chip debug setting选择设置为使用在线调试模式。
<ignore_js_op>
图片27.png (30.68 KB, 下载次数: 0)
下载附件 保存到相册
2016-4-9 14:35 上传
双击左侧工作窗口的“Serial”选项,
进行串行通信接口设置。在“General setting”下,选择“IICA0”选项,在“Transfer mode”选项卡中将其设置为单主模式。
<ignore_js_op>
图片28.png (26.24 KB, 下载次数: 0)
下载附件 保存到相册
2016-4-9 14:35 上传
在“Setting”选项卡中设置IICA0的各项参数,时钟用默认设置fCLK/2,本地地址不需要设置,传输速率可根据设置的传输时钟确认速度,在本例中,采用默认的设置。设置发送接收数据完成的函数,如图。
<ignore_js_op>
图片29.png (64.34 KB, 下载次数: 0)
下载附件 保存到相册
2016-4-9 14:35 上传
至此,IICA0的参数设置已经完成,接下来,将看门狗关闭,在右侧上方的菜单选卡中点击“Generate Code”,即可生产框架代码和接口驱动函数。
<ignore_js_op>
图片30.png (64.57 KB, 下载次数: 0)
下载附件 保存到相册
2016-4-9 14:35 上传
6.2 IIC接口的函数介绍
IICA0相关的代码在“r_cg_serial.c”和“r_cg_serial_user.c”两个文件之中,前者为系统生成的接口驱动函数,后者为给用户准备的发送和接收完成的函数,这几个都是空函数,用户可以在里面添加数据发送和接收完成后的功能。
在“r_cg_serial.c”文件中,主要有5个函数:
void R_IICA0_Create(void);
void R_IICA0_Stop(void);
void R_IICA0_StopCondition(void);
R_IICA0_Master_Send(uint8_t adr,
uint8_t * const tx_buf,
uint16_t tx_num,
uint8_t wait);
R_IICA0_Master_Receive( uint8_t adr,
uint8_t * const rx_buf,
uint16_t rx_num,
uint8_t wait);
R_IICA0_Create(void)函数,是IICA0串行接口单元初始化函数,该函数在r_systeminit.c文件中的R_Systeminit()函数中被调用。对于我们开发人员来说,在应用编程过程中,不需要使用这个函数。
R_IICA0_Stop(void)函数和R_IICA0_StopCondition(void)函数都是IICA0停止的函数,对于开发人员来说,在编程中也是极少用到。与用户直接相应的是接收和发送函数。
IICA0的发送函数R_IICA0_Master_Receive,有四个参数:
参数1:设备地址。
参数2:发送数据缓冲区,是一个指针或数组名。
参数3:发送数据的长度。
参数4:每次发送数据后的延时时间。
调用该函数后,等待发送中断函数产生,当发送中断发送数据达到设定的数据长度后,数据发送完成函数r_iica0_callback_master_sendend(void)被调用,用户可以在该行数中进行后续的操作编程。
IICA0的接收函数R_IICA0_Master_Send,有四个参数:
参数1:设备地址。
参数2:接收数据缓冲区,是一个指针或数组名。
参数3:接收数据的长度。
参数4:每次发送数据后的延时时间。
调用该函数后,等待接收中断函数产生,当接收中断发送数据达到设定的数据长度后,数据发送完成函数r_iica0_callback_master_receiveend(void)被调用,用户可以在该行数中进行后续的操作编程。
6.3 读写主程序的应用开发
将6个字节的数据写到24C02的地址0,然后将其读出来存在一个数组中。
开发思路如下:
我们要将6个字节的数据写入24C02,但是我们在设置输出数据缓冲区的时候,不能设置6字节的数组,而应该设置一个7字节的数据,用第0个元素来存放字节地址,第1元素到第6元素才是要发送的数据,这样的话,就可以利用发送函数一次将字节地址和数据一次传送过去。
在接收数据中,首先要将字节地址通过一个伪写操作发送过去,然后才能利用接收函数去接收相应的数据。
具体程序实现如下:
void main(){
unsigned char sendIIC[7] = {0,1,2,3,4,5,6};
unsigned char recvIIC[6],Addr_24C02;
Addr_24C02 = 0x00; //字节地址
sendIIC[0] = Addr_24C02; //将字节地址放在发送缓冲区的第一元素
R_IICA0_Master_Send(0xa0, sendIIC, 7,200); //发送数据
Addr_24C02 = 0x00; //字节地址
R_IICA0_Master_Send(0xa0,&Addr_24C02,1,200); //执行一个伪写操作
R_IICA0_Master_Receive(0xa0,recvIIC,6,200); //接收数据
}
7.结语
IIC接口是嵌入式应用开发的一个常用接口,无非也就是模拟时序和外设模块两种开发模式,只要掌握了IIC接口的通信规范和工作原理,不管是那种开发情况,都可以得心应手,这就是我们《大学》说的:物有本末,事有终始,知所先后,则近道矣。
============================================================================================================