打印
[STM32]

关于AT24C08读写

[复制链接]
4338|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
AT24C08怎么在指定的(unsigned int 类型)的地址写入和读取(unsigned Int类型)的数据,之前操作或者网上大部分都是写入或读取(unsigned char类型)的数据,求高手帮忙解答,谢谢。
void WriteI2C((unsigned int) *luwtData,(unsigned int)  luwtAddr,(unsigned int)  luwtDataLen)
{
}
void ReadI2C((unsigned int) *luwtData,(unsigned int)  luwtAddr,(unsigned int)  luwtDataLen)
{
}

相关帖子

沙发
JY-DX-JY| | 2015-5-17 20:05 | 只看该作者
分两个字节写。

使用特权

评论回复
板凳
luofeng2g| | 2015-5-17 22:45 | 只看该作者

使用特权

评论回复
地板
ayb_ice| | 2015-5-18 07:54 | 只看该作者
两个字节而已

使用特权

评论回复
5
Alisa_song|  楼主 | 2015-5-18 09:04 | 只看该作者

void I2c_delay(unsigned int t)
{
        while(t--);
}

void I2c_start(void)
{
        SDA_out();
        SCL_L();
        I2c_delay(10);
        SDA_H();
        I2c_delay(10);
        SCL_H();
        I2c_delay(20);
        SDA_L();
        I2c_delay(20);
        SCL_L();
        I2c_delay(10);
}

void I2c_stop(void)
{
        SDA_out();
        SDA_L();
        I2c_delay(10);
        SCL_H();
        I2c_delay(20);
        SDA_H();
        I2c_delay(20);
        SCL_L();
        I2c_delay(10);
}

unsigned char I2c_wait_ack(void)
{
        unsigned char i;                       
        unsigned char I2c_bad;
        SDA_in();                       
        I2c_delay(20);
        SCL_H();
        I2c_delay(10);
        for(i=0; i<3; i++)
        {
                if(SDA_High)        
                {
                        I2c_bad=1;
                }
                else
                {
                        I2c_bad=0;
                        break;
                }
                I2c_delay(10);
        }
        SCL_L();
        I2c_delay(10);
        SDA_out();
        I2c_delay(10);
        return  I2c_bad;
}

void I2c_no_wait_ack(void)
{
        SDA_out();
        I2c_delay(20);
        SDA_H();
        I2c_delay(20);
        SCL_H();
        I2c_delay(20);
        SCL_L();
        I2c_delay(20);
}

void I2c_wr8bit(unsigned char c)
{
        unsigned char        i;                       
        SDA_out();
        for(i=0; i<8; i++)
        {
                if(c&0x80)
                        SDA_H();
                else       
                        SDA_L();
                I2c_delay(10);
                SCL_H();
                I2c_delay(20);
                SCL_L();
                c=c<<1;               
                I2c_delay(10);
        }
        SDA_H();               
}

unsigned char I2c_rd8bit(void)
{
        unsigned char i, val=0;       
        SDA_in();
        I2c_delay(10);
        for(i=0x80; i>0;)            
        {
                SCL_H();                     
                I2c_delay(20);
                if(SDA_High)
                        val=(val | i);   
                I2c_delay(10);
                SCL_L();
                i>>=1;
                I2c_delay(20);
        }
        return val;
}

void I2c_write(unsigned char Addr,unsigned char Data,unsigned char DeviceID)
{
        I2c_start();
        I2c_wr8bit(DeviceID&Write);
        I2c_wait_ack();
        I2c_wr8bit(Addr);
        I2c_wait_ack();
        I2c_wr8bit(Data);
        I2c_wait_ack();
        I2c_stop();
}

unsigned char I2c_read(unsigned char Addr,unsigned char Data,unsigned char DeviceID)
{
        I2c_start();
        I2c_wr8bit(DeviceID&Write);
        I2c_wait_ack();
        I2c_wr8bit(Addr);  
        I2c_wait_ack();
        I2c_start();
        I2c_wr8bit(DeviceID|Read);
        I2c_wait_ack();
        Data=I2c_rd8bit();  
        I2c_no_wait_ack();
        I2c_stop();
        return Data;
}

void I2c_wr8bit_low(unsigned char c)
{
        char        i;                       
        SDA_out();
        for(i=0; i<8; i++)
        {
                if(c&0x01)
                        SDA_H();
                else       
                        SDA_L();
                I2c_delay(10);
                SCL_H();
                I2c_delay(10);
                SCL_L();
                c>>=1;                       
                I2c_delay(10);
        }
        SDA_H();                       
}
然后我也想分两个字节写入或读取,就
void Write_I2C(INT16U *luwtData,INT16U luwtAddr,INT16U luwtDataLen)
{
        unsigned char Len;
        unsigned char PageAddr;
        unsigned char WriteTimes;
       
        for(Len = 0;Len < luwtDataLen;Len++)
        {
                PageAddr = ((unsigned char)(luwtAddr>>8))&0x03;
                PageAddr <<= 1;
                for(WriteTimes = 0;WriteTimes < 5; WriteTimes++)
                {
                        I2c_write(luwtAddr&0xff,(unsigned char)(luwtData&0xff),E2promID|(PageAddr&0x0f));
                        I2c_wait_ack();
                        I2c_write(luwtAddr&0xff,(unsigned char)((luwtData>>8)&0xff),E2promID|(PageAddr&0x0f));
                        I2c_wait_ack();                       
                }
                luwtAddr++;
                luwtData++;
        }
       
}

