zoukankan      html  css  js  c++  java
  • [DM8168]Linux下控制GPIO控制12864液晶屏(ST7565控制器)

    首先加载驱动模块,应用程序通过调用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
     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) != ''){
    68         // offset
    69         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         // ascii
    81         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!
    ");
    25         return -1;
    26     }
    27     
    28     api_lcd12864_dispstr(fd_lcd, 0, 0, "hello, linux");
    29 
    30     printf("Hello, LCD displaying!
    ");
    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
    ", date_str);
    41 
    42         memcpy(num_str1, date_str+0, 11);
    43         num_str1[11] = '';
    44         api_lcd12864_dispstr(fd_lcd, 1, 0, num_str1);  // Web Feb 13
    45 
    46         memcpy(num_str2, date_str+11, 13);
    47         num_str2[13] = '';
    48         api_lcd12864_dispstr(fd_lcd, 2, 0, num_str2);  // 09:49:30 2014
    49 
    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下Kafka单机安装配置
    MySQL30条规范解读
    MySQL联合索引最左匹配范例
    Percona Data Recovery Tool 单表恢复
    SQL中的where条件,在数据库中提取与应用浅析
    【leetcode】908. Smallest Range I
    【leetcode】909. Snakes and Ladders
    【leetcode】910. Smallest Range II
    【leetcode】395. Longest Substring with At Least K Repeating Characters
    【leetcode】907. Sum of Subarray Minimums
  • 原文地址:https://www.cnblogs.com/imapla/p/4127142.html
Copyright © 2011-2022 走看看