树莓派调用bcm2835库读写at24c02
学习初衷:最近学习了韦东山老师的嵌入式开发手册,奈何手上没有韦东山老师的开发板,恰好老板有下发树莓派4b,所以拿树莓派4b玩一下I2C,通过实践更好的去理解。(后面会尝试进行I2C驱动开发实验)
由于网上没有找到什么用bcm2835库读写at24c02的代码资料,所以自己也走了一点弯路。现记录一下读写操作的注意事项,给想学习的朋友们提供一点借鉴,也供自己以后参考。
1.树莓派I2c配置可参考该博主文章:
链接: link
此外,请先安装好i2c-tools和bcm2835库再进行以下操作。(这些csdn教程很多,就不重复贴出来了)
2.模块及连接图片
我买的是现成模块,连接简单。
3.关键函数理解
函数:uint8_t bcm2835_i2c_write (const char *buf, uint32_t len)
描述:向从设备写入数据,如果是直接向从设备发送数据,则直接将数据填入buf中,len为数据长度。如果向从设备的寄存器写数据,那么buf[0]里先填写寄存器地址,从buf[1]开始放数据。总之,len是要发送数据的总长度。
(这里需要注意:写操作的buf[0]里先填写的寄存器地址是偏移地址,不是指器件的地址0x50)
函数:uint8_t bcm2835_i2c_read (char *buf, uint32_t len)
描述:从从设备读取长度为len的数据放入buf里。
我们把at24c02接上树莓派后在终端输入
sudo i2cdetect -y 1
可以看到地址为0x50
4.直接上代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <bcm2835.h>
#define I2C_ADDR_AT24C02 0x50
int main(int argc, char **argv)
{
int rc = 0;
int i = 0;
int counter = 0;
const char WriteBuf[4] = {0x08,2,0x03,9};
const char WriteBuf2[4] = {0x15,12,18,19};
const char WriteBuf3[4] = {0x01,2,0x03,4};
unsigned char rbuf = 0;
unsigned char buf[8] = {0};
int temp=0;
if (!bcm2835_init())
return 1;
bcm2835_i2c_begin();
bcm2835_i2c_setSlaveAddress(I2C_ADDR_AT24C02);
bcm2835_i2c_set_baudrate(10000); /* 10 KHz */
bcm2835_i2c_write( WriteBuf , 4);
bcm2835_delay(50);//得经过延时才能写入第二次数据
bcm2835_i2c_write( WriteBuf2 , 4);
bcm2835_delay(50);
bcm2835_i2c_write( WriteBuf3 , 4);
bcm2835_delay(50);
// read
//rc = bcm2835_i2c_read(buf, 3);//3表示读了三位数据放在buf里面
//printf("data=0x%X\n",buf[2]);
counter = 8;
for (i = 0; i < counter; i++) {
rc = bcm2835_i2c_read(&rbuf, 1);
//rbuf=buf[i];
if (!rc) {
//if (1) {
printf("Read rbuf = %x\n", rbuf);//他读数据地址会自动递增的
} else {
printf("ERROR! rc = %d\n", rc);
}
}
// Just leave them as i2c pin to make i2c tools happy :-)
//bcm2835_i2c_end();
bcm2835_close();
return 0;
}
然后运行结果为下:
其实在读写操作的过程中,它的地址是会自动加一。因此,读写操作后,如果没有重新设定开头地址,那么下一次进行读操作的地址会紧接上一个操作的地址。
代码中可以看到,bcm2835_i2c_write( WriteBuf3 , 4)后,进行读操作,它的偏移地址是从0x04开始的。
我们可以看到在写操作:bcm2835_i2c_write( WriteBuf , 4);后会加上一个延时函数。第一次用的时候,没有加上延时,可能会导致下一次读的第一,二个失败;或者写数据也会失败。(当时博主就是踩了这个坑,浪费了不少时间。后面参考了这篇内容才发现得进行延时:链接: link)
不过最少延时时间大家可以亲自试验一下。
读写失败的情况如下:
博主也是在学习探索阶段,如文章有内容讲的不正确的,恳请大家指正。