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

驱动函数:

 /*
* fileName: st7565_driver.c
* just for LCD12864 driver
* GP1_14(46) -> D6(SCK)
* GP1_15(47) -> D7(SDA)
* GP1_27(59) -> RST
* GP1_28(60) -> RS
*/ #include <linux/device.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/moduleparam.h>
#include <linux/list.h>
#include <linux/cdev.h>
#include <linux/proc_fs.h>
#include <linux/mm.h>
#include <linux/seq_file.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <asm/io.h>
#include <linux/io.h>
#include <mach/gpio.h>
#include <linux/device.h>
#include <linux/platform_device.h> #include <linux/delay.h> // ASCII code
#include "font.h" #define DRIVERNAME "lcd12864" // PANEL CON
#define CTRL_MODULE_BASE_ADDR 0x48140000
#define conf_gpio46 (CTRL_MODULE_BASE_ADDR + 0x0B04)
#define conf_gpio47 (CTRL_MODULE_BASE_ADDR + 0x0B08)
#define conf_gpio59 (CTRL_MODULE_BASE_ADDR + 0x0AB8)
#define conf_gpio60 (CTRL_MODULE_BASE_ADDR + 0x0ABC) #define WR_MEM_32(addr, data) *(unsigned int*)OMAP2_L4_IO_ADDRESS(addr) = (unsigned int)(data)
#define RD_MEM_32(addr) *(unsigned int*)OMAP2_L4_IO_ADDRESS(addr) // LCD spec
#define _delay_ms(n) mdelay(n)
#define ST7565_X_SIZE 128
#define ST7565_Y_SIZE 64
#define u8 unsigned char
#define u16 unsigned int #define LCD_SCK_H gpio_set_value(46, 1);
#define LCD_SCK_L gpio_set_value(46, 0);
#define LCD_SDA_H gpio_set_value(47, 1);
#define LCD_SDA_L gpio_set_value(47, 0);
#define LCD_CS_H
#define LCD_CS_L
#define LCD_RST_H gpio_set_value(59, 1);
#define LCD_RST_L gpio_set_value(59, 0);
#define LCD_RS_H gpio_set_value(60, 1);
#define LCD_RS_L gpio_set_value(60, 0); static dev_t lcd_dev;
static struct cdev lcd_cdev;
static struct class *lcd_class = NULL;
static int gpio[]; static int lcd12864_open(struct inode *inode, struct file *file);
static int lcd12864_close(struct inode *inode, struct file *file);
static ssize_t lcd12864_write(struct file *file, const char *buf, size_t count, loff_t *offset); // ST7565 gpio config
static void store_gpio_pin(void)
{
// store gpio pinmux
gpio[] = RD_MEM_32(conf_gpio46);
gpio[] = RD_MEM_32(conf_gpio47);
gpio[] = RD_MEM_32(conf_gpio59);
gpio[] = RD_MEM_32(conf_gpio60);
} static void recover_gpio_pin(void)
{
// recover gpio pinmux
WR_MEM_32(conf_gpio46, gpio[]);
WR_MEM_32(conf_gpio47, gpio[]);
WR_MEM_32(conf_gpio59, gpio[]);
WR_MEM_32(conf_gpio60, gpio[]);
gpio_free(gpio[]);
gpio_free(gpio[]);
gpio_free(gpio[]);
gpio_free(gpio[]);
} static void config_gpio_pin(void)
{
// config gpio direction
WR_MEM_32(conf_gpio46, );
gpio_request(, "gpio46_en"); // request gpio46
gpio_direction_output(, ); WR_MEM_32(conf_gpio47, );
gpio_request(, "gpio47_en"); // request gpio47
gpio_direction_output(, ); WR_MEM_32(conf_gpio59, );
gpio_request(, "gpio59_en"); // request gpio59
gpio_direction_output(, ); WR_MEM_32(conf_gpio60, );
gpio_request(, "gpio60_en"); // request gpio60
gpio_direction_output(, );
} // ST7565 basic driver
void ST7565_WrByte(u8 chr, u8 dir)
{
u8 i=;
if(dir == ){ LCD_RS_L;}
else { LCD_RS_H;}
for(i = ; i < ; i++){
LCD_SCK_L;
if(chr & 0x80){ LCD_SDA_H;}
else { LCD_SDA_L;}
chr = (chr << );
LCD_SCK_H;
}
} void ST7565_PgSet(u8 clm, u8 pag)
{
u8 lsb = ;
u8 msb = ;
lsb = clm & 0x0F; //
msb = clm & 0xF0; //
msb = msb >> ; //
msb = msb | 0x10; //
pag = pag | 0xB0; //
ST7565_WrByte(pag, ); //
ST7565_WrByte(msb, ); //
ST7565_WrByte(lsb, ); // 0 - 127
} void ST7565_Clear(void)
{
u8 i = ;
u8 j = ;
// LCD_CS_L;
for(i=; i < ST7565_Y_SIZE/; i++){
ST7565_PgSet(, i);
for(j=; j < ST7565_X_SIZE; j++){
ST7565_WrByte(0x00, );
}
}
// LCD_CS_H;
} void ST7565_Init(void)
{
// LCD_CS_L;
LCD_RST_L;
_delay_ms();
LCD_RST_H; ST7565_WrByte(0xE2, ); // software rst
_delay_ms();
ST7565_WrByte(0x2C, ); // burst stage1
_delay_ms();
ST7565_WrByte(0x2E, ); // burst stage2
_delay_ms();
ST7565_WrByte(0x2F, ); // burst stage3
_delay_ms();
ST7565_WrByte(0x25, ); //
ST7565_WrByte(0x81, ); //
ST7565_WrByte(0x16, ); //
ST7565_WrByte(0xA2, ); //
ST7565_WrByte(0xC8, ); //
ST7565_WrByte(0xA0, ); //
ST7565_WrByte(0x40, ); //
ST7565_WrByte(0xAF, ); // open display // LCD_CS_H;
ST7565_Clear();
} void ST7565_DispChr(u8 xpos, u8 ypos, char chr)
{
u8 i=;
ST7565_PgSet(xpos, ypos);
for(i=; i<; i++){
// six bytes
ST7565_WrByte(ascii_0806[][(chr-' ')* + i], );
}
} // lcd file operations
static int lcd12864_open(struct inode *inode, struct file *file)
{
store_gpio_pin();
config_gpio_pin(); ST7565_Init();
return ;
} static int lcd12864_close(struct inode *inode, struct file *file)
{
recover_gpio_pin();
return ;
} static ssize_t lcd12864_write(struct file *file, const char *buf, size_t count, loff_t *offset)
{
unsigned char cnt=;
unsigned char raw; // y
unsigned char col; // x char *data = NULL; if(count == )
ST7565_Clear();
else{
data = (char *)kzalloc(count, GFP_KERNEL); // kmalloc to kzalloc
memcpy(data, buf, count);
raw = *data;
col = *(data+);
while(cnt < (count-)){
// offset
ST7565_DispChr(col+*cnt, raw, *(data+cnt+));
cnt++; // char++
}
kfree(data);
data = NULL;
} return count;
} static struct file_operations lcd12864_fops =
{
.owner = THIS_MODULE,
.open = lcd12864_open,
.release = lcd12864_close,
.write = lcd12864_write,
}; static int __init LCD12864_init(void)
{
int result; result = alloc_chrdev_region(&lcd_dev, , , DRIVERNAME);
if(result < ){
printk("Error registering led_gpio character device\n");
return -ENODEV;
}
printk("st7565_driver major#: %d, minor#: %d\n", MAJOR(lcd_dev), MINOR(lcd_dev)); cdev_init(&lcd_cdev, &lcd12864_fops);
lcd_cdev.owner = THIS_MODULE;
lcd_cdev.ops = &lcd12864_fops; result = cdev_add(&lcd_cdev, lcd_dev, );
if(result){
unregister_chrdev_region(lcd_dev, );
printk("Error adding led_gpio.. error no:%d\n", result);
return -EINVAL;
}
lcd_class = class_create(THIS_MODULE, DRIVERNAME);
device_create(lcd_class, NULL, lcd_dev, NULL, DRIVERNAME); printk(DRIVERNAME " initialized!\n"); return ;
} static void __exit LCD12864_exit(void)
{
printk(KERN_EMERG "lcd12864 driver exit!\n");
cdev_del(&lcd_cdev);
unregister_chrdev_region(lcd_dev, );
device_destroy(lcd_class, lcd_dev);
class_destroy(lcd_class);
} module_init(LCD12864_init);
module_exit(LCD12864_exit);
MODULE_LICENSE("GPL");

