刚才和一个朋友聊天,说 linux的门坎太高。控制硬件必须通过驱动。 我的这个例子是独创,通过地址映射直接控制硬件。 这可是花了我一个月功夫搞定的。 这样很多对linux不怎么了解的人很容易学会这个程序。 估计这个程序对15us以上的数据采集速度应该问题不大。 用到是是pc口。是我的那个A9 core板的一个例子。
/*------------------------------------------------------------------------------------- date:20070625 author: wkj ver 1.0 contrl 8*8 led matrix example ,Application direct control HardWare input:XXXXXX output:return 0 ---------------------------------------------------------------------------------------*/ #include <sys/types.h> #include <stdio.h> #include <stdarg.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <signal.h> #include <time.h> #include <sys/time.h> #include <sys/ioctl.h> #include <sys/stat.h> #include <sys/file.h> #include "gpio.h" #include "main.h" #include "io.h" #include <stdarg.h> #include <memory.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/mman.h> #include <sys/ioctl.h> #include <fcntl.h> #include <signal.h> #include "font5x7.h" #define DEVICE_FILE_NAME "scan_keyb"
void *map_base; //phy 0xffff f000 virtual address
#define DEBUGMSG(x, y, args...) printf(y, ##args)
//#define DEBUGMSG(x, y, args...) FILE *f; int n,fd;
int main(int argc, char *argv[]) { char num,status=0; int i,j,count; int ch; printf("start
"); if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1){ DEBUGMSG(DEBUG_ERR, "gpio: Error opening /dev/mem
"); exit(-1); } //map 0xffff map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, AT91_SYS);//AT91_SYS = 0xffff f000 *((volatile unsigned int*)(map_base + ((PIOC_OFFSET + AT91_PIO_PER )))) = 0xFFFF0000; //PC31:PC16 as gpio *((volatile unsigned int*)(map_base + ((PIOC_OFFSET + AT91_PIO_OER )))) = 0xFFFF0000;
/* 8*8 LED mattix 1 A 2 B 3 C 4 D 5 E 6 F 7 G 8 H Data(-) scan line(+) D0-8-PC16 D0-1-PC31 D1-7-PC18 D1-6-PC20 D2-3-PC24 D2-A-PC30 D3-C-PC25 D3-4-PC27 D4-2-PC29 D4-H-PC17 D5-E-PC23 D5-B-PC28 D6-F-PC21 D6-G-PC19 D7-5-PC22 D7-D-PC26
*/ for(;;) //dispaly all character in Fonts lib { *((volatile unsigned int*)(map_base + ((PIOC_OFFSET + AT91_PIO_CODR)))) = 0xFFFF0000; //0 default state usleep(1000000); for (i=0;i<8;i++) { *((volatile unsigned int*)(map_base + ((PIOC_OFFSET + AT91_PIO_CODR)))) = (0x1<<31)|(0x1<<20)|(0x1<<30)|(0x1<<27)|(0x1<<17)|(0x1<<28)|(0x1<<19)|(0x1<<26); *((volatile unsigned int*)(map_base + ((PIOC_OFFSET + AT91_PIO_SODR)))) =(0x1<<16)|(0x1<<18)|(0x1<<24)|(0x1<<25)|(0x1<<29) |(0x1<<23)|(0x1<<21)|(0x1<<22);//all col light off /* //*((volatile unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_CODR))))=0xffff0000; //= (0x1<<31)|(0x1<<20)|(0x1<<30)|(0x1<<27)|(0x1<<17)|(0x1<<28)|(0x1<<19)|(0x1<<26); *((volatile unsigned int*)(map_base + ((PIOC_OFFSET + AT91_PIO_SODR)))) = (0x1<<31);//|(0x1<<20)|(0x1<<30)|(0x1<<27)|(0x1<<17)|(0x1<<28)|(0x1<<19)|(0x1<<26); *((volatile unsigned int*)(map_base + ((PIOC_OFFSET + AT91_PIO_CODR)))) =(0x1<<16);//|(0x1<<18)|(0x1<<24)|(0x1<<25)|(0x1<<29) //|(0x1<<23)|(0x1<<21)|(0x1<<22); for(;;); */ switch (i) {//select which col is on case 0://D0.PC31=1 *((volatile unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_SODR)))) = 0x1<<31; break; case 1://D1.PC20=1 *((volatile unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_SODR)))) = 0x1<<20; break; case 2://D2.PC30=1 *((volatile unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_SODR)))) = 0x1<<30; break; case 3://D3.PC27=1 *((volatile unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_SODR)))) = 0x1<<27; break; case 4://D4.PC17=1 *((volatile unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_SODR)))) = 0x1<<17; break; case 5://D5.PC28=1 *((volatile unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_SODR)))) = 0x1<<28; break; case 6://D6.PC19=1 *((volatile unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_SODR)))) = 0x1<<19; break; case 7://D7.PC26=1 *((volatile unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_SODR)))) = 0x1<<26; break; } //Put on col line Fonts[i+j]
for (j=0;j<8;j++) //LED matrix col 0..7 { switch (j)//col dot {//1 mean the colum is on case 0://D0.PC16=0 *((volatile unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_CODR)))) = 0x1<<16; break; case 1: *((volatile unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_CODR)))) = 0x1<<18; break; case 2: *((volatile unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_CODR)))) = 0x1<<24; break; case 3: *((volatile unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_CODR)))) = 0x1<<25; break; case 4: *((volatile unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_CODR)))) = 0x1<<29; break; case 5: *((volatile unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_CODR)))) = 0x1<<23; break; case 6: *((volatile unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_CODR)))) = 0x1<<21; break; case 7: *((volatile unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_CODR)))) = 0x1<<22; break; } printf("%d,%d
",i,j); usleep(300000); } } } close(fd); return 0; }
|