使用S3C2440的GPE14--SCL和GPE15--SDA来软件模拟IIC:
由于不清楚如何像51那样位定义,就特意进行了如下定义:
#define IIC_SDA_L (rGPEDAT = rGPEDAT & ~(1<<15))
#define IIC_SDA_H (rGPEDAT = rGPEDAT | (1<<15))
#define IIC_SCL_L (rGPEDAT = rGPEDAT & ~(1<<14))
#define IIC_SCL_H (rGPEDAT = rGPEDAT | (1<<14))
初始化:
void IIC_Init()
{
//GPE15--SDA GPE14--SCL
rGPEUP = 0xc000;
rGPECON = 0x50000000;
IIC_SCL_L;
IIC_SDA_H;
Delay_moment(10);
IIC_SCL_H;
}
START CONDITION:
A high-to-low transition of SDA with SCL high is a start condition which must precede any othe rcommand (refer to Start and Stop Definition timing diagram).
void IIC_Start()
{
IIC_SDA_H;
IIC_SCL_H;
Delay_moment(10);
IIC_SDA_L;
Delay_moment(15);
IIC_SCL_L;
Delay_moment(15);
}
STOP CONDITION:
A low-to-high transition of SDA with SCL high is a stop condition. After a read sequence, the stop command will place the EEPROM in a standby power mode (refer to Start and Stop Definition timing diagram).
void IIC_Stop()
{
IIC_SCL_L;
IIC_SDA_L;
Delay_moment(10);
IIC_SCL_H;
Delay_moment(20);
IIC_SDA_H;
Delay_moment(10);
}
是故写或读数据必须在SCL为低时,避免造成START和STOP的条件触发。
写8位数据:在SCL为低时把数据通过SDA输出,翻转SCL。
void Write_8bit(U32 data)
{
unsigned int i;
for(i=0;i<8;i++)
{
if(data & (1<<(7-i)))
IIC_SDA_H;
else
IIC_SDA_L;
Delay_moment(10);
IIC_SCL_H;
Delay_moment(10);
IIC_SCL_L;
}
Delay_moment(10);
}
读8位:在SCL为低时读取SDA上面的电平。
U8 Read_8bit()
{
unsigned int i;
U8 temp = 0;
rGPECON = 0x10000000; //SDA input
Delay_moment(10);
for(i=0;i<8;i++)
{
IIC_SDA_H;
if(rGPEDAT & (1<<15))
temp |= (1<<(7-i));
Delay_moment(10);
IIC_SCL_H;
Delay_moment(10);
IIC_SCL_L;
Delay_moment(10);
}
rGPECON = 0x50000000; //SDA output
IIC_SDA_H;
Delay_moment(10);
return temp;
}
应答ACKNOWLEDGE:
All addresses and data words are serially transmitted to and from the EEPROM in 8-bit words. The EEPROM sends a zero to acknowledge that it has received each word. This happens during the ninth clock cycle.
在第9个时钟的高电平读取SDA。为0则正确应答。
U8 Acknowledge()
{
unsigned char temp;
rGPECON = 0x10000000; //SDA input
Delay_moment(30);
IIC_SCL_H;
Delay_moment(10);
temp = rGPEDAT & (1<<15); //read SDA
Delay_moment(10);
IIC_SCL_L;
Delay_moment(10);
rGPECON = 0x50000000; //SDA output
Delay_moment(30);
if(temp)
return 1; //ACK fault
else
return 0; //ACK OK
}
写操作,可以连续写多个字节。
void IIC_Write_nByte(U32 slave_addr,U32 IIC_addr,U8 byte_Count,U8 *WriteData)
{
unsigned int i;
IIC_Start();
Write_8bit(slave_addr | 0);
if(Acknowledge()) //if return 1,exit
{
IIC_Stop();
return;
}
Write_8bit(IIC_addr); //写数据的起始地址
if(Acknowledge())
{
IIC_Stop();
return;
}
for(i=0;i
Write_8bit(WriteData[i]);
if(Acknowledge())
{
IIC_Stop();
return;
}
}
IIC_Stop();
}
读操作:读操作必须要先写设备地址和数据起始地址,然后再写设备地址(带读标志),读的最后一个字节NO ACK。
void IIC_Read_nByte(U32 slave_addr,U32 IIC_addr,U8 byte_Count,U8*ReadBuffer)
{
unsigned int i;
IIC_Start();
Write_8bit(slave_addr | 0); //第一次写设备地址,写操作
if(Acknowledge())
{
IIC_Stop();
return;
}
Write_8bit(IIC_addr); //写数据起始地址
if(Acknowledge())
{
IIC_Stop();
return;
}
IIC_Start(); //Restart
Write_8bit(slave_addr | 0x01); //写设备地址,带读操作
if(Acknowledge())
{
IIC_Stop();
return;
}
for(i=0;i
ReadBuffer[i] = Read_8bit();
if(Acknowledge())
{
IIC_Stop();
return;
}
}
ReadBuffer[byte_Count-1] = Read_8bit(); //读的最后一个数据,不判断ACK,直接结束
IIC_Stop();
}
写6位:IIC_Write_nByte(0xa0,0x11,6,&(WriteBuffer[0]));
读6位:IIC_Read_nByte(0xa0,0x11,6,&(databuffer[0]));
上一篇:S3C2440中断分析
下一篇:S3C2440 测试程序(七) IIC实验1--读写EEPROM(不开中断)
推荐阅读最新更新时间:2024-03-16 15:23
- 热门资源推荐
- 热门放大器推荐