[讨论]
PIC16单片机写的一个24LC08的读写程序,为什么读出来是FF
#include
#define delay2408_TIME 2 //24C08的延迟时间
#define SCL1 RC3
#define SDA1 RC4
#define uchar unsigned char
#define uint unsigned int
void I2cinit(void)
{
//SSP1STAT=0x80;
SSP1CON1=0x28;
TRISC4=1; //SDA配置为输入;
delay2408(delay2408_TIME);
TRISC3=1; //SCL配置为输入;
delay2408(delay2408_TIME);
}
void delay2408(unsigned int t) //24c08的延时函数,微妙延迟
{
while(t--);
}
void I2C_Start(void)
{
/*启动I2C总线的函数,当SCL为高电平时使SDA产生一个负跳变*/
//SCL1=0;
SDA1=1;
delay2408(delay2408_TIME);
SCL1=1;
delay2408(delay2408_TIME);
SDA1=0;
delay2408(delay2408_TIME);
//SCL1=0;
//delay2408(delay2408_TIME);
}
void I2C_Stop(void)
{
/*终止I2C总线,当SCL为高电平时使SDA产生一个正跳变*/
//SCL1=0;
SDA1=0;
delay2408(delay2408_TIME);
SCL1=1;
delay2408(delay2408_TIME);
SDA1=1;
delay2408(delay2408_TIME);
//SCL1=0;
//delay2408(delay2408_TIME);
}
void SEND_0(void) /*SEND ACK*/
{
/*发送0,在SCL为高电平时使SDA信号为低*/
SDA1=0;
delay2408(delay2408_TIME);
SCL1=1;
delay2408(delay2408_TIME);
SCL1=0;
delay2408(delay2408_TIME);
}
void SEND_1(void)
{
/*发送1,在SCL为高电平时使SDA信号为高*/
SDA1=1;
delay2408(delay2408_TIME);
SCL1=1;
delay2408(delay2408_TIME);
SCL1=0;
delay2408(delay2408_TIME);
}
void Check_Acknowledge(void)
{
/*发送完一个字节后检验设备的应答信号*/
uchar a;
//SCL1=0;
//delay2408(delay2408_TIME);
//SDA1=1;
//delay2408(delay2408_TIME);
SCL1=1;
delay2408(delay2408_TIME);
a=255;
while(SDA1==1)
{
a--;
if(a==0)
{ SCL1=0;
}
}
SCL1=0;
delay2408(delay2408_TIME);
}
void WriteI2CByte(uchar b)
{
/*向I2C总线写一个字节*/
unsigned char i;
i=0;
for(i=0;i<8;i++)
{
if((b<
SEND_1();
else
SEND_0();
}
SDA1=1;
delay2408(delay2408_TIME);
}
unsigned char ReadI2CByte(void)
{
/*从I2C总线读一个字节*/
unsigned char b=0,i;
for(i=0;i<8;i++)
{
SCL1=0;
delay2408(delay2408_TIME);
//SDA1=1; /*释放总线*/
//delay2408(4);
SCL1=1; /*接受总线*/
delay2408(delay2408_TIME);
if(SDA1==1)
{
b=b<<1;
b=b|0x01;
}
else
b=b<<1;
delay2408(4);
SCL1=0;
}
return b;
}
/******24c08的读写函数********************/
void Write_One_Byte(unsigned char addr,unsigned char thedata)
{
I2C_Start();
WriteI2CByte(0xa0);
Check_Acknowledge(); //应答信号判断,这里应该需要确定它的应答信号
WriteI2CByte(addr);
Check_Acknowledge();
WriteI2CByte(thedata);
Check_Acknowledge();
I2C_Stop();
delay2408(2);
}
unsigned char Read_One_Byte(unsigned char addr)
{
unsigned char mydata;
/*read a byte from mem*/
I2C_Start();
WriteI2CByte(0xa0);
Check_Acknowledge();
WriteI2CByte(addr);
Check_Acknowledge();
I2C_Start();
WriteI2CByte(0xa1);
Check_Acknowledge();
mydata=ReadI2CByte();
delay2408(delay2408_TIME);
I2C_Stop();
return mydata;
}
void main()
{
unsigned char data;
data=0;
Write_One_Byte(0x20,0x21);
data=Read_One_Byte(0x20);
}
应该是I2C时序上的问题,你可以在protues中用I2C仪表去检查一下I2C总线。
pic16很久没有用过了,细节记得不清楚了。你这里主要就是IO模拟I2C,其他部分影响不大。
试了一下~还是不行。能帮我看看程序的问题出现在哪了吗?
在进行写数据和读数据时最好把SDA写和读时的方向寄存器TRISC进行设置一下