字符设备驱动程序

一、      实验目的和要求

1.    学习嵌入式Linux的GPIO的使用方式;

2.    学习嵌入式Linux的Arduino接口库;

3.    学习使用面包板搭简单的外部电路;

4.    学习Linux设备驱动程序的开发过程;

5.    学习在内核中访问外设寄存器,操作外设的方法

 

二、      实验器材

1.    Linux实验板卡一块;

2.    5V/1A电源一个;

3.    microUSB线一根;

4.    面包板一块;

5.    MAX7219驱动的8*8 LED矩阵一个;

6.    面包线若干;

7.    MacOS一台;

8.    USE-TTL串口线一根

9.    以太网线一根;

10.  交叉编译软件

 

三、      实验内容和原理

1.设计方法,画连接示意图;

2.在面包板上连线,完成外部电路;

3.编写C/C++程序,采用Arduino-ish库或虚拟文件系统访问GPIO,实现在矩阵上显示文字或图案;

4.编写字符设备驱动程序,直接访问GPIO控制寄存器,能将write()送来的单个字符在矩阵上显示出来

 

四、      实验过程和数据记录

1.    以下是实物连接图

GPIO端口使用bcm编号的23,24,25,对应WiringPi的4,5,6号端口,分别连接到驱动板的DIN,CS,CLK

 

2.    使用Wiring访问GPIO

在用户级别程序访问GPIO,使用Wiring是个很好的选择。

#include <stdio.h>

#include <wiringPi.h>

 

#define PIN_DIN 4  // GPIO端口号,对应驱动板的DIN

#define PIN_CS  5  //GPIO端口号,对应驱动板的CS

#define PIN_CLK 6  //GPIO端口号,对应驱动板的CLK

 

