6. S5PC100下的I2C控制器介绍
S5PC100处理器支持多主机I2C串行总线接口,并且它支持主机发送模式、主机接收模式、从机发送模式和从机接收模式4种模式,图4所示为I2C总线的概括图。
图4 I2C总线的概括图
7. I2C总线控制寄存器详解
表1为I2C总线控制寄存器描述。
表1 I2C总线控制寄存器
I2CCON |
位 |
描 述 |
复 位 值 |
应答产生 |
[7] |
IIC应答产生使能位
0 = 禁止 1 = 使能
|
0 |
Tx时钟源选择 |
[6] |
IIC传输时钟预分值选择位
0 = I2CCLK = fPCLK /16
1= I2CCLK = fPCLK /512
|
0 |
Tx/Rx中断 |
[5] |
I C-Bus Tx/Rx 中断控制位
0 = 禁止 1 = 使能
|
0 |
传输时钟值 |
[3:0] |
IIC总线时钟预分值
Tx clock = I2CCLK/(I2CCON[3:0]+1)
|
未定义 |
表2为I2C状态寄存器描述。
表2 I2C状态寄存器
I2CSTAT |
位 |
描 述 |
复 位 值 |
模式选择 |
[7:6] |
IIC总线主/从Tx/Rx模式选择位
00=从机接收模式
01=从机发送模式
10=主机接收模式
11=主机发送模式
|
00 |
忙信号状态位 |
[5] |
IIC 总线忙信号状态位
读:0=准备
&nbsnbsp; 1=忙
写:产生开启信号
|
0 |
串行输出 |
[4] |
IIC总线数据输出使能/禁止位
0=禁止Rx/Tx 1=使能Rx/Tx
|
0 |
Ar位定量状态标志 |
[3] |
0=定量成功
1=失效
|
0 |
从地址状态标志 |
[2] |
0=当开启/停止条件侦测到时清除
1=接收到的从地址匹配I2CADD的地址值
|
0 |
地址0状态标志 |
[1] |
0=当开启/停止条件侦测到时清除
1=接收从地址值为00000000b
|
0 |
后的接收位状态标志 |
[0] |
0=为0
1=为1
|
0 |
表3为I2C数据发送/接收移位寄存器描述。
表3 I2C数据发送/接收移位寄存器
I2CDS |
位 |
描 述 |
复 位 值 |
保留位 |
[31:8] |
保留位,没有使用 |
未定义 |
数据移位 |
[7:0] |
8位数据移位寄存器
如果串行输出使能,则I2CDS将变为可写。并且
I2CDS任何时刻都是可读的,不管当前I2CSTAT的设置
|
未定义 |
8. 电路原理分析
结合上面已经提到的I2C理论基础,将以一个例子来进行实际讲解,用I2C来操作LM75温度传感器。
图5所示为LM75的原理图。
图5 LM75原理图
可以看到SDA/SCL被接到了S5PC100的IIC控制器上,并且接了一个外部中断,该中断可作为从机应答信号。
下面简单介绍一下LM75的操作时序,其操作时序的第一部分如图6所示。
图6 LM75操作时序第一部分
如图6所示显示了LM75操作时序的第一阶段,可以看到,如果要获取数据,需要先配置一下模式,并且LM75的从机地址为0x90,发送地址后要做的就是配置工作模式,LM75芯片提供了以下4种模式。
(1)温度(只读模式)。
(2)配置(读/写)。
(3)T(HYST读/写)。
(4)T(OS读/写)。
这里选择第一个即可,也就是发送0x0,接着有如图7所示的时序。
图7 时序第二部分
接下来再次发送从机地址,选择LM75芯片后,即可等待芯片回送数据,这时芯片会发送给主机端两次数据,第一次是主要值,第二次是小数部分,小能精确到0.5。要注意的是每一次都要进行应答,才能保证数据的有效性。
9. 代码实现
1.寄存器定义
/*IIC寄存器结构体定义*/
/*
*I2C0 REGISTERS
*/
typedef struct {
unsigned int I2CCON0 ;
unsigned int I2CSTAT0 ;
unsigned int I2CADD0 ;
unsigned int I2CDS0 ;
unsigned int I2CLC0 ;
}i2c0;
#define I2C0 (* (volatile i2c0 *)0xEC100000 )
/*设置GPIO*/
void cfg_gpio(void)
{
GPD.GPDCON=(GPD.GPDCON&(~((0X0f<<12)|(0x0f<<16))))+((2<<12) | (2<<16)) ;
}
/*写入LM75要读取的地址,然后读出2字节的温度数据*/
int set_pointer_and_read_2byte(int mode)
{
I2C0.I2CDS0 = 0x90; /*LM75 SLAVE ADDRESS 第0位为0 代表接下来是要写入数据*/
I2C0.I2CCON0 = 0xe0; /*ENABLE ACK BIT, PRESCALER:512 ,RX/TX INTERRUPT ENABLE ,*/
I2C0.I2CSTAT0 =0xf0; /*Master Trans mode ,START ,ENABLE RX/TX ,*/
while(!(I2C0.I2CCON0&(1<<4))); /*The end of the waiting to be sent */
I2C0.I2CDS0 = mode; // READ TEMPERATURE ONLY
I2C0.I2CCON0 &= ~(1<<4); /* Clear pending condition & Resume the operation */
while(!(I2C0.I2CCON0&(1<<4))); /*The end of the waiting to be sent */
// 以上是主机发送一个从机地址和一个从机的命令
I2C0.I2CDS0 = 0x91; /*Again to send LM75 salve address 第0位为1 代表接下来是要读出数据*/
I2C0.I2CSTAT0 =0xb0; /*Master receive mode ,START ,ENABLE RX/TX ,*/
I2C0.I2CCON0 &= ~(1<<4); /* Clear pending condition & Resume the operation */
while(!(I2C0.I2CCON0&(1<<4))); /*The end of the waiting to be sent */
I2C0.I2CCON0 &= ~(1<<4); /* Clear pending condition & Resume the operation */
while(!(I2C0.I2CCON0&(1<<4))); /*The end of the waiting to read */
high = I2C0.I2CDS0; /*read temperature of low 8 bit */
I2C0.I2CCON0 &= ~((1<<7)|(1<<4));
/* Clear pending condition & Resume the operation & no ack*/
while(!(I2C0.I2CCON0&(1<<4))); /*The end of the waiting to read */
low = I2C0.I2CDS0; /*read temperature of low 2 bit */
I2C0.I2CSTAT0 &= ~(1<<5); /*STOP signal generation,free bus */
I2C0.I2CCON0 &= ~(1<<4); /*clean interrup pending bit */
return ((high << 8) | low);
}
int main()
{
volatile int delay;
int low, high, temp, config, i;
uart0_init();
cfg_gpio();
/*循环打印采集的数据*/
while (1){
read_data_one(); // 配置模式
temp = read_data_two(); // 开始连续两次读数据
high = temp >> 8;
low = temp & 0xff;
printf("TEMP is : %d.%d\n", high, (((low>>7)==0) ? 0 : 5));
}
return 0;
}
2.实验调试过程与结果
编译生成的.elf文件,连接硬件。并连接好FS_JTAG仿真器套件。将程序编译后获得.elf文件,将该文件通过仿真器下载并运行在目标板上,终端打印信息如图8所示。
TEMP is :22.5
TEMP is :22.5
TEMP is :23.0
TEMP is :23.0
TEMP is :23.0
TEMP is :23.5
TEMP is :23.5
TEMP is :23.5
TEMP is :23.5
TEMP is :23.5
TEMP is :23.5