STM32/STM8技术论坛
直播中

casy

12年用户 229经验值
擅长:嵌入式技术
私信 关注
[经验]

【MYD-YA157C开发板试用连载】+ I2C子系统介绍与测评

首先,介绍一下我们要驱动的芯片:AT24C02
          AT24C02的存储容量为2Kb,内容分成32页,每页8B,共256B,操作时有两种寻址方式:芯片寻址和片内子地址寻址。
  (1)芯片寻址:AT24C02的芯片地址为1010,其地址控制字格式为 1010A2A1A0R/W。其中A2,A1,A0可编程地址选择位。
A2,A1,A0引脚接高、低电平后得到确定的三位编码,与1010形成7位编码, 即为该器件的地址码。R/W为芯片读写控制位,
该位为0,表示芯片进行写操作。
  (2)片内子地址寻址:芯片寻址可对内部256B中的任一个进行读/写操作,其寻址范围为00~FF,共256个寻址单位。
我们采用的是第2种 寻址方式。
另外,有一个问题需要了解一下,就是EEPROM 与flash , 什么时候使用EEPROM,什么时候用FLASH合适。
 Flash存储器又称闪存,它结合了ROM和RAM的长处,不仅具备电子可擦除可编程(EEPROM)的性能,还可以快速读取数据(NVRAM的优势),使数据不会因为断电而丢失。U盘和MP3里用的就是这种存储器。用作存储Bootloader以及操作系统或者程序代码,或者直接当硬盘使用(U盘)。
一, EEPROM以单字节读写,FLASH部分芯片只能以块方式擦除(整片擦除),部分芯片可以单字节写入(编程),一般需要采用块写入方式;
二,FLASH比EEPROM读写速度更快,可靠性更高。
三,价格方面比较,FLASH比EEPROM贵。
So,我们的版卡参数信息,等一些固定的,小量的,不需要经常修改资料信息放在EEPROM中。而flash作为存储程序的存储器,存放操作系统代码等需要快速读写的,经常访问的数据。
   其次,我们来看看linux iic的驱动框架:

到这里,我们就可以写应用测试程序了!
  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. #include
  7. #include
  8. #include
  9. #define I2C_RETRIES 0x0701
  10. #define I2C_tiMEOUT 0x0702
  11. #define I2C_RDWR 0x0707

  12. // not include READ/WRITE bit
  13. #define I2C_ADDR 0x50

  14. struct i2c_msg
  15. {
  16.         unsigned short addr;
  17.         unsigned short flags;
  18. #define I2C_M_TEN 0x0010
  19. #define I2C_M_RD 0x0001
  20.         unsigned short len;
  21.         unsigned char *buf;
  22. };
  23. struct i2c_rdwr_ioctl_data
  24. {
  25.         struct i2c_msg *msgs;
  26.         int nmsgs;
  27. };

  28. int main(int argc, char** argv){
  29.         int fd,ret;
  30.     char buf[100];
  31.         struct i2c_rdwr_ioctl_data e2prom_data;

  32.         //disable WP
  33.         //system("echo 103 > /sys/class/gpio/export");
  34.         //system("echo "out" > /sys/class/gpio/gpio103/direction");
  35.         //system("echo 0 > /sys/class/gpio/gpio103/value");

  36.         fd = open(argv[1],O_RDWR);

  37.         if(fd<0){
  38.                 perror("open error");
  39.         }

  40.         e2prom_data.nmsgs=2;

  41.         e2prom_data.msgs=(struct i2c_msg*)malloc(e2prom_data.nmsgs*sizeof(struct i2c_msg));
  42.         if(!e2prom_data.msgs)
  43.         {
  44.                 perror("malloc error");
  45.                 exit(1);
  46.         }
  47.         ioctl(fd,I2C_TIMEOUT,1);
  48.         ioctl(fd,I2C_RETRIES,2);
  49.         /* write data to e2prom */
  50.         e2prom_data.nmsgs=1;
  51.         (e2prom_data.msgs[0]).len = 6;
  52.         (e2prom_data.msgs[0]).addr = I2C_ADDR;
  53.         (e2prom_data.msgs[0]).flags = 0; //write
  54.         (e2prom_data.msgs[0]).buf = (unsigned char*)malloc(6);
  55.         (e2prom_data.msgs[0]).buf[0] = 0x00;// e2prom addr[15:8]
  56.         (e2prom_data.msgs[0]).buf[1] = 0x00;//e2prom addr[7:0]
  57.         (e2prom_data.msgs[0]).buf[2] = 0x55;//the data to write byte0
  58.         (e2prom_data.msgs[0]).buf[3] = 0x66;//the data to write byte1
  59.         (e2prom_data.msgs[0]).buf[4] = 0x77;//the data to write byte2
  60.         (e2prom_data.msgs[0]).buf[5] = 0x88;//the data to write byte2

  61.     ret=ioctl(fd,I2C_RDWR,(unsigned long)&e2prom_data);
  62.         if(ret<0)
  63.         {
  64.                 perror("ioctl error1");
  65.         }
  66.         sleep(1);
  67.        
  68.     /* read data from e2prom */
  69.         e2prom_data.nmsgs=2;
  70.         (e2prom_data.msgs[0]).len=2;
  71.         (e2prom_data.msgs[0]).addr=I2C_ADDR;
  72.         (e2prom_data.msgs[0]).flags=0;
  73.         (e2prom_data.msgs[0]).buf=(unsigned char*)malloc(2);
  74.         (e2prom_data.msgs[0]).buf[0]=0x00;// e2prom addr[15:8]
  75.         (e2prom_data.msgs[0]).buf[1]=0x00;//e2prom addr[7:0]

  76.         (e2prom_data.msgs[1]).len=6;
  77.         (e2prom_data.msgs[1]).addr=I2C_ADDR;
  78.         (e2prom_data.msgs[1]).flags=I2C_M_RD;
  79.         (e2prom_data.msgs[1]).buf=(unsigned char*)malloc(6);
  80.         (e2prom_data.msgs[1]).buf[0]=0;
  81.         (e2prom_data.msgs[1]).buf[1]=0;
  82.         (e2prom_data.msgs[1]).buf[2]=0;
  83.         (e2prom_data.msgs[1]).buf[3]=0;
  84.         (e2prom_data.msgs[1]).buf[4]=0;
  85.         (e2prom_data.msgs[1]).buf[5]=0;

  86.         ret=ioctl(fd,I2C_RDWR,(unsigned long)&e2prom_data);
  87.         if(ret<0)
  88.         {
  89.                 perror("ioctl error2");
  90.         }
  91.         printf("Read back:0x%02Xnr",(e2prom_data.msgs[1]).buf[0]);
  92.         printf("Read back:0x%02Xnr",(e2prom_data.msgs[1]).buf[1]);
  93.         printf("Read back:0x%02Xnr",(e2prom_data.msgs[1]).buf[2]);
  94.         printf("Read back:0x%02Xnr",(e2prom_data.msgs[1]).buf[3]);

  95.         close(fd);
  96.         //system("echo 103 > /sys/class/gpio/unexport");

  97.         return 0;
  98. }
至此,我们可以把以上代码测试,通过串口sz命令把编译出来的可执行文件发送到开发板执行了!


回帖(1)

casy

2020-5-19 22:47:12
利用makefile,编译更简单
举报

更多回帖

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