[DM8168]Linux下控制GPIO控制12864液晶屏(ST7565控制器)

摘要:
st7565_驱动程序。c3*仅适用于LCD12864驱动程序4*GP1_ 14(46)->D6(SCK)5*GP1_ 15(47)->RST7*GP1_ 28(60)->马赫/gpio.h>linux/平台_设备.h>2829#包括<6364静电装置_ tlcd_装置;结构文件*文件);

首先加载驱动模块,应用程序通过调用API实现GPIO控制功能。

驱动函数:

  1 /*
  2 * fileName: st7565_driver.c
  3 * just for LCD12864 driver
  4 * GP1_14(46) -> D6(SCK)
  5 * GP1_15(47) -> D7(SDA)
  6 * GP1_27(59) -> RST
  7 * GP1_28(60) -> RS
  8 */
  9 
 10 #include <linux/device.h>
 11 #include <linux/fs.h>
 12 #include <linux/module.h>
 13 #include <linux/kernel.h>
 14 #include <linux/init.h>
 15 #include <linux/moduleparam.h>
 16 #include <linux/list.h>
 17 #include <linux/cdev.h>
 18 #include <linux/proc_fs.h>
 19 #include <linux/mm.h>
 20 #include <linux/seq_file.h>
 21 #include <linux/ioport.h>
 22 #include <linux/delay.h>
 23 #include <asm/io.h>
 24 #include <linux/io.h>
 25 #include <mach/gpio.h>
 26 #include <linux/device.h>
 27 #include <linux/platform_device.h>
 28 
 29 #include <linux/delay.h>
 30 
 31 // ASCII code
 32 #include "font.h"
 33 
 34 #define DRIVERNAME  "lcd12864"
 35 
 36 // PANEL CON
 37 #define CTRL_MODULE_BASE_ADDR    0x48140000
 38 #define conf_gpio46              (CTRL_MODULE_BASE_ADDR + 0x0B04)
 39 #define conf_gpio47              (CTRL_MODULE_BASE_ADDR + 0x0B08)
 40 #define conf_gpio59              (CTRL_MODULE_BASE_ADDR + 0x0AB8)
 41 #define conf_gpio60              (CTRL_MODULE_BASE_ADDR + 0x0ABC)
 42 
 43 #define WR_MEM_32(addr, data)    *(unsigned int*)OMAP2_L4_IO_ADDRESS(addr) = (unsigned int)(data)
 44 #define RD_MEM_32(addr)          *(unsigned int*)OMAP2_L4_IO_ADDRESS(addr)
 45 
 46 // LCD spec
 47 #define _delay_ms(n)   mdelay(n)  
 48 #define ST7565_X_SIZE  128
 49 #define ST7565_Y_SIZE  64
 50 #define u8  unsigned char
 51 #define u16 unsigned int
 52 
 53 #define LCD_SCK_H  gpio_set_value(46, 1);
 54 #define LCD_SCK_L  gpio_set_value(46, 0);
 55 #define LCD_SDA_H  gpio_set_value(47, 1);
 56 #define LCD_SDA_L  gpio_set_value(47, 0);
 57 #define LCD_CS_H
 58 #define LCD_CS_L
 59 #define LCD_RST_H  gpio_set_value(59, 1);
 60 #define LCD_RST_L  gpio_set_value(59, 0);
 61 #define LCD_RS_H   gpio_set_value(60, 1);
 62 #define LCD_RS_L   gpio_set_value(60, 0);
 63 
 64 static        dev_t  lcd_dev;
 65 static struct cdev   lcd_cdev;
 66 static struct class  *lcd_class = NULL;
 67 static int gpio[4];
 68 
 69 static int     lcd12864_open(struct inode *inode, struct file *file);
 70 static int     lcd12864_close(struct inode *inode, struct file *file);
 71 static ssize_t lcd12864_write(struct file *file, const char *buf, size_t count, loff_t *offset);
 72 
 73 // ST7565 gpio config
 74 static void store_gpio_pin(void)
 75 {
 76     // store gpio pinmux
 77     gpio[0] = RD_MEM_32(conf_gpio46);
 78     gpio[1] = RD_MEM_32(conf_gpio47);
 79     gpio[2] = RD_MEM_32(conf_gpio59);
 80     gpio[3] = RD_MEM_32(conf_gpio60);
 81 }
 82 
 83 static void recover_gpio_pin(void)
 84 {
 85     // recover gpio pinmux
 86     WR_MEM_32(conf_gpio46, gpio[0]);
 87     WR_MEM_32(conf_gpio47, gpio[1]);
 88     WR_MEM_32(conf_gpio59, gpio[2]);
 89     WR_MEM_32(conf_gpio60, gpio[3]);
 90     gpio_free(gpio[0]);
 91     gpio_free(gpio[1]);
 92     gpio_free(gpio[2]);
 93     gpio_free(gpio[3]);
 94 } 
 95 
 96 static void config_gpio_pin(void)
 97 {
 98     // config gpio direction
 99     WR_MEM_32(conf_gpio46, 2); 
100     gpio_request(46, "gpio46_en");       // request gpio46
101     gpio_direction_output(46, 0);
102 
103     WR_MEM_32(conf_gpio47, 2); 
104     gpio_request(47, "gpio47_en");       // request gpio47
105     gpio_direction_output(47, 0);
106 
107     WR_MEM_32(conf_gpio59, 1); 
108     gpio_request(59, "gpio59_en");       // request gpio59
109     gpio_direction_output(59, 0);   
110 
111     WR_MEM_32(conf_gpio60, 1); 
112     gpio_request(60, "gpio60_en");       // request gpio60
113     gpio_direction_output(60, 0);   
114 }
115 
116 // ST7565 basic driver
117 void ST7565_WrByte(u8 chr, u8 dir)
118 {
119     u8 i=0;
120     if(dir == 0){ LCD_RS_L;}
121     else { LCD_RS_H;}
122     for(i = 0; i < 8; i++){
123         LCD_SCK_L;
124         if(chr & 0x80){ LCD_SDA_H;}    
125         else { LCD_SDA_L;}
126         chr = (chr << 1);
127         LCD_SCK_H;
128     }
129 }
130 
131 void ST7565_PgSet(u8 clm, u8 pag)
132 {
133     u8 lsb = 0;
134     u8 msb = 0;
135     lsb = clm & 0x0F;        // 
136     msb = clm & 0xF0;       // 
137     msb = msb >> 4;            // 
138     msb = msb | 0x10;        // 
139     pag = pag | 0xB0;        //
140     ST7565_WrByte(pag, 0);    // 
141     ST7565_WrByte(msb, 0);    // 
142     ST7565_WrByte(lsb, 0);     // 0 - 127
143 }
144 
145 void ST7565_Clear(void)
146 {
147     u8 i = 0;
148     u8 j = 0;
149 //    LCD_CS_L;
150     for(i=0; i < ST7565_Y_SIZE/8; i++){
151         ST7565_PgSet(0, i);
152         for(j=0; j < ST7565_X_SIZE; j++){
153             ST7565_WrByte(0x00, 1);    
154         }        
155     }    
156 //    LCD_CS_H;
157 }
158 
159 void ST7565_Init(void)
160 {
161 //    LCD_CS_L;
162     LCD_RST_L;
163     _delay_ms(1);
164     LCD_RST_H;
165 
166     ST7565_WrByte(0xE2, 0);         // software rst
167     _delay_ms(1);
168     ST7565_WrByte(0x2C, 0);      // burst stage1
169     _delay_ms(1);    
170     ST7565_WrByte(0x2E, 0);      // burst stage2
171     _delay_ms(1);
172     ST7565_WrByte(0x2F, 0);      // burst stage3
173     _delay_ms(1);
174     ST7565_WrByte(0x25, 0);      // 
175     ST7565_WrByte(0x81, 0);      // 
176     ST7565_WrByte(0x16, 0);      // 
177     ST7565_WrByte(0xA2, 0);      //
178     ST7565_WrByte(0xC8, 0);      //
179     ST7565_WrByte(0xA0, 0);      //
180     ST7565_WrByte(0x40, 0);      //
181     ST7565_WrByte(0xAF, 0);      // open display
182 
183 //    LCD_CS_H;
184     ST7565_Clear();
185 }
186 
187 void ST7565_DispChr(u8 xpos, u8 ypos, char chr)
188 {
189     u8 i=0;
190     ST7565_PgSet(xpos, ypos);
191     for(i=0; i<6; i++){          
192         // six bytes
193         ST7565_WrByte(ascii_0806[0][(chr-' ')*6 + i], 1);
194     }
195 }
196 
197 // lcd file operations
198 static int lcd12864_open(struct inode *inode, struct file *file)
199 {
200     store_gpio_pin();
201     config_gpio_pin();
202 
203     ST7565_Init();
204     return 0;
205 }
206 
207 static int lcd12864_close(struct inode *inode, struct file *file)
208 {
209     recover_gpio_pin();
210     return 0;
211 }
212 
213 static ssize_t lcd12864_write(struct file *file, const char *buf, size_t count, loff_t *offset)
214 {
215     unsigned char cnt=0;
216     unsigned char raw;     // y
217     unsigned char col;     // x
218 
219     char *data = NULL;    
220 
221     if(count == 0)
222         ST7565_Clear();
223     else{
224         data = (char *)kzalloc(count, GFP_KERNEL);  // kmalloc to kzalloc
225         memcpy(data, buf, count);
226         raw = *data;
227         col = *(data+1);
228         while(cnt < (count-2)){
229             // offset
230             ST7565_DispChr(col+6*cnt, raw, *(data+cnt+2)); 
231             cnt++;  // char++ 
232         }
233         kfree(data);        
234         data = NULL;      
235     }
236 
237     return count;
238 }
239 
240 static struct file_operations lcd12864_fops = 
241 {
242     .owner = THIS_MODULE,
243     .open  = lcd12864_open,
244     .release = lcd12864_close,
245     .write = lcd12864_write,
246 };
247 
248 static int __init LCD12864_init(void)
249 {
250     int result;
251 
252     result = alloc_chrdev_region(&lcd_dev, 0, 1, DRIVERNAME);
253     if(result < 0){
254         printk("Error registering led_gpio character device
");
255         return -ENODEV;
256     }
257     printk("st7565_driver major#: %d, minor#: %d
", MAJOR(lcd_dev), MINOR(lcd_dev));
258 
259     cdev_init(&lcd_cdev, &lcd12864_fops);
260     lcd_cdev.owner = THIS_MODULE;
261     lcd_cdev.ops = &lcd12864_fops; 
262 
263     result = cdev_add(&lcd_cdev, lcd_dev, 1);
264     if(result){
265         unregister_chrdev_region(lcd_dev, 1);
266         printk("Error adding led_gpio.. error no:%d
", result);
267         return -EINVAL;
268     }
269     lcd_class = class_create(THIS_MODULE, DRIVERNAME);
270     device_create(lcd_class, NULL, lcd_dev, NULL, DRIVERNAME);
271 
272     printk(DRIVERNAME " initialized!
");
273 
274     return 0;
275 }
276 
277 static void __exit LCD12864_exit(void)
278 {
279     printk(KERN_EMERG "lcd12864 driver exit!
");
280     cdev_del(&lcd_cdev);
281     unregister_chrdev_region(lcd_dev, 1);
282     device_destroy(lcd_class, lcd_dev);
283     class_destroy(lcd_class);
284 }
285 
286 module_init(LCD12864_init);
287 module_exit(LCD12864_exit);
288 MODULE_LICENSE("GPL");

API函数:

 1 #ifndef API_LCD12864_H
 2 #define API_LCD12864_H
 3 #include <stdio.h>
 4 
 5 #ifdef __cplusplus
 6 extern "C" {
 7 #endif
 8 
 9 #define u8  unsigned char
10 #define u16 unsigned int
11 
12 int api_lcd12864_open(void);
13 int api_lcd12864_close(int fd_lcd);
14 int api_lcd12864_dispstr(int fd_lcd, u8 row, u8 col, char *str);
15 
16 #ifdef __cplusplus
17 }
18 #endif
19 
20 #endif
[DM8168]Linux下控制GPIO控制12864液晶屏(ST7565控制器)第1张[DM8168]Linux下控制GPIO控制12864液晶屏(ST7565控制器)第2张
 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #include <fcntl.h>
 5 #include <unistd.h>
 6 #include <sys/types.h>
 7 #include <sys/stat.h>
 8 #include "api_lcd12864.h"
 9 
10 // #define u8  unsigned char
11 // #define u16 unsigned int
12 
13 #define DEVICENAME "/dev/lcd12864"
14 
15 int api_lcd12864_open(void)
16 {
17     int fd_lcd;
18     if((fd_lcd = open(DEVICENAME, O_RDWR)) <= -1){
19         printf("open device error
");
20         return -1;
21     }
22     return fd_lcd;
23 }
24 
25 int api_lcd12864_close(int fd_lcd)
26 {
27     if(0 == close(fd_lcd))
28         return 0;
29     else
30         return -1;
31 }
32 
33 int api_lcd12864_dispstr(int fd_lcd, u8 row, u8 col, char *str)
34 {
35     unsigned int cnt;
36     char ret;
37     char *data = NULL;
38 
39     cnt = 2+(strlen(str));
40     data = (char *)malloc(cnt);
41 
42     *data = row;
43     *(data+1) = col;     
44  
45     memcpy(data+2, str, cnt-2);
46 
47     if(write(fd_lcd, data, cnt) < 0){
48         printf("write error
");        
49         ret = -1;
50     }
51     else{
52         ret = 0;
53     }
54     
55     free(data);
56     data = NULL;
57     
58     return ret;
59 }
60 
61 
62 /*--
63 void ST7565_DispStr(u8 xpos, u8 ypos, u8 *str)
64 {
65     u8 i=0;  // the num of bytes
66     LCD_CS_L;
67     while(*(str+i) != '

免责声明:内容来源于网络,仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇[RN] React Native 实现 类似京东 的 沉浸式状态栏和搜索栏opencv3学习:reshape函数下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

vue+element-ui el-table表格(含表头)内容溢出省略,鼠标悬浮提示

第一种:参考:https://my.oschina.net/u/3455362/blog/4674804 <template> <div class="test"> <el-table :data="gridData" border stripe style=" 100%"> &...

Video.js

Video.js 官网: https://videojs.com/ 开源HTML5播放器框架 优点 支持多种格式,可以支持MP4、WebM、HLS、RTSP等。 可以自定义主题样式。 插件丰富。 支持广泛,可支持PC端各种浏览器和移动端的浏览器。 插件列表 https://videojs.com/plugins 使用 原生代码,未使用主题样式 <he...

c语言数据类型长度

 头文件<limits.h>和<float.h>中说明了基础数据的长度。float,double和long double的范围就是在IEEE 754标准中提及的典型数据。 关键字 位长(字节) 范围 格式化字符串 char 1 -128..127(或0..255,与体系结构相关) %c unsigned char 1 0...

JBoss配置连接池

         什么是数据库连接池?          配置连接池为的是解决效率问题.由于每创建一个连接都是非常耗时的,有了连接池,就能够提前放一些连接进去.以后我们再用连接就去连接池里面取而不是每次都创建.可是我们知道连接池是有上限的,假设仅仅同意我们放10个,那么当这10个连接都被占用的时候,下一个用户再来请求连接将不能得到,仅仅好等待,假设等的时...

java中远程http文件上传及file2multipartfile

    工作中有时会遇到各种需求,你得变着法儿去解决,当然重要的是在什么场景中去完成。 比如Strut2中file类型如何转换成multipartfile类型,找了几天,发现一个变通的方法记录如下(虽然最后没有用上。。): 1 private static MultipartFile getMulFileByPath(String picPath) {...

Python--循环

__author__ = 'maioge'i = 1# while i <= 5 :# print('miaoge')# i += 1# while i <= 5 :# if i<=3 :# print('miaoge')# i+=1# continue# break# while i...