嵌入式中linux系统对eeprom芯片at24c02的操作实例(包括驱动层和应用层代码)

6 篇文章 0 订阅
3 篇文章 0 订阅

应用层代码示例

/* app.c at24c08读写测试应用程序 */
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <sys/types.h> 

#define DEV "/dev/at24_eeprom"

int main(int argc, char **argv) 
{ 
      int fd, pos, i;  
      unsigned char value[512] = {}; 

      fd = open(DEV, O_RDWR); 
      if(fd < 0)  
      {   
          perror(DEV);
          exit(1); 
      }   

      for(i = 0; i < 32; i++)
          value[i] = i * 2;

      pos = 16; 
      lseek(fd, pos, SEEK_SET);
      write(fd, value, 32);
    
      sleep(1); 

      pos = 16; 
      lseek(fd, pos, SEEK_SET);

      printf("\nread eeprom from at offset %d\n", pos);
      printf("===============================================\n");
      memset(value, 0, sizeof(value));
      read(fd, value, 256); 
      for(i = 0; i < 256; i++) 
      {   
          if(i && ((i % 16) == 0)) 
              printf("\n");
          printf("%02x ",value[i]); 
      }   
      printf("\n===============================================\n");

      pos = 0;
      lseek(fd, pos, SEEK_SET);
      printf("\nread eeprom from at offset %d:\n", pos);
      printf("===============================================\n");

      memset(value,0,sizeof(value));
      read(fd, value, 256); 
      for(i = 0; i < 256; i++) 
      {   
          if(i && ((i % 16) == 0)) 
              printf("\n");
          printf("%02x ",value[i]); 
      }   
      printf("\n===============================================\n");

      close(fd); 
      return 0;    
}

linux系统驱动层代码:

#include <linux/module.h>
#include <linux/delay.h>
#include <linux/mod_devicetable.h>
#include <linux/log2.h>
#include <linux/i2c.h>
#include <linux/i2c/at24.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <asm/uaccess.h>


#define AT24_SIZE_BYTELEN   5
#define AT24_SIZE_FLAGS     8


/* create non-zero magic value for given eeprom parameters */
#define AT24_DEVICE_MAGIC(_len, _flags)         \
    ((1 << AT24_SIZE_FLAGS | (_flags))      \
        << AT24_SIZE_BYTELEN | ilog2(_len))

static const struct i2c_device_id at24_ids[] = { 
    { "24c00", AT24_DEVICE_MAGIC(128 / 8, AT24_FLAG_TAKE8ADDR) },
    { "24c01", AT24_DEVICE_MAGIC(1024 / 8, 0) },
    { "24c02", AT24_DEVICE_MAGIC(2048 / 8, 0) },
    { "spd", AT24_DEVICE_MAGIC(2048 / 8,
        AT24_FLAG_READONLY | AT24_FLAG_IRUGO) },
    { "24c04", AT24_DEVICE_MAGIC(4096 / 8, 0) },
    { "at24c08", AT24_DEVICE_MAGIC(8192 / 8, 0) },
    { "24c16", AT24_DEVICE_MAGIC(16384 / 8, 0) },
    { "24c32", AT24_DEVICE_MAGIC(32768 / 8, AT24_FLAG_ADDR16) },
    { "24c64", AT24_DEVICE_MAGIC(65536 / 8, AT24_FLAG_ADDR16) },
    { "24c128", AT24_DEVICE_MAGIC(131072 / 8, AT24_FLAG_ADDR16) },
    { "24c256", AT24_DEVICE_MAGIC(262144 / 8, AT24_FLAG_ADDR16) },
    { "24c512", AT24_DEVICE_MAGIC(524288 / 8, AT24_FLAG_ADDR16) },
    { "24c1024", AT24_DEVICE_MAGIC(1048576 / 8, AT24_FLAG_ADDR16) },
    { "at24", 0 },
    { /* END OF LIST */ }
};
MODULE_DEVICE_TABLE(i2c, at24_ids);

static struct i2c_client *client;
static ssize_t at24_eeprom_read(struct file *file, 
                                char __user *buffer, 
                                size_t count,
                                loff_t * offset)
{
    u8 buf[1024] = {};
    int ret;

    ret = i2c_master_send(client, (const char *)offset, 1);
    if(ret < 0)
    {
        printk("i2c_master_send failed!\n");
        return -EAGAIN;
    }

    ret = i2c_master_recv(client, buf, sizeof(buf));
    if(ret < 0)
    {
        printk("i2c_master_recv failed!\n");
        return -EAGAIN;
    }

    ret = copy_to_user (buffer, (void *) buf, count);
    if (!ret)
    {
        *offset += count;
        return count;
    }

    return -EAGAIN;
}

