新會員
Joined
: 2008/12/6 10:21 最後登入時間
: 2014/5/5 14:48
From HFUT
Group:
註冊會員
Level : 2 HP : 0 / 46 MP : 5 / 2097 EXP : 86
|
我在准程序中调用 了 unsigned char I2C_Byte_Read(unsigned char AddH,unsigned char AddL); void I2C_Byte_Write(unsigned char AddH,unsigned char AddL,unsigned char WriteByte);
Main程序中这么写的 I2C_Byte_Write(0x00,0x00,11); I2C_Byte_Write(0x00,0x02,99); I2C_Byte_Write(0x00,0x04,99); m_Values[7]=I2C_CurrentByte_Read(); m_Values[1]=I2C_Byte_Read(0x00,0x00); m_Values[2]=I2C_Byte_Read(0x00,0x04);
利用ICD2仿真器看看m_Values一直是零,但是发送好像是能够收到应答的,我查看了I2C_Error1,I2C_Error2,I2C_Error3都一直是零吧中断是没有写进去还是没有读出来。不知道问题出在哪里。请大家帮我看看,谢谢 #ifndef E2prom_h #define E2prom_h //#include <pic168xa.h> #include <pic.h>
#define D_SCL TRISC3 //SCL方向控制 #define D_SDA TRISC4 //SDA方向控制 #define SCL RC3 #define SDA RC4 #define WriteCommand 0xA0 //写命令字 #define ReadCommand 0xA1 //读命令字 char Ack_Temp=0; //用于检测应答,为0有应答,1无应答
char I2C_Error1=0;//0无通讯错误,1有通讯错误 char I2C_Error2=0; char I2C_Error3=0; char I2C_Error=0;
void Delays(unsigned char Time_delay); void I2C_Delay(unsigned char Time_delay); void I2C_Init(void); void I2C_Start(void); void I2C_Stop(void); void I2C_AckOut(void); void I2C_NAckOut(void); void I2C_AckRec(); void I2C_OneByteOut(unsigned char OneByte) ; unsigned char I2C_OneByteIn(void); //unsigned char I2C_ReadOneByte(); //unsigned int I2C_ReadOneWord(); void I2C_WriteAddress(unsigned char cmd,unsigned char addh,unsigned char addl); void I2C_Byte_Write(unsigned char AddH,unsigned char AddL,unsigned char WriteByte);
void I2C_Word_Write(unsigned char AddH,unsigned char AddL,unsigned char DataH,unsigned char DataL); void I2C_Page_Write(unsigned char AddH,unsigned char AddL,unsigned char Datanum,unsigned char *P_Data); unsigned char I2C_CurrentByte_Read(); unsigned char I2C_Byte_Read(unsigned char AddH,unsigned char AddL); unsigned int I2C_Word_Read(unsigned char AddH,unsigned char AddL); void I2C_Page_Read(unsigned char AddH,unsigned char AddL,unsigned char Datanum,unsigned char *P_Data); void I2C_WriteAll();
/*---------------------------------------------------------- 长延时程序 Time_delay=1时 延时250us -----------------------------------------------------------*/ void Delays(unsigned char Time_delay) { unsigned char i,j; for(i=0;i<=Time_delay-1;i++) {for(j=0;j<0xfd;j++)asm("nop");} }
/*-------------------------------------------------------- I2C总线延时程序 ---------------------------------------------------------*/ void I2C_Delay(unsigned char Time_delay) { unsigned char i; for(i=0;i<=Time_delay;i++) asm("nop"); }
/*-------------------------------------------------------- E2prom初始化设置 ---------------------------------------------------------*/ void I2C_Init(void) { D_SCL=0; D_SDA=0; SDA=1; SCL=1; }
/*--------------------------------------------------------- 在I2C总线上产生起始信号 ----------------------------------------------------------*/ void I2C_Start(void) { D_SCL=0; D_SDA=0; SCL=0; I2C_Delay(8); SDA=1; //SCL SDA为高电平 SCL=1; I2C_Delay(8); SDA=0; //SCL高时,SDA由1变0产生起始位 I2C_Delay(3); SCL=0; I2C_Delay(8); }
/*--------------------------------------------------------- 在I2C总线上产生停止信号 ----------------------------------------------------------*/ void I2C_Stop(void) { D_SCL=0; D_SDA=0; SCL=0; I2C_Delay(8); SDA=0; //确保SDA=0 SCL=1; //确保SCL=1 I2C_Delay(8); SDA=1; //SCL=1时,SDA有0变1产生停止位 SCL=0; I2C_Delay(8); } /*--------------------------------------------------------- 在I2C总线上产生应答信号 ----------------------------------------------------------*/ void I2C_AckOut(void) { D_SCL=0; D_SDA=0; SCL=0; I2C_Delay(8); SDA=0; //SDA=0 I2C_Delay(3); SCL=1; //产生时钟上升沿,产生应答 I2C_Delay(10); //准备发送应答 SCL=0; I2C_Delay(8); // SDA=1; I2C_Delay(8); }
/*--------------------------------------------------------- 在I2C总线上产生非应答信号 ----------------------------------------------------------*/ void I2C_NAckOut(void) { D_SCL=0; D_SDA=0; SCL=0; I2C_Delay(8); SDA=1; //SDA=1 I2C_Delay(8); SCL=1; //SCL=1产生时钟上升沿 I2C_Delay(8); //发送非应答 SCL=0; //时钟结束 I2C_Delay(8); // SDA=1; // I2C_Delay(8); }
/*---------------------------------------------------- 从总线上接受应答信号,存放到Ack_Temp中 -----------------------------------------------------*/ void I2C_AckRec() { //SCL=0;I2C_Delay(8); //SCL-1;I2C_Delay(8); //SCL=0;I2C_Delay(8); Ack_Temp=1; D_SCL=0; D_SDA=1; SDA=1; //SDA置高,准备接受应答 //I2C_Delay(8); SCL=1; //Ack_Temp=SDA; if(SDA)Ack_Temp=1; else Ack_Temp=0; I2C_Delay(3); SCL=0; // I2C_Delay(6); } /*-------------------------------------------------- 向E2PROM写一个字节 入口参数:OneByte是要写入的数 ---------------------------------------------------*/ void I2C_OneByteOut(unsigned char OneByte) { unsigned char i; D_SCL=0; D_SDA=0;
SCL=0; I2C_Delay(8); for(i=0;i<8;i++) { if(OneByte&0x80==0x80)SDA=1; else SDA=0; // I2C_Delay(10); SCL=1; I2C_Delay(10); OneByte=OneByte<<1; SCL=0; //SDA=0; } I2C_AckRec(); //接收从器件应答信号 } /*--------------------------------------------------- 从E2PROM读取一个字节数据 函数返回值:OneByte是从E2PROM读取的字节 ----------------------------------------------------*/ unsigned char I2C_OneByteIn() { unsigned char i, OneByte; D_SDA=1; SCL=0; OneByte=0; for(i=0;i<=7;i++) { SDA = 1; OneByte<<=1; //左移一位 SCL=1; I2C_Delay(5); if(SDA) OneByte|=0x01; else OneByte=OneByte&0xfe; I2C_Delay(5);asm("nop"); SCL=0; I2C_Delay(5); } //从i2c总线上读取字数据的高位字节 //D_SDA=0; return(OneByte); }
/*--------------------------------------------------- 向E2prom写地址高字节和地址低字节 入口参数:Cmd控制命令字 AddH,AddL分别是地址高八位好低八位 ----------------------------------------------------*/ void I2C_WriteAddress(unsigned char Cmd,unsigned char AddH,unsigned char AddL) { I2C_Start(); I2C_OneByteOut(Cmd); I2C_AckRec(); if(Ack_Temp==1) {I2C_Error1=1; return;} I2C_OneByteOut(AddH); if(Ack_Temp==1) { I2C_Error2=1; return;} I2C_OneByteOut(AddL); if(Ack_Temp==1) { I2C_Error3=1; return;} }
/*--------------------------------------------------- 向E2prom写一个字节,并产生停止位 入口参数:WriteByte 要写入的字节 AddH,AddL要写入的E2PROM的高低地址 ----------------------------------------------------*/ void I2C_Byte_Write(unsigned char AddH,unsigned char AddL,unsigned char WriteByte) { I2C_WriteAddress(WriteCommand,AddH,AddL); /*I2C_OneByteOut(WriteCommand); I2C_Delay(8); I2C_OneByteOut(AddH); I2C_Delay(8); I2C_OneByteOut(AddL); I2C_Delay(8); */ I2C_OneByteOut(WriteByte); if(Ack_Temp==1) { I2C_Error=1; return;} I2C_Stop(); }
/*--------------------------------------------------- 向E2prom写一个字,并产生停止位 入口参数:DataH 要写入字的高字节 DataL 要写入字的低字节 ----------------------------------------------------*/ void I2C_Word_Write(unsigned char AddH,unsigned char AddL,unsigned char DataH,unsigned char DataL) { I2C_WriteAddress(WriteCommand,AddH,AddL); I2C_OneByteOut(DataH); //送高字节 I2C_OneByteOut(DataL); //送低字节 I2C_Stop(); }
/*--------------------------------------------------- 向E2prom连续写一组数,(即按页写入) 入口参数:AddH,AddL 起始地址的高位和低位 Datanum 一次写入的字节数 *P_Data指向存放被写入的数据数组的指针 ----------------------------------------------------*/ void I2C_Page_Write(unsigned char AddH,unsigned char AddL,unsigned char Datanum,unsigned char *P_Data) { unsigned char i; I2C_WriteAddress(WriteCommand,AddH,AddL); for (i=0;i<Datanum;i++) { I2C_OneByteOut(*(P_Data+i)); } I2C_Stop(); Delays(0x0f); //延时 } void I2C_WriteAll() { unsigned int i,j; unsigned char k; I2C_WriteAddress(WriteCommand,0x00,0x00); for (i=0;i<1024;i++) { if(k==0)k=1; else if(k!=0)k=0; for(j=0;j<256;j++) {I2C_OneByteOut(11); I2C_Delay(8); I2C_OneByteOut(22);RA5=k; } } I2C_Stop(); Delays(0x0f); //延时 } /*-------------------------------------------------------- ---------------------------------------------------------*/ unsigned char I2C_CurrentByte_Read() { unsigned char CurrentByte; I2C_Start(); I2C_OneByteOut(ReadCommand); CurrentByte= I2C_OneByteIn(); I2C_Delay(5); I2C_NAckOut(); I2C_Stop(); return(CurrentByte); } /*------------------------------------------------------- 从E2PROM读取一个字节 入口参数:AddH,AddL是读取数据存放地址的高位好低位 函数返回值:从E2PROM读取的字节数据 ReadByte --------------------------------------------------------*/ unsigned char I2C_Byte_Read(unsigned char AddH,unsigned char AddL) { unsigned char ReadByte; I2C_WriteAddress(WriteCommand,AddH,AddL); I2C_Start(); I2C_OneByteOut(ReadCommand) ; //I2C_AckOut(); ReadByte= I2C_OneByteIn(); I2C_Delay(5); I2C_NAckOut(); I2C_Stop(); Delays(0xff); //延时 return(ReadByte); } /*------------------------------------------------------- 从E2PROM读取一个字节 入口参数:AddH,AddL是读取数据存放地址的高位好低位 函数返回值:从E2PROM读取的字节数据 ReadByte --------------------------------------------------------*/ unsigned int I2C_Word_Read(unsigned char AddH,unsigned char AddL) { unsigned char ReadWord; I2C_WriteAddress(WriteCommand,AddH,AddL); I2C_Start(); I2C_OneByteOut(ReadCommand); ReadWord= I2C_OneByteIn(); I2C_AckOut(); ReadWord=ReadWord<<8; I2C_Delay(8); ReadWord=ReadWord+I2C_OneByteIn(); I2C_NAckOut(); I2C_Stop(); Delays(0xff); //延时 return(ReadWord); } /*-------------------------------------------------------------- 向E2prom连续读取一组数,(即按页读) 入口参数:AddH,AddL 起始地址的高位和低位 Datanum 一次读出的字节数 *P_Data指向存放读出的数据数组的指针 ---------------------------------------------------------------*/ void I2C_Page_Read(unsigned char AddH,unsigned char AddL,unsigned char Datanum,unsigned char *P_Data) { unsigned char i; I2C_WriteAddress(WriteCommand,AddH,AddL); I2C_Start(); I2C_OneByteOut(ReadCommand); for(i=0;i<Datanum;i++) { *(P_Data+i)=I2C_OneByteIn(); if(i==Datanum) I2C_NAckOut(); else I2C_AckOut(); } I2C_Stop(); Delays(0xff); //延时 Delays(0xff); //延时 }
#endif
發表於: 2009/3/15 17:43
|