主题 : smart210裸机读写i2c板载AT24LC04代码 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 82003
精华: 0
发帖: 26
金钱: 130 两
威望: 26 点
贡献值: 0 点
综合积分: 52 分
注册时间: 2012-11-16
最后登录: 2017-05-28
楼主  发表于: 2016-10-19 08:16

 smart210裸机读写i2c板载AT24LC04代码

void i2c_24c04_write_byte(unsigned char dataAddr,unsigned char data)
{
    
    ///************************
    //设置为发送模式
    I2CSTAT0 |= (0x3<<6);
    //写入从设备地址-I2CDS
    I2CDS0 = I2C24C04_WRITE_ADDR;
    I2CCON0 &= ~(1<<4);
    //写0xF0 到I2CSTAT
    I2CSTAT0 = 0xF0;
    //等待ACK
    while((I2CCON0 & 0x10) ==0)
        delay_xz(100);
    //发送数据地址到I2CDS
    I2CDS0 = dataAddr;
    I2CCON0 &= ~(1<<4);
    //等待ACK
    while((I2CCON0 & 0x10) ==0)
        delay_xz(100);
    //写入数据
    I2CDS0 = data;
    I2CCON0 &= ~(1<<4);
    //等待ACK
    while((I2CCON0 & 0x10) ==0)
        delay_xz(100);
    //写入0xD0到I2CSTAT
    I2CSTAT0 = 0xD0;
    //清除PEND
    I2CCON0 &= ~(1<<4);
    //等待ACK
    delay_xz(100);
    //********************/

    
}
//随机读
void i2c_24c04_read(unsigned char *buf,unsigned char dataAddr,unsigned int length)
{
    
    
    ///************************
    int i =0;
    unsigned char unusedData;
    //设置为主设备发送模式
    I2CSTAT0 |= (0x3<<6);
    //写入从设备地址-I2CDS
    I2CDS0 = I2C24C04_WRITE_ADDR;
    I2CCON0 &= ~(1<<4);
    //写0xF0 到I2CSTAT
    I2CSTAT0 = 0xF0;
    //等待ACK
    while((I2CCON0 & 0x10) ==0)
        delay_xz(100);
    //发送数据地址到I2CDS
    I2CDS0 = dataAddr;
    I2CCON0 &= ~(1<<4);
    //等待ACK
    while((I2CCON0 & 0x10) ==0)
        delay_xz(100);
    
    //设定为主机读模式
    I2CSTAT0 &= ~(0x3<<6);
    I2CSTAT0 |= (0x2<<6);
    //写入从设备地址-I2CDS
    I2CDS0 = I2C24C04_READ_ADDR;
    I2CCON0 &= ~(1<<4);
    //写0xB0 到 I2CSTAT
    I2CSTAT0 = 0xB0;
    //这边设备有个问题第一个字节的数据是无效的,因此需要丢弃

    //等待中断--循环读取
    while((I2CCON0 & 0x10) ==0)
        delay_xz(100);
    //定义了一个无效变量接收无用数据
    unusedData = I2CDS0;
    //清除pend --循环结束
    I2CCON0 &= ~(1<<4);    
    
    for (i=0;i<length;i++)
    {
        //读取完数据所有需要的数据时,需要回覆NOACK
        if (i==(length-1))
        {
            I2CCON0 &= ~(1<<7);
        }
        
        //等待中断--循环读取
        while((I2CCON0 & 0x10) ==0)
            delay_xz(100);
        //从I2CDS读取数据
        buf = I2CDS0;
        //清除pend --循环结束
        I2CCON0 &= ~(1<<4);
    }
    
    
    //等待中断--循环读取
    while((I2CCON0 & 0x10) ==0)
        delay_xz(100);
    
    //写入0x90到I2CSTAT
    I2CSTAT0 = 0x90;
    //清除中断
    I2CCON0 &= ~(1<<4);
    
    //为了后续操作应该要恢复ACK
    I2CCON0 |= (1<<7);
    //*************************/
}

void i2c_init(void)
{
    ///*****************
    //1.设置引脚-I2C复用
    GPD1CON &= ~(0xFF <<0);
    GPD1CON |= (0x22 <<0);
    //设定引脚上拉,但是原理图上已经加了上拉电阻,所以直接悬空就可以了
    GPD1PUD &= ~(0xF);
    
    //2.设置I2CCON寄存器
    //2.1使能中断

    //清除中断标示
    I2CCON0 &= ~(1<<4);
    //启用中断
    I2CCON0 |= (1<<5);
    //2.2设定SCL时钟-PCLK=96M/(16 * (7+1)) 大约在750KHz 发现这样速度还是太块会不稳定
    //I2CCON0 &= ~(1<<6);
    //I2CCON0 |= (0x7<<0);
    
    //改用512分频 96M/512 = 187.5KHz 就正常了
    I2CCON0 |= (1<<6);        //设置成512分频
    //2.3允许返回ack
    I2CCON0 |= (1<<7);
    
    //3.设定I2CSTAT寄存器使能串行输出
    //3.1设定工作模式为写
    I2CSTAT0 |= (1<<4);
    //************************************/

}
[ 此帖被cliffdean在2016-10-19 13:39重新编辑 ]