API函数:

 #ifndef API_LCD12864_H
#define API_LCD12864_H
#include <stdio.h> #ifdef __cplusplus
extern "C" {
#endif #define u8 unsigned char
#define u16 unsigned int int api_lcd12864_open(void);
int api_lcd12864_close(int fd_lcd);
int api_lcd12864_dispstr(int fd_lcd, u8 row, u8 col, char *str); #ifdef __cplusplus
}
#endif #endif
 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "api_lcd12864.h" // #define u8 unsigned char
// #define u16 unsigned int #define DEVICENAME "/dev/lcd12864" int api_lcd12864_open(void)
{
int fd_lcd;
if((fd_lcd = open(DEVICENAME, O_RDWR)) <= -){
printf("open device error\n");
return -;
}
return fd_lcd;
} int api_lcd12864_close(int fd_lcd)
{
if( == close(fd_lcd))
return ;
else
return -;
} int api_lcd12864_dispstr(int fd_lcd, u8 row, u8 col, char *str)
{
unsigned int cnt;
char ret;
char *data = NULL; cnt = +(strlen(str));
data = (char *)malloc(cnt); *data = row;
*(data+) = col; memcpy(data+, str, cnt-); if(write(fd_lcd, data, cnt) < ){
printf("write error\n");
ret = -;
}
else{
ret = ;
} free(data);
data = NULL; return ret;
} /*--
void ST7565_DispStr(u8 xpos, u8 ypos, u8 *str)
{
u8 i=0; // the num of bytes
LCD_CS_L;
while(*(str+i) != '\0'){
// offset
ST7565_DispChr(xpos+6*i, ypos, *(str+i));
i++; // char++
}
LCD_CS_H;
}
--*/
/*--
void ST7565_DispNum(u8 xpos,u8 ypos, u32 num, u8 len)
{
LCD_CS_L;
while(len > 0){
// ascii
ST7565_DispChr(xpos+6*(--len), ypos, num%10 + '0');
num = num / 10;
}
LCD_CS_H;
}
--*/

