昨天3D打印了一个安放电路板的结构件,然后发现没有树莓派用的M2.5的螺丝,赶紧网上下单然后开始码别的。
想了一下,人家MPU9250明明是有GPIO中断输出的,干啥要用延迟呢,改个中断吧,于是今天基本就折腾了一天中断。
其实中断也不是很难,用wiringPi这个库就可以了,或者BCM的那套也行。不过用了wiringPi之后执行需要root权限,让我不太高兴。Linux不是一切皆文件吗?Linux不是有GPIO子系统吗?借助这个子系统不就好了?
别说,还真有,用/sys/class/gpio/这个目录就可以了。这个要求编译内核时开启Device Drivers -> GPIO Support -> /sys/class/gpio/… (sysfs interface) 这个选项,树莓派官方镜像的内核已经开启了。
然后echo 端口号(BCM) > /sys/class/gpio/export
来将这个接口从内核中暴露出来,接下来就可以通过/sys/class/gpio/gpio*/下的direction value edge这几个文件来进行输入输出和中断触发边沿选择了。
最后怎么用作中断呢?select/poll/epoll都可以了,它们会挂起线程知道文件内容改变。
另外这是我的参考文章:http://blog.sina.com.cn/s/blog_7880d3350102w2um.html
另外MPU9250还总是有零漂,我前几周调好了,今天上电一看飘了0.4dps,纠正过来后一看又漂了0.1dps,根本不知道该怎么处理。这倒还好,大不了系统启动时纠偏,但它要是走着走着飘起来了该咋办?
附上程序一段:
void MPU9250::getData(MPU9250 *obj) { int gpio_fd; struct pollfd fds[1]; char buff[10]; gpio_fd = open("/sys/class/gpio/gpio17/value",O_RDONLY); if(gpio_fd < 0){ throw I2C_Exception(I2C_Exception::Device_Not_Exist); } fds[0].fd = gpio_fd; fds[0].events = POLLPRI; read(gpio_fd,buff,10); const uint8_t startAddr = 0x3b; uint8_t data[14]; while (obj->run) { // Wait for MPU9250 RAW data ready interrupt poll(fds,1,-1); if( fds[0].revents & POLLPRI) { lseek(gpio_fd, 0, SEEK_SET); read(gpio_fd, buff, 10); } // Get data Balabala; } close(gpio_fd); }
启动脚本:
echo 17 > /sys/class/gpio/export sleep 1 #将GPIO暴露出来需要时间 echo in > /sys/class/gpio/gpio17/direction echo rising > /sys/class/gpio/gpio17/edge ./wqmbd