//24C04读写程序
#include
#define CPU_F ((double)2000000)
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))
#define SDA_OUT P1DIR|=BIT2//数据端输出
#define SDA_IN P1DIR&=~BIT2//数据段输入
#define SDA_1 P1OUT|=BIT2//数据端置1
#define SDA_0 P1OUT&=~BIT2//数据端置0
#define SDA_VAL P1IN&BIT2
#define SCL_1 P1OUT|=BIT1
#define SCL_0 P1OUT&=~BIT1
//#define SCL_IN P1DIR&=~BIT1
#define SCL_OUT P1DIR|=BIT1
unsigned char ack=0;
void Start_24C04() //启动24C04,在SCL为高电平期间,SDA由高电平跳向低电平
{
SDA_OUT;
SCL_OUT;
SDA_1;
SCL_0;
delay_us(5);
SCL_1;
delay_us(5);
SDA_0;
delay_us(5);
SCL_0;
delay_us(2);
}
void Stop_24C04()//停止24C02,在SCL为高电平期间,SDA由低电平跳向高电平
{
SDA_OUT;
SDA_0;
SCL_0;
delay_us(5);
SCL_1;
delay_us(5);
SDA_1;
delay_us(5);
}
void Ack(void) //IIC总线应答,SCL为高电平时,SDA为低电平
{
SDA_OUT;
SDA_0;
SCL_0;
delay_us(5);
// SCL_OUT;
SCL_1;
delay_us(5);
SCL_0;
delay_us(5);
SDA_1;
}
void NoAck(void) //IIC总线无应答,SDA维持高电平,SCL产生一个脉冲
{
SDA_OUT;
SDA_1;
SCL_0;
delay_us(5);
// SCL_OUT;
SCL_1;
delay_us(5);
SCL_0;
delay_us(5);
}
/*从器件地址sla,子地址suba,读出的内容放入s指向的存储区,读no个字节。如果返回1表示操作成功,否则操作有误。*/
unsigned char RcvByte() //用来接收从器件传来的数据,并判断总线错误
{
unsigned char retc=0;
unsigned char i;
//SDA_1;
SDA_IN; //置数据线为输入方式
for(i=0;i<8;i++)
{
delay_us(2);
SCL_0; //置时钟线为低,准备接收数据位
delay_us(5); //时钟低电平周期大于4.7us
SCL_1; //置时钟线为高使数据线上数据有效
delay_us(2);
retc=retc<<1;
if(SDA_VAL==BIT2)
retc=retc+1; //读数据位,接收的数据位放入retc中
delay_us(2);
}
SCL_0;
delay_us(2);
return(retc);
}
/*将数据c发送出去,发送数据正常,ack=1; ack=0表示被控器无应答或损坏。*/
void SendByte(unsigned char c)
{
unsigned char i;
SDA_OUT;
SCL_0;
for(i=0;i<8;i++) //要传送的数据长度为8位
{
if((c<
else SDA_0;
delay_us(5);
SCL_1; //置时钟线为高,通知被控器开始接收数据位
delay_us(5); //保证时钟高电平周期大于4μ
SCL_0;
delay_us(2);
}
delay_us(2);
//SDA_1; //8位发送完后释放数据线,准备接收应答位
//delay_us(2);
SDA_IN;
delay_us(5);
SCL_1;
delay_us(5);
if(SDA_VAL==BIT2)
ack=0;
else
ack=1; //判断是否接收到应答信号
SCL_0;
delay_us(2);
}
unsigned char Read_data(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no)
{
unsigned char i;
Start_24C04(); //启动总线
SendByte(sla); //发送器件地址
if(ack==0)return(0);
SendByte(suba); //发送器件子地址
if(ack==0)return(0);
Start_24C04();
SendByte(sla+1);
if(ack==0)return(0);
for(i=0;i
{
*s=RcvByte(); //发送数据
Ack(); //发送就答位
s++;
}
*s=RcvByte();
NoAck(); //发送非应位
Stop_24C04(); //结束总线
return(1);
}
unsigned char Save_data_c(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no)
{
unsigned char i;
Start_24C04(); //启动总线
SendByte(sla); //发送器件地址
if(ack==0)return(0);
SendByte(suba); //发送器件子地址
if(ack==0)return(0);
for(i=0;i
{
SendByte(*s); //发送数据
if(ack==0)return(0);
s++;
}
Stop_24C04(); //结束总线
return(1);
}
#include
#define uchar unsigned char
extern unsigned char Save_data_c(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no);
extern unsigned char Read_data(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no);
uchar e=3,f=0;
int main()
{
WDTCTL = WDTPW + WDTHOLD;
Save_data_c(0xa8,0,&e,1);//引脚A2接Vcc,A1和A0接地,故器件地址为a8
Read_data(0xa8,0,&f,1);
while(1);
}
我也不知道些没写进去,反正读是读不出来的,请各位大神给指点下,万分感谢
sda和scl有没有使能上拉电阻,使能一下试试,或外加5.1k的上拉电阻
写数据完成后再延时一段时间再去读芯片,否则写入没有成功
能不能先移植到430F1系列上然后去PROTEUS里仿真一下。。PROTEUS里应该有24C04的
在数据变换参数的时候出了错,如果能仿真,可以尝试下