完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
基于PIC24FJ256GB106读写ROM 24C1024时,读出数据总是不对,哪位大牛给看看呀
读出数据一直都是0xffff,不知道问题出在哪里呀呀 #include void Initi2C(void); void WaitMI2C(void); void I2C_write(unsigned char data); void I2C_BYTE_WRITE(unsigned char addhigh,unsigned char addmid,unsigned char addlow,unsigned char data); unsigned char I2C_BYTE_READ(unsigned char addhigh,unsigned char addmid,unsigned char addlow); void I2C_ACK_CHECK(void); #define StartI2C() I2C1CONbits.SEN=1 //启动I2C #define StopI2C() I2C1CONbits.PEN=1 //停止I2C #define RstartI2C() I2C1CONbits.RSEN=1 //重新启动I2C #define NACKI2C() I2C1CONbits.ACKDT=1;I2C1CONbits.ACKEN=1 //发送不应答信号 #define ACKI2C() I2C1CONbits.ACKDT=0;I2C1CONbits.ACKEN=1 //发送应答信号 #define RecI2C() I2C1CONbits.RCEN=1 //使能接收允许位 #define CMD_W24C01 0XA0 #define CMD_R24C01 0XA1 unsigned char I2C_Data; //读写24C01的数据暂存单元 unsigned char I2C_Addr; //读写24C01的地址暂存单元 unsigned char I2C_DATA_BACK; //写入24C01的数据备份单元 unsigned char I2C_STEP = 0; //调试变量,一旦I2C死机,监视执行到哪个步骤死机 void delay_ms(unsigned char count) //1ms延时 { unsigned int i,j; for(i = 0 ; i < count ; i++) { for(j = 0 ; j < 0x2eda; j++); } } int main(void) { CLKDIV = 0; //CPU时钟为32MHZ,外设总线与CPU时钟一致 while(OSCCONbits.LOCK == 0); //等待PLL时钟稳定,如果上电后有重要IO要马上设置,此语句可挪到IO初使化后 _DISI = 1 ; //使能DISI指令,某些内建函数需要配合DISI指令操作 CM2CON = 0 ; //模拟比较器2关闭,RB0~3的比较器复用功能关闭 ODCB &= 0x0000 ; //RB0~3设置为正常的双向口,其它不变 AD1PCFGL |= 0xFFFF ;//AN0~3设置为数字口,其它不变 TRISB &= 0X0000 ; //TRISB低4位清0,置输出 //实验板L4~L1,默认分别对应RB3~0,全亮 InitI2C(); I2C_Addr = 0x66; //0到127之间有效 I2C_Data=0x49; I2C_DATA_BACK = 0X49; I2C_BYTE_WRITE(0x00,0x00,I2C_Addr,I2C_Data); // I2C_ACK_CHECK(); //dsPIC30/PIC24可直接调用此函数后进行读,PIC32还得加延时(错误:执行该语句便进入死循环) LATB=0x0002; delay_ms(1000); delay_ms(1000); delay_ms(1000); delay_ms(1000); delay_ms(1000); delay_ms(1000); delay_ms(1000); delay_ms(1000); I2C_Data = 0; I2C_Data = I2C_BYTE_READ(0x00,0x23,I2C_Addr); //如果读回来的即为写下去的0x49,读写都OK, //如果读回来为0XFF,未必代表写失败。 LATB=I2C_Data&0X000F ; //LATB低4位送1,其它不变 while(1); } /* 函数功能:I2C初使化 入口参数:无 出口参数:无 调用说明:无 */ void InitI2C(void) { _ODD9 = 1; //RD9/10设置OC功能打开 _ODD10 = 1; // LATDbits.LATD9 = 1; LATDbits.LATD10 = 1; TRISDbits.TRISD9 = 1; TRISDbits.TRISD10 = 1; I2C1CON = 0X8000; I2C1STAT = 0; I2C1BRG = 159; //16mips,调整到接近100KHZ } /* 函数说明:通用的等待I2C各种动作完成函数 入口参数:无 出口参数:无 调用说明:无 */ void WaitMI2C(void) { while(_MI2C1IF == 0); //判断MI2CIF以判定各种动作是否完成 Nop(); Nop(); _MI2C1IF = 0; //清标志位 } void I2C_write(unsigned char data) { while (I2C1STATbits.TBF); //传输正在进行中,等待 I2C1TRN = data; //写入数据 } void I2C_BYTE_WRITE(unsigned char addhigh,unsigned char addmid,unsigned char addlow,unsigned char data) { unsigned char temp_i2cdata,add; StartI2C(); //1, 启动I2C WaitMI2C(); //等待启动完成 add=CMD_W24C01|addhigh; I2C_write(add); //2, 送入命令, //地址+读写方式,地址为101 0000 ,写方式=0 WaitMI2C(); //等待写入完成 temp_i2cdata = I2C1RCV; // I2C_write(addmid); //3,要操作24C1024的高地址值发送到I2C总线 WaitMI2C(); temp_i2cdata = I2C1RCV; // I2C_write(addlow); //3,要操作24C1024的地址值发送到I2C总线 WaitMI2C(); temp_i2cdata = I2C1RCV; // I2C_write(data); //4,要写入24C01的数据值发送到I2C总线 WaitMI2C(); temp_i2cdata = I2C1RCV; // StopI2C(); //5,发送停止信号 WaitMI2C(); // // } unsigned char I2C_BYTE_READ(unsigned char addhigh,unsigned char addmid,unsigned char addlow) { unsigned char data; unsigned char temp_i2cdata,add_w,add_r; StartI2C(); //1, 启动I2C WaitMI2C(); //等待启动完成 add_w=CMD_W24C01|addhigh; I2C_write(add_w); //2, 送入命令, //地址+读写方式,地址为101 0000 ,写方式=0 WaitMI2C(); //等待写入完成 temp_i2cdata = I2C1RCV; // I2C_write(addmid); //3,要操作24C1024的高地址值发送到I2C总线 WaitMI2C(); temp_i2cdata = I2C1RCV; // I2C_write(addlow); //3,要操作24C1024的地址值发送到I2C总线 WaitMI2C(); temp_i2cdata = I2C1RCV; // RstartI2C(); //4,发送重启动信号 WaitMI2C(); add_r=CMD_R24C01|addhigh; I2C_write(add_r); //5, 送入命令, //地址+读写方式,地址为101 0000 ,读方式=1 WaitMI2C(); //等待写入完成 temp_i2cdata = I2C1RCV; // RecI2C(); //6,使能接收 WaitMI2C(); data = I2C1RCV; //7,保存数据 NACKI2C(); //8,发送非应答信号,停止从发送方的发送 WaitMI2C(); StopI2C(); //9,发送停止信号 WaitMI2C(); return (data); //10,返回读到的数据 } /* 函数功能;通过发读命令检测I2C总线是否空闲 入口参数:无 出口参数:无 调用说明:PIC24F/dsPIC30F上均可用,PIC32上还需配合延时函数 */ void I2C_ACK_CHECK(void) { do { StartI2C(); WaitMI2C(); I2C_write(CMD_R24C01); WaitMI2C(); StopI2C(); WaitMI2C(); LATB=I2C1STATbits.ACKSTAT&0X000F; } while(I2C1STATbits.ACKSTAT); } |
|
相关推荐
1个回答
|
|
是不是单片机复位时可以保存,并且存储的数据存储正常。但是断电后保存的数据不正常。
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-TF卡烧录流程之烧写过程
604 浏览 0 评论
894 浏览 0 评论
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-mfgtools烧录流程之烧写原理
979 浏览 0 评论
请问SPH0641LU4H这款麦克风如何在不使用I2S的情况下,单纯通过GPIO来进行驱动且正常读取数据呢
738 浏览 1 评论
483 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
12094 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-1 18:59 , Processed in 0.499810 second(s), Total 70, Slave 53 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号