完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
本帖最后由 江口kk 于 2014-8-14 20:42 编辑 Banana Pi IO控制静态库--IO输入输出 以下代码参考了wiringPi,并且只做了GPIO输入输出简单控制,后续会加上SPI,PWM等功能。 编写IO控制静态库 IO控制静态库可以调用系统/dev/mem驱动,也可以参照《Banana Pi驱动编写--IO驱动》制作自己的驱动。源码如下: portPi.h文件: #ifndef __PORTPI_H__ #define __PORTPI_H__ #define LOW 0 #define HIGH 1 //pin mode #define INPUT 0 #define OUTPUT 1 extern int portPiSetup(void); extern void pinMode(int pin, int mode); extern int digitalRead(int pin); extern void digitalWrite (int pin, int value); extern void portPiUnset(void); #endif portPi.c如下: #include #include #include #include #include #include #include #include #include #include #include #include "portPi.h" #define PIO_BASE 0x01c20800 #define PI_GPIO_MASK (0xFFFFFFC0) #define PORT_CFG_OFFSET(x,i) ((x*0x24+0x04*i)>>2) #define PAGE_SIZE (4096) #define PAGE_MASK (PAGE_SIZE - 1) #define MMAP_SIZE (PAGE_SIZE*2) static volatile uint32_t *gpio; static int fd_mem; uint32_t mmap_base;//must be a multiple of the page size uint32_t mmap_seek;//the phy addr's offset static uint8_t gpioToGPSET [] = //A,B,C,D,E,F,G,H,I 0,1,2,3,4,5,6,7,8 { 8,7,8,8,7,7,8,8, 1,1,8,8,8,8,8,7, 7,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8, }; static uint8_t gpioToGPCSEL [] = //CFG0,CFG1,CFG2,CFG3 { 2,0,2,2,2,2,2,0, 2,2,1,1,1,1,1,0, 0,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, }; static uint8_t gpioToShift [] = //control regsiter bit offset { 12,8,8,4,16,20,0,12, 20,16,8,24,16,20,12,0, 4,12,12,12,12,12,12,12, 12,12,12,12,12,12,12,12, 12,12,12,12,12,12,12,12, 12,12,12,12,12,12,12,12, 12,12,12,12,12,12,12,12, 12,12,12,12,12,12,12,12, } ; static uint8_t gpioDataShift [] = //data shift { 19,2,18,17,20,21,16,3, 21,20,10,14,12,13,11,0, 1,19,19,19,19,19,19,19, 19,19,19,19,19,19,19,19, 19,19,19,19,19,19,19,19, 19,19,19,19,19,19,19,19, 19,19,19,19,19,19,19,19, 19,19,19,19,19,19,19,19, } ; extern int portPiSetup (void) { mmap_base=(PIO_BASE&~PAGE_MASK); mmap_seek=(PIO_BASE-mmap_base)>>2; fd_mem = open("/dev/mem",O_RDWR); if(-1 == fd_mem){ printf("open /dev/men failed!n"); return -1; } gpio = (uint32_t *)mmap(NULL, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd_mem, mmap_base) ; if (0 == gpio){ close(fd_mem); return -1; } return 0; } extern void pinMode (int pin, int mode) { int port_shift,cfg_shift,control_shift; if ((pin & PI_GPIO_MASK) == 0) { port_shift = gpioToGPSET[pin] ; //port cfg_shift = gpioToGPCSEL[pin] ; //cfg control_shift = gpioToShift[pin] ; //control shift bits //if mode=input if(mode==INPUT) *(gpio+mmap_seek+PORT_CFG_OFFSET(port_shift,cfg_shift))=(*(gpio +mmap_seek+PORT_CFG_OFFSET(port_shift,cfg_shift)) & ~(7 << control_shift));//set port i as input else if (mode == OUTPUT) *(gpio + mmap_seek+PORT_CFG_OFFSET(port_shift,cfg_shift)) = (*(gpio + mmap_seek+PORT_CFG_OFFSET(port_shift,cfg_shift)) & ~(7 << control_shift)) | (1 << control_shift) ; } } extern int digitalRead(int pin){ int port_shift,data_shift; if ((pin & PI_GPIO_MASK) == 0) { port_shift = gpioToGPSET[pin] ; //port data_shift = gpioDataShift[pin] ; //data shift if ((*(gpio +mmap_seek+PORT_CFG_OFFSET(port_shift,4)) & (1 << (data_shift & 31))) != 0) return HIGH; else return LOW; } return -1; } extern void digitalWrite (int pin, int value){ int port_shift,data_shift; if ((pin & PI_GPIO_MASK) == 0) { port_shift = gpioToGPSET[pin] ; //port data_shift = gpioDataShift[pin] ; //data shift if (value == LOW) *(gpio +mmap_seek+PORT_CFG_OFFSET(port_shift,4)) = *(gpio +mmap_seek+PORT_CFG_OFFSET(port_shift,4))&~(1<< (data_shift & 31)); else *(gpio +mmap_seek+PORT_CFG_OFFSET(port_shift,4)) = *(gpio +mmap_seek+PORT_CFG_OFFSET(port_shift,4))&(~1 << (data_shift & 31))|1 << (data_shift & 31); } } extern void portPiUnset(void){ if (0 != gpio){ munmap((uint32_t *)gpio, MMAP_SIZE); close(fd_mem); } } 编写Makefile文件 这里的Makefile文件只是编译出静态库,以及将头文件和库放到指定目录下: # Makefile for libportPi CC=ARM-linux-gnueabihf-gcc CFLAGS=-Wall AR=ar AFLAGS=-rc INSTALL=install TESTSRC=portPi.c TESTOBJ=libportPi.o TESTINC=portPi.h TESTLIB=libportPi.a DIRINC=/usr/include/ DIRLIB=/usr/lib/ all: $(TESTSRC) $(CC) $(CFLAGS) -o $(TESTOBJ) -c $(TESTSRC) $(AR) $(AFLAGS) $(TESTLIB) $(TESTOBJ) clean: rm $(TESTOBJ) $(TESTLIB) install: $(TESTINC) $(TESTLIB) $(INSTALL) $(TESTLIB) -m 644 $(DIRLIB) $(INSTALL) $(TESTINC) -m 644 $(DIRINC) remove: make uninstall uninstall: rm -f $(DIRLIB)$(TESTLIB) rm -f $(DIRINC)$(TESTINC) 进入目录: #make #sudo make install 就可以生成静态库了。 编写测试程序 编写测试程序的开发环境为:eclipse+CDT,这里需要在Properties--C/C++ Build--Settings--GCC C++ Linker--Libraries 加上编译后的静态库 #include #include #include #include #include #include #include #include int main (void) { int i; unsigned long read_data; portPiSetup(); pinMode (0, 0);//input pinMode (1, 1);//output for (;;) { digitalWrite(1,LOW); sleep(1); read_data=digitalRead(0); printf("pin0=%xn",read_data); digitalWrite(1,HIGH); sleep(1); read_data=digitalRead(0); printf("pin0=%xn",read_data); } portPiUnset(); return 0; } 将pin0和pin1用导线连接,程序运行结果如下:
|
|
相关推荐 |
|
只有小组成员才能发言,加入小组>>
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-8 10:57 , Processed in 0.699282 second(s), Total 39, Slave 29 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号