单片机学习小组
直播中

杨平

7年用户 151经验值
私信 关注

请问读写AT24C256的时序是扫描样吗?

最近在研究IIC通讯,做IIC读写AT24C256的程序,但是单片机用1M晶振可以正常运行,换成12M就出错,这应该就是时序的问题了,哪位大侠能帮我看看12M频率下应该把时序调整成扫描样呢??[C] 纯文本查看 复制代码
#ifndef AT24CXX_H_#define AT24CXX_H_#include #include #define    Wait_1us    _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_()#define    Wait_2us    {Wait_1us;Wait_1us;}#define    Sla_Wr       0xa0    /*0000 0 0 0 0*/#define    Sla_Rd       0xa1    /*0000 0 0 0 1*/#define    AT24C01      0x01#define    AT24C01A     0x02#define    AT24C02      0x03#define    AT24C04      0x04#define    AT24C08      0x05#define    AT24C16      0x06#define    AT24C32      0x07#define    AT24C64      0x08#define    AT24C128     0x09#define    AT24C256     0x0a#define    AT24C512     0x0b#define    Mem_Size    AT24C04     // 01/01A/02/04/08/16/32/64/128/256/512#define    Chip_1        0x00     //本器件的器件地址,可以第一8个不同地址的芯片使之能用同一段程序进行读写void Start_I2c(void);void End_I2c(void);unsigned char Scan_I2c();void Send_I2c(unsigned char cData);void Send_Ack(void);void Send_Not_Ack(void);void Write_Mem(unsigned char cMem_Size,cChips_Address,cData_Size,unsigned int cStart_Address);void Read_Mem(unsigned char cMem_Size,cChips_Address,cData_Size,unsigned int cStart_Address);#endif[C] 纯文本查看 复制代码
#ifndef AT24CXXX_C_#define AT24CXXX_C_#include "at24cxx.h"***it    bSda        =P0^0;***it    bScl        =P0^1;    bit bScan_Err;unsigned char idata cShare_Buf[8]={'P',1,2,3,4,5,6,7};    //I2c read and write buffervoid Start_I2c(void){ //   unsigned char /*idata*/ i;    bSda = 1;//    Wait_1us;    bScl = 1;//    for(i=0;i<32;i++);     //wait 7us     Wait_1us;    bSda = 0;//    for(i=0;i<32;i++);     //wait 7us    Wait_1us;    bScl = 0;    Wait_1us;}void End_I2c(void){//    unsigned char /*idata*/ i;    bSda=0;    Wait_1us;    bScl=1;//    for(i=0;i<16;i++);     //wait 7us    Wait_1us;    bSda = 1;    Wait_1us;}unsigned char Scan_I2c(){    unsigned char /*idata*/ i,j;//IIC data    bSda = 1;    j = 0;    for(i=0;i<8;i++)    {        bScl = 1;        j <<= 1;        Wait_1us;        j |= bSda;  //Scan 0    Scan 1        bScl=0;        Wait_1us;    }    return j;}void Send_I2c(unsigned char cData){    unsigned char /*idata*/ i;    for(i=0;i<8;i++)    {        bSda=(bit)(cData&0x80);        Wait_1us;        bScl=1;        cData<<=1;        Wait_1us;        bScl=0;        Wait_1us;    }    bSda=1;    Wait_1us;    bScl=1;     //检测ACK    for(i=0;(bSda==1)&&(bScan_Err==0);i++)    {        if(i==90)                    bScan_Err=1; //如果101us没有响应就错误    }    bScl=0;    Wait_1us;}void Send_Ack(void){//unsigned char /*idata*/ i;    bSda=0;    Wait_1us;    bScl=1;//    for(i=0;i<2;i++);    //wait 8us    Wait_1us;    bScl=0;    Wait_1us;}void Send_Not_Ack(void){//    unsigned char /*idata*/ i;    bSda = 1;    Wait_1us;          bScl = 1;//    for(i=0;i<2;i++);    //wait 8us    Wait_1us;    bScl=0;    Wait_1us;}    void Write_Mem(unsigned char cMem_Size,cChips_Address,cData_Size,unsigned int cStart_Address){    unsigned char /*idata*/ i,cAddress[2];    //0-L;1-H    bScan_Err=0;    cAddress[0]=cStart_Address;    cStart_Address>>=8;    cAddress[1]=cStart_Address;    i=Sla_Wr;    i|=cChips_Address;    if(cMem_Size==AT24C256)        i&=0xf7;    Start_I2c();    Wait_1us;    Send_I2c(i); //SLA:1010 xxx0    Wait_1us;    if(cMem_Size==AT24C256)     //1-16用1个字节地址,32-512用2个字节地址,匹配地址AT24C32、64        Send_I2c(cAddress[1]);     //先发送高字节地址        Send_I2c(cAddress[0]); //如果是双字节地址则为低地址否则为高地址    for(i=0;(bScan_Err==0)&&(i!=cData_Size);i++)        Send_I2c(cShare_Buf);    //写一个字节数据    End_I2c();    }void Read_Mem(unsigned char cMem_Size,cChips_Address,cData_Size,unsigned int cStart_Address){    unsigned char /*idata*/ i,cAddress[2];        bScan_Err=0;    cAddress[0]=cStart_Address;     //将16位地址分解为高低字节    cStart_Address>>=8;    cAddress[1]=cStart_Address;    i = Sla_Wr;    i |= cChips_Address;    if(cMem_Size==AT24C256)        i&=0xf7;    Start_I2c();    Send_I2c(i);//SLA:1010 xxx0    if(cMem_Size==AT24C256)     //1-16用1个字节地址,32-512用2个字节地址,匹配地址AT24C32、64        Send_I2c(cAddress[1]);    //先发送高字节地址    Send_I2c(cAddress[0]); //address and write    i|=0x01;     //Read    Start_I2c();    Send_I2c(i); //address and  read    for(i=0;(bScan_Err==0)&&(i!=cData_Size);i++)    {        cShare_Buf=Scan_I2c(); //读入第一个字节        if(i==(cData_Size-1))            Send_Not_Ack();                    else             Send_Ack();    }    End_I2c();}#endif

回帖(2)

莫循虎

2019-5-10 09:39:23
就是调延时了....
12M说明你MCU速度变快了,延时要改长.
说白了,就是要Wait_1us是真正的1us.
举报

刘刚

2019-5-10 09:48:30
扫描样  是什么鬼
主要把延时调一下吧
举报

更多回帖

发帖
×
20
完善资料,
赚取积分