void Read_I2C(INT16U* lubtData,INT16U luwtAddr,INT16U luwtDataLen)
{
        unsigned char Len;
        unsigned char PageAddr;
        unsigned char ReadTimes;
       
        for(Len = 0;Len < luwtDataLen;Len++)
        {
                PageAddr = (unsigned char)((luwtAddr>>8)&0x03);
                PageAddr <<= 1;       
                for(ReadTimes = 0;ReadTimes < 3;ReadTimes++)
                {
                        I2c_read(luwtAddr&0xff,lubtData,E2promID|(PageAddr&0x0f));
                        I2c_wait_ack();
                }
                luwtAddr++;
                lubtData++;
        }
}

在运行中就不对,请问我这样写问题出在哪里?请帮忙解答,谢谢

使用特权

评论回复
6
ayb_ice| | 2015-5-18 09:45 | 只看该作者
Alisa_song 发表于 2015-5-18 09:04
void I2c_delay(unsigned int t)
{
        while(t--);

#define A2                        (1<<3)        // (0<<3)
#define P1_P0(addr)        (((addr / 256) & 0x03) << 1)
#define WRITE                0x00
#define READ                0x01

void write_u16(U16 addr, U16 da)        // 不可跨页写
{
        I2c_start();

        I2c_wr8bit(0xa0 + A2 + P1_P0(addr) + WRITE);
        I2c_wait_ack()

        I2c_wr8bit(addr%256);
        I2c_wait_ack();

        I2c_wr8bit(da/256);
        I2c_wait_ack();

        I2c_wr8bit(da%256);
        I2c_wait_ack();

        I2c_stop();
}

U16 read_u16(U16 addr)
{
        U8 t1,t2;

        I2c_start();

        I2c_wr8bit(0xa0 + A2 + P1_P0(addr) + WRITE);
        I2c_wait_ack()

        I2c_wr8bit(addr%256);
        I2c_wait_ack();

        I2c_start();
        I2c_wr8bit(0xa0 + A2 + P1_P0(addr) + READ);
        I2c_wait_ack();

        t1 = I2c_rd8bit();
        I2c_send_ack();                // 注意是发送应答, 不是等待应答

        t2 = I2c_rd8bit();
        I2c_send_nack();                // 注意是发送非应答, 不是等待应答

        I2c_stop();

        return t1 * 256 + t2;
}

使用特权

评论回复
7
Alisa_song|  楼主 | 2015-5-18 10:23 | 只看该作者
ayb_ice 发表于 2015-5-18 09:45
#define A2                        (1

对着你发的代码和时序还在学习,非常感谢你的回复。

使用特权

评论回复
8
Alisa_song|  楼主 | 2015-5-18 10:30 | 只看该作者
ayb_ice 发表于 2015-5-18 09:45
#define A2                        (1

谢谢你的回复,有一点不是很明白,
#define A2                        (1<<3)        // (0<<3)
#define P1_P0(addr)        (((addr / 256) & 0x03) << 1)
的宏定义我不是很理解,不知可否帮忙解释下?谢谢。
还有在写的时候为什么要先写
I2c_wr8bit(0xa0 + A2 + P1_P0(addr) + WRITE);
谢谢

使用特权

评论回复
9
ayb_ice| | 2015-5-18 10:42 | 只看该作者
Alisa_song 发表于 2015-5-18 10:30
谢谢你的回复,有一点不是很明白,
#define A2                        (1

对着图就明白了

未命名.jpg (27.9 KB )

未命名.jpg

使用特权

评论回复
10
coody| | 2015-5-18 11:15 | 只看该作者
都是单字节读写的,你强转一下类型就好啦

使用特权

评论回复
11
luofeng2g| | 2015-5-18 11:53 | 只看该作者
Alisa_song 发表于 2015-5-18 10:30
谢谢你的回复,有一点不是很明白,
#define A2                        (1

你说的一大串其实就是为了写地址

使用特权

评论回复
12
Alisa_song|  楼主 | 2015-5-18 13:06 | 只看该作者
ayb_ice 发表于 2015-5-18 10:42
对着图就明白了

对着手册明白了,谢谢。我要写入多个数据,你看这样写可以吗?谢谢你了!
void WriteI2C(INT16U *luwtData,INT16U luwtAddr,INT16U luwtDataLen)
{
        unsigned char Len;
       
        I2c_start();
       
        I2c_wr8bit(0xa0 + A2 + P1_P0(luwtAddr) + Write);                                                //Write Device Address
        I2c_wait_ack();
       
        I2c_wr8bit(luwtAddr % 256);                                                                                                //Write Word Address
        I2c_wait_ack();
       
        for(Len = 0;Len < luwtDataLen;Len++)
        {
                I2c_wr8bit(*luwtData / 256);                                                                                //Write high byte
                I2c_wait_ack();
                I2c_wr8bit(*luwtData % 256);                                                                                //Write low byte
                I2c_wait_ack();                       

                luwtData++;
        }
        I2c_stop();
}
void ReadI2C(INT16U* luwtData,INT16U luwtAddr,INT16U luwtDataLen)
{
        unsigned char Len;
        unsigned char t1,t2;
       
        I2c_start();
       
        I2c_wr8bit(0xa0 + A2 + P1_P0(luwtAddr) + Write);                                                //Write Device Address
        I2c_wait_ack();
       
        I2c_wr8bit(luwtAddr % 256);                                                                                                //Write Word Address
        I2c_wait_ack();
       
        I2c_start();
        I2c_wr8bit(0xa0 + A2 + P1_P0(luwtAddr) + Read);
        I2c_wait_ack();
        for(Len = 0;Len < luwtDataLen ;Len++)
        {
                t1 = I2c_rd8bit();
                I2c_send_ack();
               
                t2 = I2c_rd8bit();
                I2c_send_ack();
               
                if(Len == luwtDataLen - 1)
                {
                        t1 = I2c_rd8bit();
                        I2c_send_ack();
               
                        t2 = I2c_rd8bit();
                        I2c_no_wait_ack();
                }
        }
        I2c_stop();
        *luwtData = t1 * 256 + t2;
}

使用特权

评论回复
13
gx_huang| | 2015-5-18 13:22 | 只看该作者
要么拷贝别人现成的程序,要么自己仔细读懂EEPROM的数据手册。

使用特权

评论回复
14
ayb_ice| | 2015-5-18 13:28 | 只看该作者
Alisa_song 发表于 2015-5-18 13:06
对着手册明白了,谢谢。我要写入多个数据,你看这样写可以吗?谢谢你了!
void WriteI2C(INT16U *luwtDat ...

可以

注意读写都是16位数据

使用特权

评论回复
15
Alisa_song|  楼主 | 2015-5-18 14:22 | 只看该作者
ayb_ice 发表于 2015-5-18 13:28
可以

注意读写都是16位数据

好的,谢谢你的指导和帮助。

使用特权

评论回复
16
runningwzf| | 2015-5-18 16:29 | 只看该作者
强制转换指针吧

使用特权

评论回复
17
星星点灯69| | 2015-9-19 10:07 | 只看该作者
弱弱地问一句, I2c_send_ack()和I2c_send_nack()这两个函数是怎么定义的,它们与I2c_wait_ack(), I2c_no_wait_ack()这两个函数有和区别,应答信号不都是由从设备发送给主设备的么?劳烦各位解答一下,不甚感激!

使用特权

评论回复
18
星星点灯69| | 2015-9-19 10:14 | 只看该作者
ayb_ice 发表于 2015-5-18 09:45
#define A2                        (1


弱弱地问一句, I2c_send_ack()和I2c_send_nack()这两个函数是怎么定义的,它们与I2c_wait_ack()、I2c_no_wait_ack()这两个函数有何区别?应答信号不都是由从设备响应给主设备的么,那为何还有发送和等待之说?劳烦解答一下,不甚感激!

使用特权

评论回复
19
ayb_ice| | 2015-9-19 10:57 | 只看该作者
本帖最后由 ayb_ice 于 2015-9-19 11:00 编辑
星星点灯69 发表于 2015-9-19 10:14
弱弱地问一句, I2c_send_ack()和I2c_send_nack()这两个函数是怎么定义的,它们与I2c_wait_ack()、I2c_n ...

谁接收信息谁应答,主机始终产生时钟,主机接收了最后一个字节了就需要发送非应答信号,从机收到非应答信号会释放SDA(实现线与功能,否则可能是低电平,无法实现线与功能,导致后面的通信错误),从机也不知道主机什么时候通信结束

仔细看协议你就明白了
I2c_wait_ack()应该是接收应答,而且必须是有效应答才返回,I2c_wait_nack()应该是发送应答脉冲就可以了,不管接收了什么,这不是我写的,具体的要看代码




使用特权

评论回复
20
星星点灯69| | 2015-9-19 11:04 | 只看该作者
ayb_ice 发表于 2015-9-19 10:57
谁接收信息谁应答,主机始终产生时钟,主机接收了最后一个字节了就需要发送非应答信号,从机收到非应答信 ...

好的,谢谢你的回答,没想到这么快就回复了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

19

主题

94

帖子

1

粉丝