应用程序:

 /*- test for Lcd12864 -*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include "api_lcd12864.h"
int main(void)
{
int fd_lcd;
// unsigned int num=0;
char date_str[];
char num_str1[];
char num_str2[];
time_t rawtime;
struct tm *timeinfo; // int delay = 10; fd_lcd = api_lcd12864_open();
// my_tt = time(&NULL); if(fd_lcd < ){
printf("fd_lcd open failed!\n");
return -;
} api_lcd12864_dispstr(fd_lcd, , , "hello, linux"); printf("Hello, LCD displaying!\n"); // api_lcd12864_close(fd_lcd); while(){
// sprintf(num_str, "%d", num);
time(&rawtime);
timeinfo = localtime(&rawtime);
strcpy(date_str, asctime(timeinfo)); // printf("Time is: %s\n", date_str); memcpy(num_str1, date_str+, );
num_str1[] = '\0';
api_lcd12864_dispstr(fd_lcd, , , num_str1); // Web Feb 13 memcpy(num_str2, date_str+, );
num_str2[] = '\0';
api_lcd12864_dispstr(fd_lcd, , , num_str2); // 09:49:30 2014 // if(num == 65535) num=0;
// num ++;
usleep();
} api_lcd12864_close(fd_lcd); return ;
}

[DM8168]Linux下控制GPIO控制12864液晶屏(ST7565控制器)的更多相关文章

  1. linux下操作gpio寄存器的方法

    一. 在驱动中: 1. 用的时候映射端口:ioremap; #define GPIO_OFT(x) ((x) - 0x56000000) #define GPFCON (*(volatile unsi ...

  2. Linux 下操作GPIO(两种方法,驱动和mmap)(转载)

    目前我所知道的在Linux下操作GPIO有两种方法: 1.编写驱动,这当然要熟悉Linux下驱动的编写方法和技巧,在驱动里可以使用ioremap函数获得GPIO物理基地址指针,然后使用这个指针根据io ...

  3. Linux 下操作gpio(两种方法,驱动和mmap)

    目前我所知道的在linux下操作GPIO有两种方法: 1.  编写驱动,这当然要熟悉linux下驱动的编写方法和技巧,在驱动里可以使用ioremap函数获得GPIO物理基地址指针,然后使用这个指针根据 ...

  4. linux设备驱动程序--gpio控制

    gpio驱动程序 上一章节linux设备驱动程序--创建设备节点章节主要介绍了linux字符设备驱动程序的框架,从这一章节开始我们讲解各种外设的控制,包括gpio,i2c,dma等等,既然是外设,那就 ...

  5. linux下的权限控制

    终于还是要弄服务器了,这是多年前用fedora的时候整理的,也贴出来,顺便也再复习一下. 先来了解一下文件属性,在shell环境里输入:ls -l 可以查看当前目录文件.如:drwxr-xr-x. 1 ...

  6. [转载]嵌入式linux下操作GPIO

    本文转自:http://blog.csdn.net/mirkerson/article/details/8464231 在嵌入式设备中对GPIO的操作是最基本的操作.一般的做法是写一个单独驱动程序,网 ...

  7. Linux下LCD 10分钟自动关屏的问题总结

    Linux下的LCD驱动默认10分钟后会自动关闭屏幕,我们可以修改一下代码让其不自动关屏 在有一个 drivers/char/vt.c 文件其中有一个变量(blankinterval)可以设置它来修改 ...

  8. linux下常用的截图、录屏工具

    录屏: 在linux下常用的录屏工具有5种,可以baidu或者google下喔,我选用的是recordMydesktop,使用非常方便,用时注意先把每秒桢数调高,否则效果必然很差. 在ubuntu下可 ...

  9. [DM8168]Linux下控制GPIO实现LED流水灯

    首先加载驱动模块,应用程序通过调用API实现GPIO控制功能. 驱动程序: /* * fileName: led_gpio.c * just for LED GPIO test * GP1_14 -& ...

随机推荐

  1. 如何在InstallShield的MSI工程中调用Merge Module的Custom Action

    使用InstallShield创建了合并模块安装程序,定义自定义活动,可如何调用却不太清楚,网上也就找到这点信息,还是没有成功,到底该在什么地方执行合并模块的自定义活动? http://1662487 ...

  2. VMware-Ubuntu16.04LTS-安装ssh

    1,检查是否安装ssh 2,安装ssh

  3. dojo中类的继承

    类似于c# java等后台语言,在基于类的面向对象编程中,通常需要在子类中扩展某些父类的方法,这时可以在子类的方法中,先调用从父类继承的方法,然后再执行子类自定义的操作.凡是使用declare创建的类 ...

  4. javaweb基础(28)_jstl的核心标签

    一.JSTL标签库介绍 JSTL标签库的使用是为弥补html标签的不足,规范自定义标签的使用而诞生的.使用JSLT标签的目的就是不希望在jsp页面中出现java逻辑代码 二.JSTL标签库的分类 核心 ...

  5. eclipse中关闭java文件后再打开,找不到如何切换可视化编辑器

    http://www.iteye.com/problems/64806 两种方式:   第一种正如楼上的老兄说的.在该java类中,鼠标右击,移动到openWith上 找到jigloo,找不到就在ot ...

  6. MySQL派生表(derived)优化一例

    1.什么是派生表derived 关键字:子查询–>在From后where前的子查询 mysql; +----+-------------+------------+------+-------- ...

  7. C的xml编程-libxml2

    这里主要讲述libxml2在linux下的使用. (以下内容除了linux下的安装步骤是自己写的,其余均出自http://www.blogjava.net/wxb_nudt/archive/2007/ ...

  8. 数据结构(C语言)分享笔记:数据结构的逻辑层次、存储层次

    [1] 严格意义上数据结构的概念 数据结构,一个简单的定义:相互之间存在一种或多种特定关系的数据元素的集合.即:数据结构 = 元素集合 + 元素间关系的集合 . 在讨论数据结构时,可以基于两个不同的层 ...

  9. SpingBoot之多Profile文件

    1.我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml默认使用application.properties的配置: 在我们的项目开发.测 ...

  10. String&StringBuffer&StringBuilder区别

    String  String类是final类故不可以继承,也就意味着String引用的字符串内容是不能被修改.String有两种实例化方式:    (1)直接赋值(例中,String str = &q ...