实验11 IIC 总线应用实验

总线的长度可高达25 英尺,并且能够以10Kbps 的最大传输速率支持40 个组件。IIC 总线的另一个优点是,它支持多主控(multimastering), 其中任何能够进行发送和接收的设备都可以成为主总线。一个主控能够控制信号的传输和时钟频率。当然,在任何时间点上只能有一个主控。IIC 总线的数据传送速率在标准工作方式下为100kbit/s,快速方式下最高传送速率达400kbit/s。

每个电路和模块都有唯一的地址,在信息的传输过程中,IIC 总线上并接的每一模块电路既是主控器(或被控器),又是发送器(或接收器),这取决于它所要完成的功能。CPU 发出的控制信号分为地址码和控制量两部分,地址码用来选址,即接通需要控制的电路,确定控制的种类;控制量决定该调整的类别(如对比度、亮度等)及需要调整的量。

IIC 总线在传送数据过程中共有三种类型信号, 它们分别是:开始信号、结束信号和应答信号
开始信号:SCL 为高电平时,SDA 由高电平向低电平跳变,开始传送数据。
结束信号:SCL 为低电平时,SDA 由低电平向高电平跳变,结束传送数据。
应答信号:接收数据的IC 在接收到8bit 数据后,向发送数据的IC 发出特定的低电平脉冲,表示已收到数据。CPU 向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU 接收到应答信号后,根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为受控单元出现故障。

写操作分为字节写和页面写两种操作,对于页面写根据芯片的一次装载的字节不同有所不同。

 

读操作有三种基本操作:当前地址读、随机读和顺序读。应当注意的是:最后一个读操作的第9 个时钟周期不是“不关心”。为了结束读操作,主机必须在第9 个周期间发出停止条件或者在第9 个时钟周期内保持SDA 为高电平、然后发出停止条件。

Tx/Rx 操作之间需要做的工作

在任何 IIC Tx/Rx 操作之前,向IICADD 寄存器写入器件地址。

设置 IICCON 寄存器。

允许中断。

定义 SCL 的时钟周期。

设置 IICSTAT 来允许串行输出。

 

11.1 测试函数

void Test_IIC(void)
{
unsigned int i,j;
static U8 data[256];
Uart_Printf("IIC Test(Polling) using AT24C02\n");
//设置GPE15->IICSDA 和GPE14->IICSCL
rGPEUP |= 0xc000; //Pull-up disable
rGPECON &= ~0xf0000000;
rGPECON |= 0xa0000000; //GPE15:IICSDA , GPE14:IICSCL
//Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
//********************************************
//在Rx 模式下访问EEPROM 时,为了产生停止条件,在读取最后一个字节数据之后不允许产生ACK信号。
//IIC 总线上发生中断的条件: 1) 当一个字节的读写操作完成时; 2) 当一个通常的通话发生或者是从地址匹配上时; 3)总线仲裁失败时。
//如果IICCON[5]=0,IICCON[4]就不能够正常工作了。因此,建议务必将IICCON[5]设置为1,即使你暂时并不用IIC 中断。  
rIICCON = (1<<7) | (0<<6) | (1<<5) | (0xf); //IICCON ――IIC 总线控制寄存器,0xaf
rIICADD = 0x10; //IICADD―― IIC 地址寄存器,2440 slave address = [7:1]
rIICSTAT = 0x10; //IICSTAT ――IIC 状态寄存器,IIC bus data output enable(Rx/Tx)
Uart_Printf("Write test data into AT24C02\n");
//写入一个page 的数据,page 的大小是256byte,
//page 的起始地址是0xa0,写入的数据是:0、1、2、...255。0xa0 是AT24C02 的页地址。
//AT24C02 的页地址是0x00/0x20/0x40/0x60/0x80/0xa0/0xc0/0xe0。
for(i=0;i<256;i++)
Wr24C02(0xa0,(U8)i,i);//U32 slvAddr,U32 addr,U8 data
//初始化data 数组的值为0。
for(i=0;i<256;i++)
data[i] = 0;
Uart_Printf("Read test data from AT24C02\n");
//读24C02 的0xa0 地址中数据到data 数组中。
for(i=0;i<256;i++)
Rd24C02(0xa1,(U8)i,&(data[i]));
//输出data 数组接收数据的值
for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
Uart_Printf("%2x ",data[i*8+j]);
Uart_Printf("\n");
}
Uart_Printf("OK! Write data is same to Read data!\n");
}



 

11.2 写EEPROM 程序

