首页 > 代码库 > Linux下控制GPIO控制12864液晶屏(ST7565控制器,DM8168)

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

首先加载驱动模块,应用程序通过调用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 gpio46101     gpio_direction_output(46, 0);102 103     WR_MEM_32(conf_gpio47, 2); 104     gpio_request(47, "gpio47_en");       // request gpio47105     gpio_direction_output(47, 0);106 107     WR_MEM_32(conf_gpio59, 1); 108     gpio_request(59, "gpio59_en");       // request gpio59109     gpio_direction_output(59, 0);   110 111     WR_MEM_32(conf_gpio60, 1); 112     gpio_request(60, "gpio60_en");       // request gpio60113     gpio_direction_output(60, 0);   114 }115 116 // ST7565 basic driver117 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 - 127143 }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 rst167     _delay_ms(1);168     ST7565_WrByte(0x2C, 0);      // burst stage1169     _delay_ms(1);    170     ST7565_WrByte(0x2E, 0);      // burst stage2171     _delay_ms(1);172     ST7565_WrByte(0x2F, 0);      // burst stage3173     _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 display182 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 bytes193         ST7565_WrByte(ascii_0806[0][(chr- )*6 + i], 1);194     }195 }196 197 // lcd file operations198 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;     // y217     unsigned char col;     // x218 219     char *data =http://www.mamicode.com/ NULL;    220 221     if(count == 0)222         ST7565_Clear();223     else{224         data = http://www.mamicode.com/(char *)kzalloc(count, GFP_KERNEL);  // kmalloc to kzalloc225         memcpy(data, buf, count);226         raw = *data;227         col = *(data+1);228         while(cnt < (count-2)){229             // offset230             ST7565_DispChr(col+6*cnt, raw, *(data+cnt+2)); 231             cnt++;  // char++ 232         }233         kfree(data);        234         data =http://www.mamicode.com/ 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\n");255         return -ENODEV;256     }257     printk("st7565_driver major#: %d, minor#: %d\n", 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\n", 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!\n");273 274     return 0;275 }276 277 static void __exit LCD12864_exit(void)278 {279     printk(KERN_EMERG "lcd12864 driver exit!\n");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 char10 #define u16 unsigned int11 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 __cplusplus17 }18 #endif19 20 #endif
 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 char11 // #define u16 unsigned int12 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\n");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     else30         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 =http://www.mamicode.com/ NULL;38 39     cnt = 2+(strlen(str));40     data = http://www.mamicode.com/(char *)malloc(cnt);41 42     *data =http://www.mamicode.com/ 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\n");        49         ret = -1;50     }51     else{52         ret = 0;53     }54     55     free(data);56     data =http://www.mamicode.com/ 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 bytes66     LCD_CS_L;67     while(*(str+i) != ‘\0‘){68         // offset69         ST7565_DispChr(xpos+6*i, ypos, *(str+i)); 70         i++;  // char++ 71     }72     LCD_CS_H;73 }74 --*/75 /*--76 void ST7565_DispNum(u8 xpos,u8 ypos, u32 num, u8 len)77 {78     LCD_CS_L;79     while(len > 0){80         // ascii81         ST7565_DispChr(xpos+6*(--len), ypos, num%10 + ‘0‘); 82         num = num / 10;83     }84     LCD_CS_H;85 }86 --*/
View Code

应用程序:

 1 /*- test for Lcd12864 -*/ 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> 5 #include <unistd.h> 6 #include <time.h> 7 #include "api_lcd12864.h" 8 int main(void) 9 {10     int fd_lcd;11 //    unsigned int num=0;12     char date_str[30];13     char num_str1[20];14     char num_str2[20];15     time_t rawtime;16     struct tm *timeinfo; 17 18 //    int delay = 10;19     20     fd_lcd = api_lcd12864_open();21 //    my_tt = time(&NULL);22     23     if(fd_lcd < 0){24         printf("fd_lcd open failed!\n");25         return -1;26     }27     28     api_lcd12864_dispstr(fd_lcd, 0, 0, "hello, linux");29 30     printf("Hello, LCD displaying!\n");31 32 //    api_lcd12864_close(fd_lcd);33 34     while(1){35 //        sprintf(num_str, "%d", num);      36         time(&rawtime);37         timeinfo = localtime(&rawtime);38         strcpy(date_str, asctime(timeinfo));39         40 //        printf("Time is: %s\n", date_str);41 42         memcpy(num_str1, date_str+0, 11);43         num_str1[11] = \0;44         api_lcd12864_dispstr(fd_lcd, 1, 0, num_str1);  // Web Feb 1345 46         memcpy(num_str2, date_str+11, 13);47         num_str2[13] = \0;48         api_lcd12864_dispstr(fd_lcd, 2, 0, num_str2);  // 09:49:30 201449 50 //        if(num == 65535) num=0;51 //        num ++;52         usleep(200000);53     }54 55     api_lcd12864_close(fd_lcd);56     57     return 0;58 }

 

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