首页 > 代码库 > 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 --*/
应用程序:
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)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。