static ssize_t at24_eeprom_write(struct file *file,
                                const char __user *buffer,
                                size_t count,
                                loff_t *offset)
{
    unsigned char kbuf[2048] = {0};
    unsigned transferred = 0;
    int i = 0, ret;

    if(i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
    {
        ret = copy_from_user (kbuf, buffer, count);
        if(ret)
            return -EAGAIN;

        while (transferred < count)
        {
            ret = i2c_smbus_write_byte_data (client, i + (*offset), kbuf[i]);
            if(ret < 0)
                return -EAGAIN;
            i++;
            transferred++;
        }
    }

    *offset += transferred;

    return transferred;
}

static struct file_operations dev_fops = {
    .owner  = THIS_MODULE,
    .read   = at24_eeprom_read,
    .write  = at24_eeprom_write,
};


static struct miscdevice misc = {
    .minor = MISC_DYNAMIC_MINOR,
    .name  = "at24_eeprom",
    .fops   = &dev_fops,

};

static int at24_probe(struct i2c_client *clt, const struct i2c_device_id *id)
{
    int ret;
    client = clt;

    if( !i2c_check_functionality(client->adapter,I2C_FUNC_SMBUS_READ_I2C_BLOCK) )
        return -EPFNOSUPPORT;

    ret = misc_register(&misc);  //目的在/dev生成用户空间访问接口。
    if(ret)
        printk("dev register FAILED!\n");

    return ret;
}

static int __devexit at24_remove(struct i2c_client *client)
{
    return misc_deregister(&misc);
}

static struct i2c_driver at24_driver = {
    .driver = {
        .name = "at24_eeprom",
        .owner = THIS_MODULE,
    },
    .probe  = at24_probe,
    .remove = __devexit_p(at24_remove),
    .id_table = at24_ids,
};
static int __init at24_init(void)
{
    return i2c_add_driver(&at24_driver);
}

static void __exit at24_exit(void)
{
    i2c_del_driver(&at24_driver);
}

module_init(at24_init);
module_exit(at24_exit);
MODULE_LICENSE("GPL");

 

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
EEPROM存储器AT24C02驱动是一种用于控制和操作AT24C02 EEPROM芯片的软件程序。AT24C02是一种2K位串行电路编程只读存储器(EEPROM),能够以字节为单位进行读写操作。下面是一个简单的EEPROM存储器AT24C02驱动的实现示例: 首先,需要确定与AT24C02芯片通信的硬件接口。一般来说,AT24C02芯片使用I2C(TWI)总线进行通信。因此,需要确保控制器上的I2C总线控制器(如I2C模块)已正确配置和初始化。 其次,需要实现与AT24C02芯片通信的相关函数,如写入数据、读取数据等。这些函数可以通过在控制器上通过I2C总线传输控制字节和数据字节来执行相关的EEPROM操作。 例如,实现写入数据的函数,可以按照以下步骤进行: 1. 通过发出启动条件向AT24C02芯片发送设备地址。设备地址应包括芯片的固定地址和A0、A1和A2引脚的状态,用来识别芯片的物理位置。 2. 发送一个字节的内存地址,确定要写入数据的EEPROM存储器地址。 3. 发送要写入的数据字节。 4. 等待写操作完成,可以通过轮询芯片或等待I2C总线断来检查。 5. 发送停止位,结束写操作。 同样,读取数据的函数也可以按照类似的步骤进行实现,只不过在发送内存地址之后需要切换到读操作模式,并在读取数据后保存数据字节。 在驱动程序的应用,可以使用这些函数来存储和检索数据。通过提供适当的地址,可以将数据写入或读取到AT24C02芯片的特定地址。此外,除了基本的读写功能之外,还可以实现其他操作,如块写入、页写入等。 总之,EEPROM存储器AT24C02驱动程序通过I2C总线控制器与AT24C02芯片进行通信,实现了对EEPROM芯片的读写操作驱动程序应提供适当的函数来进行数据存储和检索,并可以根据应用需求扩展其他功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值