void Wr24C02(U32 slvAddr,U32 addr,U8 data)
{
iicMode = WRDATA;
iicPt = 0;
iicData[0] = (U8)addr;
iicData[1] = data;
iicDataCount = 2;
//8-bit data shift register for IIC-bus Tx/Rx operation.
rIICDS = slvAddr; //IICDS ――IIC 移位数据寄存器,0xa0
//Master Tx mode, Start(Write), IIC-bus data output enable
//Bus arbitration sucessful, Address as slave status flag Cleared,
//Address zero status flag cleared, Last received bit is 0
rIICSTAT = 0xf0;
//Clearing the pending bit isn't needed because the pending bit has been cleared.
while(iicDataCount!=-1)
Run_IicPoll();
iicMode = POLLACK;
while(1)
{
rIICDS = slvAddr;
iicStatus = 0x100; //To check if _iicStatus is changed
rIICSTAT = 0xf0; //Master Tx, Start, Output Enable, Sucessful, Cleared, Cleared, 0
rIICCON = 0xe0;//0xaf; //Resumes IIC operation. //hzh
while(iicStatus==0x100)
Run_IicPoll();
if(!(iicStatus & 0x1))
break; //When ACK is received
}
rIICSTAT = 0xd0; //Master Tx condition, Stop(Write), Output Enable
rIICCON = 0xe0;//0xaf; //Resumes IIC operation. //hzh
Delay(1); //Wait until stop condtion is in effect.
//Write is completed.
}


 

11.3 从EEPROM 中读出数据的程序

void Rd24C02(U32 slvAddr,U32 addr,U8 *data)
{
iicMode = SETRDADDR;
iicPt = 0;
iicData[0] = (U8)addr;
iicDataCount = 1;
rIICDS = slvAddr;
rIICSTAT = 0xf0; //MasTx,Start
//Clearing the pending bit isn't needed because the pending bit has been cleared.
while(iicDataCount!=-1)
Run_IicPoll();
iicMode = RDDATA;
iicPt = 0;
iicDataCount = 1;
rIICDS = slvAddr;
rIICSTAT = 0xb0; //Master Rx,Start
rIICCON = 0xe0;//0xaf; //Resumes IIC operation.
while(iicDataCount!=-1)
Run_IicPoll();
*data = iicData[1];
}


 

11.4 IIC Poll 程序

void Run_IicPoll(void)
{
if(rIICCON & 0x10) //Tx/Rx Interrupt Enable
IicPoll();
}
void IicPoll(void)
{
U32 iicSt,i;
iicSt = rIICSTAT;
if(iicSt & 0x8){} //When bus arbitration is failed.
if(iicSt & 0x4){} //When a slave address is matched with IICADD
if(iicSt & 0x2){} //When a slave address is 0000000b
if(iicSt & 0x1){} //When ACK isn't received
switch(iicMode)
{
case POLLACK:
iicStatus = iicSt;
break;
case RDDATA:
if((iicDataCount--)==0)
{
iicData[iicPt++] = rIICDS;
rIICSTAT = 0x90; //Stop MasRx condition
rIICCON = 0xe0;//0xaf; //Resumes IIC operation.
Delay(1); //Wait until stop condtion is in effect.
//Too long time...
//The pending bit will not be set after issuing stop condition.
break;
}
iicData[iicPt++] = rIICDS;
//The last data has to be read with no ack.
if((iicDataCount)==0)
rIICCON = 0x60;//0x2f; //Resumes IIC operation with NOACK.
else
rIICCON = 0xe0;//0xaf; //Resumes IIC operation with ACK
break;
case WRDATA:
if((iicDataCount--)==0)
{
rIICSTAT = 0xd0; //stop MasTx condition
rIICCON = 0xe0;//0xaf; //resumes IIC operation.
Delay(1); //wait until stop condtion is in effect.
//The pending bit will not be set after issuing stop condition.
break;
}
rIICDS = iicData[iicPt++]; //_iicData[0] has dummy.
for(i=0;i<10;i++); //for setup time until rising edge of IICSCL
rIICCON = 0xe0;//0xaf; //resumes IIC operation.
break;
case SETRDADDR:
if((iicDataCount--)==0)
{
break; //IIC operation is stopped because of IICCON[4]
}
rIICDS = iicData[iicPt++];
for(i=0;i<10;i++); //for setup time until rising edge of IICSCL
rIICCON = 0xe0;//0xaf; //resumes IIC operation.
break;
default:
break;
}
}


 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值