unsigned char disp1[256][8] = { //ASCII码字体数据

{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0x0

{ 0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E }, //0x1

{ 0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E }, //0x2

{ 0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00 }, //0x3

{ 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00 }, //0x4

{ 0x38, 0x7C, 0x38, 0xFE, 0xFE, 0x7C, 0x38, 0x7C }, //0x5

{ 0x10, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C }, //0x6

{ 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00 }, //0x7

{ 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF }, //0x8

{ 0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00 }, //0x9

{ 0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF }, //0xA

{ 0x0F, 0x07, 0x0F, 0x7D, 0xCC, 0xCC, 0xCC, 0x78 }, //0xB

{ 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18 }, //0xC

{ 0x3F, 0x33, 0x3F, 0x30, 0x30, 0x70, 0xF0, 0xE0 }, //0xD

{ 0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0 }, //0xE

{ 0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99 }, //0xF

{ 0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80, 0x00 }, //0x10

{ 0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00 }, //0x11

{ 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E, 0x3C, 0x18 }, //0x12

{ 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00 }, //0x13

{ 0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00 }, //0x14

{ 0x3E, 0x63, 0x38, 0x6C, 0x6C, 0x38, 0xCC, 0x78 }, //0x15

{ 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x00 }, //0x16

{ 0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF }, //0x17

{ 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00 }, //0x18

{ 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00 }, //0x19

{ 0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00 }, //0x1A

{ 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00 }, //0x1B

{ 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00 }, //0x1C

{ 0x00, 0x24, 0x66, 0xFF, 0x66, 0x24, 0x00, 0x00 }, //0x1D

{ 0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x00, 0x00 }, //0x1E

{ 0x00, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x00, 0x00 }, //0x1F

{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0x20

{ 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00 }, //0x21

{ 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0x22

{ 0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00 }, //0x23

{ 0x30, 0x7C, 0xC0, 0x78, 0x0C, 0xF8, 0x30, 0x00 }, //0x24

{ 0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00 }, //0x25

{ 0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00 }, //0x26

{ 0x60, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0x27

{ 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00 }, //0x28

{ 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00 }, //0x29

{ 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00 }, //0x2A

{ 0x00, 0x30, 0x30, 0xFC, 0x30, 0x30, 0x00, 0x00 }, //0x2B

{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60 }, //0x2C

{ 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00 }, //0x2D

{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00 }, //0x2E

{ 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00 }, //0x2F

{ 0x7C, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0x7C, 0x00 }, //0x30

{ 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xFC, 0x00 }, //0x31

{ 0x78, 0xCC, 0x0C, 0x38, 0x60, 0xCC, 0xFC, 0x00 }, //0x32

{ 0x78, 0xCC, 0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00 }, //0x33

{ 0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x1E, 0x00 }, //0x34

{ 0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00 }, //0x35

{ 0x38, 0x60, 0xC0, 0xF8, 0xCC, 0xCC, 0x78, 0x00 }, //0x36

{ 0xFC, 0xCC, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00 }, //0x37

{ 0x78, 0xCC, 0xCC, 0x78, 0xCC, 0xCC, 0x78, 0x00 }, //0x38

{ 0x78, 0xCC, 0xCC, 0x7C, 0x0C, 0x18, 0x70, 0x00 }, //0x39

{ 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00 }, //0x3A

{ 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60 }, //0x3B

{ 0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00 }, //0x3C

{ 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFC, 0x00, 0x00 }, //0x3D

{ 0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00 }, //0x3E

{ 0x78, 0xCC, 0x0C, 0x18, 0x30, 0x00, 0x30, 0x00 }, //0x3F

{ 0x7C, 0xC6, 0xDE, 0xDE, 0xDE, 0xC0, 0x78, 0x00 }, //0x40

{ 0x30, 0x78, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00 }, //0x41

{ 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00 }, //0x42

{ 0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0x66, 0x3C, 0x00 }, //0x43

{ 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00 }, //0x44

{ 0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00 }, //0x45

{ 0xFE, 0x62, 0x68, 0x78, 0x68, 0x60, 0xF0, 0x00 }, //0x46

{ 0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3E, 0x00 }, //0x47

{ 0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00 }, //0x48

{ 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0x49

{ 0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00 }, //0x4A

{ 0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00 }, //0x4B

{ 0xF0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00 }, //0x4C

{ 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00 }, //0x4D

{ 0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00 }, //0x4E

{ 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00 }, //0x4F

{ 0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00 }, //0x50

{ 0x78, 0xCC, 0xCC, 0xCC, 0xDC, 0x78, 0x1C, 0x00 }, //0x51

{ 0xFC, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0xE6, 0x00 }, //0x52

{ 0x78, 0xCC, 0xE0, 0x70, 0x1C, 0xCC, 0x78, 0x00 }, //0x53

{ 0xFC, 0xB4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0x54

{ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00 }, //0x55

{ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00 }, //0x56

{ 0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0xEE, 0xC6, 0x00 }, //0x57

{ 0xC6, 0xC6, 0x6C, 0x38, 0x38, 0x6C, 0xC6, 0x00 }, //0x58

{ 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x78, 0x00 }, //0x59

{ 0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00 }, //0x5A

{ 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00 }, //0x5B

{ 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00 }, //0x5C

{ 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00 }, //0x5D

{ 0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00 }, //0x5E

{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF }, //0x5F

{ 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0x60

{ 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00 }, //0x61

{ 0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xDC, 0x00 }, //0x62

{ 0x00, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00 }, //0x63

{ 0x1C, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00 }, //0x64

{ 0x00, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00 }, //0x65

{ 0x38, 0x6C, 0x60, 0xF0, 0x60, 0x60, 0xF0, 0x00 }, //0x66

{ 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8 }, //0x67

{ 0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00 }, //0x68

{ 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0x69

{ 0x0C, 0x00, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78 }, //0x6A

{ 0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00 }, //0x6B

{ 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0x6C

{ 0x00, 0x00, 0xCC, 0xFE, 0xFE, 0xD6, 0xC6, 0x00 }, //0x6D

{ 0x00, 0x00, 0xF8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00 }, //0x6E

{ 0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00 }, //0x6F

{ 0x00, 0x00, 0xDC, 0x66, 0x66, 0x7C, 0x60, 0xF0 }, //0x70

{ 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E }, //0x71

{ 0x00, 0x00, 0xDC, 0x76, 0x66, 0x60, 0xF0, 0x00 }, //0x72

{ 0x00, 0x00, 0x7C, 0xC0, 0x78, 0x0C, 0xF8, 0x00 }, //0x73

{ 0x10, 0x30, 0x7C, 0x30, 0x30, 0x34, 0x18, 0x00 }, //0x74

{ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00 }, //0x75

{ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00 }, //0x76

{ 0x00, 0x00, 0xC6, 0xD6, 0xFE, 0xFE, 0x6C, 0x00 }, //0x77

{ 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00 }, //0x78

{ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8 }, //0x79

{ 0x00, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00 }, //0x7A

{ 0x1C, 0x30, 0x30, 0xE0, 0x30, 0x30, 0x1C, 0x00 }, //0x7B

{ 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00 }, //0x7C

{ 0xE0, 0x30, 0x30, 0x1C, 0x30, 0x30, 0xE0, 0x00 }, //0x7D

{ 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0x7E

{ 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00 }, //0x7F

{ 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x18, 0x0C, 0x78 }, //0x80

{ 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00 }, //0x81

{ 0x1C, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00 }, //0x82

{ 0x7E, 0xC3, 0x3C, 0x06, 0x3E, 0x66, 0x3F, 0x00 }, //0x83

{ 0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00 }, //0x84

{ 0xE0, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00 }, //0x85

{ 0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00 }, //0x86

{ 0x00, 0x00, 0x78, 0xC0, 0xC0, 0x78, 0x0C, 0x38 }, //0x87

{ 0x7E, 0xC3, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00 }, //0x88

{ 0xCC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00 }, //0x89

{ 0xE0, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00 }, //0x8A

{ 0xCC, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0x8B

{ 0x7C, 0xC6, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00 }, //0x8C

{ 0xE0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0x8D

{ 0xC6, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0xC6, 0x00 }, //0x8E

{ 0x30, 0x30, 0x00, 0x78, 0xCC, 0xFC, 0xCC, 0x00 }, //0x8F

{ 0x1C, 0x00, 0xFC, 0x60, 0x78, 0x60, 0xFC, 0x00 }, //0x90

{ 0x00, 0x00, 0x7F, 0x0C, 0x7F, 0xCC, 0x7F, 0x00 }, //0x91

{ 0x3E, 0x6C, 0xCC, 0xFE, 0xCC, 0xCC, 0xCE, 0x00 }, //0x92

{ 0x78, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00 }, //0x93

{ 0x00, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00 }, //0x94

{ 0x00, 0xE0, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00 }, //0x95

{ 0x78, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00 }, //0x96

{ 0x00, 0xE0, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00 }, //0x97

{ 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8 }, //0x98

{ 0xC3, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x00 }, //0x99

{ 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x00 }, //0x9A

{ 0x18, 0x18, 0x7E, 0xC0, 0xC0, 0x7E, 0x18, 0x18 }, //0x9B

{ 0x38, 0x6C, 0x64, 0xF0, 0x60, 0xE6, 0xFC, 0x00 }, //0x9C

{ 0xCC, 0xCC, 0x78, 0xFC, 0x30, 0xFC, 0x30, 0x30 }, //0x9D

{ 0xF8, 0xCC, 0xCC, 0xFA, 0xC6, 0xCF, 0xC6, 0xC7 }, //0x9E

{ 0x0E, 0x1B, 0x18, 0x3C, 0x18, 0x18, 0xD8, 0x70 }, //0x9F

{ 0x1C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00 }, //0xA0

{ 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0xA1

{ 0x00, 0x1C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00 }, //0xA2

{ 0x00, 0x1C, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00 }, //0xA3

{ 0x00, 0xF8, 0x00, 0xF8, 0xCC, 0xCC, 0xCC, 0x00 }, //0xA4

{ 0xFC, 0x00, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00 }, //0xA5

{ 0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00 }, //0xA6

{ 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00 }, //0xA7

{ 0x30, 0x00, 0x30, 0x60, 0xC0, 0xCC, 0x78, 0x00 }, //0xA8

{ 0x00, 0x00, 0x00, 0xFC, 0xC0, 0xC0, 0x00, 0x00 }, //0xA9

{ 0x00, 0x00, 0x00, 0xFC, 0x0C, 0x0C, 0x00, 0x00 }, //0xAA

{ 0xC3, 0xC6, 0xCC, 0xDE, 0x33, 0x66, 0xCC, 0x0F }, //0xAB

{ 0xC3, 0xC6, 0xCC, 0xDB, 0x37, 0x6F, 0xCF, 0x03 }, //0xAC

{ 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00 }, //0xAD

{ 0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00 }, //0xAE

{ 0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00 }, //0xAF

{ 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88 }, //0xB0

{ 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA }, //0xB1

{ 0xDB, 0x77, 0xDB, 0xEE, 0xDB, 0x77, 0xDB, 0xEE }, //0xB2

{ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 }, //0xB3

{ 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18 }, //0xB4

{ 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18 }, //0xB5

{ 0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36 }, //0xB6

{ 0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36 }, //0xB7

{ 0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18 }, //0xB8

{ 0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36 }, //0xB9

{ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 }, //0xBA

{ 0x00, 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36 }, //0xBB

{ 0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00 }, //0xBC

{ 0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00 }, //0xBD

{ 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00 }, //0xBE

{ 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18 }, //0xBF

{ 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00 }, //0xC0

{ 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00 }, //0xC1

{ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18 }, //0xC2

{ 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18 }, //0xC3

{ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00 }, //0xC4

{ 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18 }, //0xC5

{ 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18 }, //0xC6

{ 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36 }, //0xC7

{ 0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00 }, //0xC8

{ 0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36 }, //0xC9

{ 0x36, 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00 }, //0xCA

{ 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36 }, //0xCB

{ 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36 }, //0xCC

{ 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00 }, //0xCD

{ 0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36 }, //0xCE

{ 0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00 }, //0xCF

{ 0x36, 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00 }, //0xD0

{ 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18 }, //0xD1

{ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36 }, //0xD2

{ 0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00 }, //0xD3

{ 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00 }, //0xD4

{ 0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18 }, //0xD5

{ 0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36 }, //0xD6

{ 0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36 }, //0xD7

{ 0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18 }, //0xD8

{ 0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00 }, //0xD9

{ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18 }, //0xDA

{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, //0xDB

{ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF }, //0xDC

{ 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0 }, //0xDD

{ 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F }, //0xDE

{ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 }, //0xDF

{ 0x00, 0x00, 0x76, 0xDC, 0xC8, 0xDC, 0x76, 0x00 }, //0xE0

{ 0x00, 0x78, 0xCC, 0xF8, 0xCC, 0xF8, 0xC0, 0xC0 }, //0xE1

{ 0x00, 0xFC, 0xCC, 0xC0, 0xC0, 0xC0, 0xC0, 0x00 }, //0xE2

{ 0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x00 }, //0xE3

{ 0xFC, 0xCC, 0x60, 0x30, 0x60, 0xCC, 0xFC, 0x00 }, //0xE4

{ 0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0x70, 0x00 }, //0xE5

{ 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0xC0 }, //0xE6

{ 0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x00 }, //0xE7

{ 0xFC, 0x30, 0x78, 0xCC, 0xCC, 0x78, 0x30, 0xFC }, //0xE8

{ 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x6C, 0x38, 0x00 }, //0xE9

{ 0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x6C, 0xEE, 0x00 }, //0xEA

{ 0x1C, 0x30, 0x18, 0x7C, 0xCC, 0xCC, 0x78, 0x00 }, //0xEB

{ 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0x7E, 0x00, 0x00 }, //0xEC

{ 0x06, 0x0C, 0x7E, 0xDB, 0xDB, 0x7E, 0x60, 0xC0 }, //0xED

{ 0x38, 0x60, 0xC0, 0xF8, 0xC0, 0x60, 0x38, 0x00 }, //0xEE

{ 0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x00 }, //0xEF

{ 0x00, 0xFC, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0x00 }, //0xF0

{ 0x30, 0x30, 0xFC, 0x30, 0x30, 0x00, 0xFC, 0x00 }, //0xF1

{ 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xFC, 0x00 }, //0xF2

{ 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xFC, 0x00 }, //0xF3

{ 0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18 }, //0xF4

{ 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0x70 }, //0xF5

{ 0x30, 0x30, 0x00, 0xFC, 0x00, 0x30, 0x30, 0x00 }, //0xF6

{ 0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00 }, //0xF7

{ 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00 }, //0xF8

{ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00 }, //0xF9

{ 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00 }, //0xFA

{ 0x0F, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C }, //0xFB

{ 0x78, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00 }, //0xFC

{ 0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00 }, //0xFD

{ 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00 }, //0xFE

{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0xFF

};

 

void write_byte(unsigned char data)  //最底层的传输一个byte的函数

{

    unsigned char i;

    digitalWrite(PIN_CS, LOW);

    for(i=8; i>=1; i--)

    {

        digitalWrite(PIN_CLK, LOW);

        digitalWrite(PIN_DIN, data&0x80);

        data = data<<1;

        digitalWrite(PIN_CLK, HIGH);

    }

}

 

void write(unsigned char addr, unsigned char data)  //传输一行数据函数

{

    digitalWrite(PIN_CS, LOW);

    write_byte(addr);

    write_byte(data);

    digitalWrite(PIN_CS, HIGH);

}

 

void init()  //初始化芯片

{

    write(0x09, 0x00);

    write(0x0a, 0x03);

    write(0x0b, 0x07);

    write(0x0c, 0x01);

    write(0x0f, 0x00);

}

 

int main()

{

    unsigned char i, j;

 

    wiringPiSetup();

    pinMode(PIN_DIN, OUTPUT);

    pinMode(PIN_CS, OUTPUT);

    pinMode(PIN_CLK, OUTPUT);

 

    init();

    while (1)

    {

        for(j=0; j<256; j++)

        {

            for(i=1; i<9; i++)

                write(i, disp1[j][i-1]);

            printf("0x%02X\n", j);

            delay(500);

        } 

    }

    return 0;

}

 

从以下两个图片来看,显示效果良好

 

3.    Linux字符设备驱动

Linux内核模块能更方便快捷地调整内核功能,而无需重新编译内核花费巨大的时间。通过编写字符设备驱动模块,能够使得系统通过/dev以字符设备的方式来写数据到8*8的led矩阵中显示。

#include <linux/init.h>           // 用于标记函数的宏,如_init、__exit

#include <linux/module.h>         // 将内核模块加载到内核中的核心头文件

#include <linux/device.h>         // 支持内核驱动模型的头文件

#include <linux/kernel.h>         // 包含内核中的类型、宏和函数

#include <linux/fs.h>             // 支持Linux文件系统的头文件

#include <asm/uaccess.h>          // 复制到用户用户空间函数需要的头文件

#include <linux/gpio.h>           // GPIO

#define  DEVICE_NAME "matrix"     ///< 使用此值,设备将会展示在/dev/matrix

#define  CLASS_NAME  "mat"        ///< 设备类名,这是一个字符设备驱动

 

MODULE_LICENSE("GPL");            ///< 许可类型,这回影响到可用功能

MODULE_VERSION("0.1");            ///< 告知用户的版本号

 

static int    majorNumber;                  ///< 保存主设备号,这里自动确定

static char   message[256] = {0};           ///< 用于保存从用户空间传输过来字符串的内存

static short  size_of_message;              ///< 用于记录保存的字符串长度

static int    numberOpens = 0;              ///< 用于保存设备打开次数的计数器

static struct class*  matClass  = NULL; ///< 设备驱动类结构体指针

static struct device* matDevice = NULL; ///< 设备驱动设备结构体指针

 

// 字符设备操作的函数原型,必须在结构体定义前定义

static int     dev_open(struct inode *, struct file *);

static int     dev_release(struct inode *, struct file *);

static ssize_t dev_read(struct file *, char *, size_t, loff_t *);

static ssize_t dev_write(struct file *, const char *, size_t, loff_t *);

 

/** @brief 设备在内核中被表示为文件结构。 /linux/fs.h中定义的file_operations结构体,

 * 它使用C99语法的结构体,列举了文件操作关联的回调函数。

 * 字符设备通常需要实现open、read、write和release函数。

 */

static struct file_operations fops =

{

   .open = dev_open,

   .read = dev_read,

   .write = dev_write,

   .release = dev_release,

};

 

/** @brief 可加载内核模块初始化函数

 *  static关键字限制该函数的可见性在该C文件之内。 The __init

 *  __init宏对于内置驱动(非可加载内核模块)来说,只在初始化时调用,在此之后,该函数将被废弃,内存将被回收。

 *  @return 如果成功返回0

 */

static int __init matrix_init(void){

   printk(KERN_INFO "Initializing matrix.\n");

 

   // 尝试为这个设备动态生成一个主设备号,虽然麻烦一点,但这是值得的

   majorNumber = register_chrdev(0, DEVICE_NAME, &fops);

   if (majorNumber<0){

      printk(KERN_ALERT "Failed to register a major number.\n");

      return majorNumber;

   }

   // printk(KERN_INFO "EBBChar: registered correctly with major number %d\n", majorNumber);

 

   // 注册设备类

   matClass = class_create(THIS_MODULE, CLASS_NAME);

   if (IS_ERR(matClass)){                // 如果有错误,清理环境

      unregister_chrdev(majorNumber, DEVICE_NAME);

      printk(KERN_ALERT "Failed to register device class.\n");

      return PTR_ERR(matClass);          // 对于指针类型返回错误消息正确的方式

   }

   // printk(KERN_INFO "EBBChar: device class registered correctly\n");

 

   // 注册设备驱动

   matDevice = device_create(matClass, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME);

   if (IS_ERR(matDevice)){               // 如果有错误,清理环境

      class_destroy(matClass);           // 重复的代码,可选方式是使用goto语句

      unregister_chrdev(majorNumber, DEVICE_NAME);

      printk(KERN_ALERT "Failed to create the device.\n");

      return PTR_ERR(matDevice);

   }

   // printk(KERN_INFO "EBBChar: device class created correctly\n"); // 搞定,设备已经初始化

   return 0;

}

 

/** @brief 可加载内核模块清理函数

 *  和初始化函数类似,该函数是静态的。__exit宏标识如果这个代码是使用在内置驱动(非可加载内核模块)中,该函数不需要。

 */

static void __exit matrix_exit(void){

   device_destroy(matClass, MKDEV(majorNumber, 0));     // 移除设备

   class_unregister(matClass);                          // 注销设备类

   class_destroy(matClass);                             // 移除设备类

   unregister_chrdev(majorNumber, DEVICE_NAME);             // 注销主设备号

   printk(KERN_INFO "Goodbye!\n");

}

 

static unsigned PIN_DIN = 23;

static unsigned PIN_CS = 24;

static unsigned PIN_CLK = 25;

 

static unsigned char disp1[256][8] = {

{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0x0

{ 0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E }, //0x1

{ 0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E }, //0x2

{ 0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00 }, //0x3

{ 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00 }, //0x4

{ 0x38, 0x7C, 0x38, 0xFE, 0xFE, 0x7C, 0x38, 0x7C }, //0x5

{ 0x10, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C }, //0x6

{ 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00 }, //0x7

{ 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF }, //0x8

{ 0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00 }, //0x9

{ 0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF }, //0xA

{ 0x0F, 0x07, 0x0F, 0x7D, 0xCC, 0xCC, 0xCC, 0x78 }, //0xB

{ 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18 }, //0xC

{ 0x3F, 0x33, 0x3F, 0x30, 0x30, 0x70, 0xF0, 0xE0 }, //0xD

{ 0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0 }, //0xE

{ 0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99 }, //0xF

{ 0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80, 0x00 }, //0x10

{ 0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00 }, //0x11

{ 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E, 0x3C, 0x18 }, //0x12

{ 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00 }, //0x13

{ 0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00 }, //0x14

{ 0x3E, 0x63, 0x38, 0x6C, 0x6C, 0x38, 0xCC, 0x78 }, //0x15

{ 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x00 }, //0x16

{ 0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF }, //0x17

{ 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00 }, //0x18

{ 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00 }, //0x19

{ 0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00 }, //0x1A

{ 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00 }, //0x1B

{ 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00 }, //0x1C

{ 0x00, 0x24, 0x66, 0xFF, 0x66, 0x24, 0x00, 0x00 }, //0x1D

{ 0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x00, 0x00 }, //0x1E

{ 0x00, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x00, 0x00 }, //0x1F

{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0x20

{ 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00 }, //0x21

{ 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0x22

{ 0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00 }, //0x23

{ 0x30, 0x7C, 0xC0, 0x78, 0x0C, 0xF8, 0x30, 0x00 }, //0x24

{ 0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00 }, //0x25

{ 0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00 }, //0x26

{ 0x60, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0x27

{ 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00 }, //0x28

{ 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00 }, //0x29

{ 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00 }, //0x2A

{ 0x00, 0x30, 0x30, 0xFC, 0x30, 0x30, 0x00, 0x00 }, //0x2B

{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60 }, //0x2C

{ 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00 }, //0x2D

{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00 }, //0x2E

{ 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00 }, //0x2F

{ 0x7C, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0x7C, 0x00 }, //0x30

{ 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xFC, 0x00 }, //0x31

{ 0x78, 0xCC, 0x0C, 0x38, 0x60, 0xCC, 0xFC, 0x00 }, //0x32

{ 0x78, 0xCC, 0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00 }, //0x33

{ 0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x1E, 0x00 }, //0x34

{ 0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00 }, //0x35

{ 0x38, 0x60, 0xC0, 0xF8, 0xCC, 0xCC, 0x78, 0x00 }, //0x36

{ 0xFC, 0xCC, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00 }, //0x37

{ 0x78, 0xCC, 0xCC, 0x78, 0xCC, 0xCC, 0x78, 0x00 }, //0x38

{ 0x78, 0xCC, 0xCC, 0x7C, 0x0C, 0x18, 0x70, 0x00 }, //0x39

{ 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00 }, //0x3A

{ 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60 }, //0x3B

{ 0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00 }, //0x3C

{ 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFC, 0x00, 0x00 }, //0x3D

{ 0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00 }, //0x3E

{ 0x78, 0xCC, 0x0C, 0x18, 0x30, 0x00, 0x30, 0x00 }, //0x3F

{ 0x7C, 0xC6, 0xDE, 0xDE, 0xDE, 0xC0, 0x78, 0x00 }, //0x40

{ 0x30, 0x78, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00 }, //0x41

{ 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00 }, //0x42

{ 0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0x66, 0x3C, 0x00 }, //0x43

{ 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00 }, //0x44

{ 0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00 }, //0x45

{ 0xFE, 0x62, 0x68, 0x78, 0x68, 0x60, 0xF0, 0x00 }, //0x46

{ 0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3E, 0x00 }, //0x47

{ 0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00 }, //0x48

{ 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0x49

{ 0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00 }, //0x4A

{ 0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00 }, //0x4B

{ 0xF0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00 }, //0x4C

{ 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00 }, //0x4D

{ 0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00 }, //0x4E

{ 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00 }, //0x4F

{ 0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00 }, //0x50

{ 0x78, 0xCC, 0xCC, 0xCC, 0xDC, 0x78, 0x1C, 0x00 }, //0x51

{ 0xFC, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0xE6, 0x00 }, //0x52

{ 0x78, 0xCC, 0xE0, 0x70, 0x1C, 0xCC, 0x78, 0x00 }, //0x53

{ 0xFC, 0xB4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0x54

{ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00 }, //0x55

{ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00 }, //0x56

{ 0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0xEE, 0xC6, 0x00 }, //0x57

{ 0xC6, 0xC6, 0x6C, 0x38, 0x38, 0x6C, 0xC6, 0x00 }, //0x58

{ 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x78, 0x00 }, //0x59

{ 0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00 }, //0x5A

{ 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00 }, //0x5B

{ 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00 }, //0x5C

{ 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00 }, //0x5D

{ 0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00 }, //0x5E

{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF }, //0x5F

{ 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0x60

{ 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00 }, //0x61

{ 0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xDC, 0x00 }, //0x62

{ 0x00, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00 }, //0x63

{ 0x1C, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00 }, //0x64

{ 0x00, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00 }, //0x65

{ 0x38, 0x6C, 0x60, 0xF0, 0x60, 0x60, 0xF0, 0x00 }, //0x66

{ 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8 }, //0x67

{ 0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00 }, //0x68

{ 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0x69

{ 0x0C, 0x00, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78 }, //0x6A

{ 0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00 }, //0x6B

{ 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0x6C

{ 0x00, 0x00, 0xCC, 0xFE, 0xFE, 0xD6, 0xC6, 0x00 }, //0x6D

{ 0x00, 0x00, 0xF8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00 }, //0x6E

{ 0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00 }, //0x6F

{ 0x00, 0x00, 0xDC, 0x66, 0x66, 0x7C, 0x60, 0xF0 }, //0x70

{ 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E }, //0x71

{ 0x00, 0x00, 0xDC, 0x76, 0x66, 0x60, 0xF0, 0x00 }, //0x72

{ 0x00, 0x00, 0x7C, 0xC0, 0x78, 0x0C, 0xF8, 0x00 }, //0x73

{ 0x10, 0x30, 0x7C, 0x30, 0x30, 0x34, 0x18, 0x00 }, //0x74

{ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00 }, //0x75

{ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00 }, //0x76

{ 0x00, 0x00, 0xC6, 0xD6, 0xFE, 0xFE, 0x6C, 0x00 }, //0x77

{ 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00 }, //0x78

{ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8 }, //0x79

{ 0x00, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00 }, //0x7A

{ 0x1C, 0x30, 0x30, 0xE0, 0x30, 0x30, 0x1C, 0x00 }, //0x7B

{ 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00 }, //0x7C

{ 0xE0, 0x30, 0x30, 0x1C, 0x30, 0x30, 0xE0, 0x00 }, //0x7D

{ 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0x7E

{ 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00 }, //0x7F

{ 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x18, 0x0C, 0x78 }, //0x80

{ 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00 }, //0x81

{ 0x1C, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00 }, //0x82

{ 0x7E, 0xC3, 0x3C, 0x06, 0x3E, 0x66, 0x3F, 0x00 }, //0x83

{ 0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00 }, //0x84

{ 0xE0, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00 }, //0x85

{ 0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00 }, //0x86

{ 0x00, 0x00, 0x78, 0xC0, 0xC0, 0x78, 0x0C, 0x38 }, //0x87

{ 0x7E, 0xC3, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00 }, //0x88

{ 0xCC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00 }, //0x89

{ 0xE0, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00 }, //0x8A

{ 0xCC, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0x8B

{ 0x7C, 0xC6, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00 }, //0x8C

{ 0xE0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0x8D

{ 0xC6, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0xC6, 0x00 }, //0x8E

{ 0x30, 0x30, 0x00, 0x78, 0xCC, 0xFC, 0xCC, 0x00 }, //0x8F

{ 0x1C, 0x00, 0xFC, 0x60, 0x78, 0x60, 0xFC, 0x00 }, //0x90

{ 0x00, 0x00, 0x7F, 0x0C, 0x7F, 0xCC, 0x7F, 0x00 }, //0x91

{ 0x3E, 0x6C, 0xCC, 0xFE, 0xCC, 0xCC, 0xCE, 0x00 }, //0x92

{ 0x78, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00 }, //0x93

{ 0x00, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00 }, //0x94

{ 0x00, 0xE0, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00 }, //0x95

{ 0x78, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00 }, //0x96

{ 0x00, 0xE0, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00 }, //0x97

{ 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8 }, //0x98

{ 0xC3, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x00 }, //0x99

{ 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x00 }, //0x9A

{ 0x18, 0x18, 0x7E, 0xC0, 0xC0, 0x7E, 0x18, 0x18 }, //0x9B

{ 0x38, 0x6C, 0x64, 0xF0, 0x60, 0xE6, 0xFC, 0x00 }, //0x9C

{ 0xCC, 0xCC, 0x78, 0xFC, 0x30, 0xFC, 0x30, 0x30 }, //0x9D

{ 0xF8, 0xCC, 0xCC, 0xFA, 0xC6, 0xCF, 0xC6, 0xC7 }, //0x9E

{ 0x0E, 0x1B, 0x18, 0x3C, 0x18, 0x18, 0xD8, 0x70 }, //0x9F

{ 0x1C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00 }, //0xA0

{ 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0xA1

{ 0x00, 0x1C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00 }, //0xA2

{ 0x00, 0x1C, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00 }, //0xA3

{ 0x00, 0xF8, 0x00, 0xF8, 0xCC, 0xCC, 0xCC, 0x00 }, //0xA4

{ 0xFC, 0x00, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00 }, //0xA5

{ 0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00 }, //0xA6

{ 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00 }, //0xA7

{ 0x30, 0x00, 0x30, 0x60, 0xC0, 0xCC, 0x78, 0x00 }, //0xA8

{ 0x00, 0x00, 0x00, 0xFC, 0xC0, 0xC0, 0x00, 0x00 }, //0xA9

{ 0x00, 0x00, 0x00, 0xFC, 0x0C, 0x0C, 0x00, 0x00 }, //0xAA

{ 0xC3, 0xC6, 0xCC, 0xDE, 0x33, 0x66, 0xCC, 0x0F }, //0xAB

{ 0xC3, 0xC6, 0xCC, 0xDB, 0x37, 0x6F, 0xCF, 0x03 }, //0xAC

{ 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00 }, //0xAD

{ 0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00 }, //0xAE

{ 0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00 }, //0xAF

{ 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88 }, //0xB0

{ 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA }, //0xB1

{ 0xDB, 0x77, 0xDB, 0xEE, 0xDB, 0x77, 0xDB, 0xEE }, //0xB2

{ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 }, //0xB3

{ 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18 }, //0xB4

{ 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18 }, //0xB5

{ 0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36 }, //0xB6

{ 0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36 }, //0xB7

{ 0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18 }, //0xB8

{ 0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36 }, //0xB9

{ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 }, //0xBA

{ 0x00, 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36 }, //0xBB

{ 0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00 }, //0xBC

{ 0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00 }, //0xBD

{ 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00 }, //0xBE

{ 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18 }, //0xBF

{ 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00 }, //0xC0

{ 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00 }, //0xC1

{ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18 }, //0xC2

{ 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18 }, //0xC3

{ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00 }, //0xC4

{ 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18 }, //0xC5

{ 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18 }, //0xC6

{ 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36 }, //0xC7

{ 0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00 }, //0xC8

{ 0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36 }, //0xC9

{ 0x36, 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00 }, //0xCA

{ 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36 }, //0xCB

{ 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36 }, //0xCC

{ 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00 }, //0xCD

{ 0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36 }, //0xCE

{ 0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00 }, //0xCF

{ 0x36, 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00 }, //0xD0

{ 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18 }, //0xD1

{ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36 }, //0xD2

{ 0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00 }, //0xD3

{ 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00 }, //0xD4

{ 0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18 }, //0xD5

{ 0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36 }, //0xD6

{ 0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36 }, //0xD7

{ 0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18 }, //0xD8

{ 0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00 }, //0xD9

{ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18 }, //0xDA

{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, //0xDB

{ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF }, //0xDC

{ 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0 }, //0xDD

{ 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F }, //0xDE

{ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 }, //0xDF

{ 0x00, 0x00, 0x76, 0xDC, 0xC8, 0xDC, 0x76, 0x00 }, //0xE0

{ 0x00, 0x78, 0xCC, 0xF8, 0xCC, 0xF8, 0xC0, 0xC0 }, //0xE1

{ 0x00, 0xFC, 0xCC, 0xC0, 0xC0, 0xC0, 0xC0, 0x00 }, //0xE2

{ 0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x00 }, //0xE3

{ 0xFC, 0xCC, 0x60, 0x30, 0x60, 0xCC, 0xFC, 0x00 }, //0xE4

{ 0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0x70, 0x00 }, //0xE5

{ 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0xC0 }, //0xE6

{ 0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x00 }, //0xE7

{ 0xFC, 0x30, 0x78, 0xCC, 0xCC, 0x78, 0x30, 0xFC }, //0xE8

{ 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x6C, 0x38, 0x00 }, //0xE9

{ 0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x6C, 0xEE, 0x00 }, //0xEA

{ 0x1C, 0x30, 0x18, 0x7C, 0xCC, 0xCC, 0x78, 0x00 }, //0xEB

{ 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0x7E, 0x00, 0x00 }, //0xEC

{ 0x06, 0x0C, 0x7E, 0xDB, 0xDB, 0x7E, 0x60, 0xC0 }, //0xED

{ 0x38, 0x60, 0xC0, 0xF8, 0xC0, 0x60, 0x38, 0x00 }, //0xEE

{ 0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x00 }, //0xEF

{ 0x00, 0xFC, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0x00 }, //0xF0

{ 0x30, 0x30, 0xFC, 0x30, 0x30, 0x00, 0xFC, 0x00 }, //0xF1

{ 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xFC, 0x00 }, //0xF2

{ 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xFC, 0x00 }, //0xF3

{ 0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18 }, //0xF4

{ 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0x70 }, //0xF5

{ 0x30, 0x30, 0x00, 0xFC, 0x00, 0x30, 0x30, 0x00 }, //0xF6

{ 0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00 }, //0xF7

{ 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00 }, //0xF8

{ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00 }, //0xF9

{ 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00 }, //0xFA

{ 0x0F, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C }, //0xFB

{ 0x78, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00 }, //0xFC

{ 0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00 }, //0xFD

{ 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00 }, //0xFE

{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0xFF

};

 

static void writeMatrix_byte(unsigned char data)

{

    unsigned char i;

    gpio_set_value(PIN_CS, 0);

    for(i=8; i>=1; i--)

    {

        gpio_set_value(PIN_CLK, 0);

        gpio_set_value(PIN_DIN, data&0x80);

        data = data<<1;

        gpio_set_value(PIN_CLK, 1);

    }

}

 

static void writeMatrix(unsigned char addr, unsigned char data)

{

    gpio_set_value(PIN_CS, 0);

    writeMatrix_byte(addr);

    writeMatrix_byte(data);

    gpio_set_value(PIN_CS, 1);

}

 

/** @brief 每次设备被代开的时候调用的设备打开函数

 *  在本例中,该函数只是简单的累加numberOpens计数器。

 *  @param inodep 指向inode对象的指针(定义在linux/fs.h头文件中)

 *  @param filep 指向文件对象指针(定义在linux/fs.h头文件中)

 */

static int dev_open(struct inode *inodep, struct file *filep)

{

   int req_din = gpio_request(PIN_DIN, "PIN_DIN");

   int req_cs  = gpio_request(PIN_CS, "PIN_CS");

   int req_clk = gpio_request(PIN_CLK, "PIN_CLK");

 

   if (req_din || req_cs || req_clk) {

      return -1;

   }

 

   gpio_direction_output(PIN_DIN, 0);

   gpio_direction_output(PIN_CS, 0);

   gpio_direction_output(PIN_CLK, 0);

 

   numberOpens++;

   printk(KERN_INFO "Device has been opened %d time(s)\n", numberOpens);

 

   writeMatrix(0x09, 0x00);

   writeMatrix(0x0a, 0x03);

   writeMatrix(0x0b, 0x07);

   writeMatrix(0x0c, 0x01);

   writeMatrix(0x0f, 0x00);

   return 0;

}

 

/** @brief 该函数在设备从用户空间读取的时候被调用,即数据从设备向用户空间传输。

 *  在本例中,通过copy_to_user()函数将缓冲区中的字符串发送给用户,并且捕获任何异常。

 *  @param filep 指向文件对象的指针(定义在linux/fs.h头文件中)

 *  @param buffer 指向本函数写入数据的缓冲区指针

 *  @param len 缓冲区长度

 *  @param offset 此次读取在内核缓冲区中的偏移量

 */

static ssize_t dev_read(struct file *filep, char *buffer, size_t len, loff_t *offset)

{

   return 0;

}

 

/** @brief 该函数在设备想用户空间写入的时候调用,即从数据从用户发往设备。

 *  在此内核模块中,数据通过sprintf()函数复制到message[]数组中,同时字符串长度被保存到size_of_message变量中。

 *  @param filep 指向文件对象的指针

 *  @param buffer 包含待写入设备字符串的缓冲区

 *  @param len 传递到const char类型缓冲区的数据长度

 *  @param offset 文件设备当前偏移量

 */

static ssize_t dev_write(struct file *filep, const char *buffer, size_t len, loff_t *offset)

{

   //sprintf(message, "%s(%d letters)", buffer, len);   // 通过长度追加当前接受到的字符串

   unsigned char i;

   for(i = 1; i < 9; i++)

      writeMatrix(i, disp1[(unsigned char)buffer[0]][i-1]);

   size_of_message = 1;

   printk(KERN_INFO "Received characters %c from the user\n", buffer[0]);

   return len;

}

 

/** @brief 当设备被用户空间程序关闭/释放时调用的函数。

 *  @param inodep 指向inode对象的指针(定义在linux/fs.h头文件中)

 *  @param filep 指向文件对象的指针(定义在linux/fs.h头文件中)

 */

static int dev_release(struct inode *inodep, struct file *filep)

{

   gpio_free(PIN_DIN);

   gpio_free(PIN_CS);

   gpio_free(PIN_CLK);

   printk(KERN_INFO "Device closed.\n");

   return 0;

}

 

/** @brief 内核模块必须使用linux/init.h头文件中提供的module_init()、module_exit()宏,

 *  在插入和清理的时候标识对应的函数(如上所列)

 */

module_init(matrix_init);

module_exit(matrix_exit);

 

编译后,生成后缀为ko的内核模块,使用insmod插入内核模块时,可以看到内核日志中带有初始化的信息提示,在使用open()打开设备文件后,可以看到其打开的信息提示。而通过write()往设备文件中写入数据时,亦可以看到内核日志中接收到字符的提示。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值