|
目前在学习linux 下开发lcd液晶驱动,lcd 是192*32的,st19232控制器,带中文字符,硬件平台是:arm9200的
现在出现了问题,搞不懂错在哪,望路过的各位高手帮忙看看,帮帮我啊,先谢谢各位了!!
程序驱动部分如下:
#define __NO_VERSION__
#include <linux/module.h>
#include <linux/version.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/config.h>
#include <linux/mm.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/system.h>
#include <asm/hardware.h>
#include <asm/uaccess.h>
#define DEBUG_HG19232
//#undef DEBUG_HG19232
#ifdef DEBUG_HG19232
#define DBG_HG19232(fmt, args...) printk(fmt,## args)
#else
#define DBG_HG19232(fmt, args...)
#endif
/* PB9 --> RS, PB10 --> RW, PB11 --> E */
#define JHD_RS AT91C_PIO_PB9 //指令数据选择--H:数据,L:指令
#define JHD_RW AT91C_PIO_PB10 //读写选择--H:读,L:写
#define JHD_E AT91C_PIO_PB11 //使能信号
#define JHD_DIR AT91C_PIO_PB0 //方向选择,H--输出,L写入
/* DB0-DB7 --> PB0-PB7 */ //8个引脚
#define DB0 AT91C_PIO_PB1
#define DB1 AT91C_PIO_PB2
#define DB2 AT91C_PIO_PB3
#define DB3 AT91C_PIO_PB4
#define DB4 AT91C_PIO_PB5
#define DB5 AT91C_PIO_PB6
#define DB6 AT91C_PIO_PB7
#define DB7 AT91C_PIO_PB8
#define DISP_READY_() while (disp_test_busy())
#define DISP_CLR 0x1
#define DISP_RET_HOME 0x2
#define LCD_AC_INC_SHIFT_OFF 0x6 //input set
#define DIS_OFF_CUR_OFF_BLIN_OFF 0x8
#define DIS_ON_CUR_OFF_BLIN_OFF 0x0c
#define DIS_ON_CUR_ON_BLIN_OFF 0x0e
//--------------------------
#define FUNC_CONFIG (0X1<<5)
#define BUS_8BIT (0x1<<4)
#define GMOD_ON (0X1<<1)
#define RE_ENABLE (0X1<<2)
//---------------------------------
#define BIT8_BASIC_DOTS 0x30
#define NOSHIFT_ACINC_RIGHT 0x7
#define CMD 0
#define DATA 1
#define HG19232_MAJOR 254
static void hg19232_hardware_init (void);
static int hg19232_open(struct inode *, struct file *);
static int hg19232_close(struct inode *, struct file *);
static int hg19232_read(struct file *, char *, size_t, loff_t *);
static int hg19232_write(struct file *, const char *, size_t, loff_t *);
static void __init hg19232_init (void);
static void __exit hg19232_cleanup (void);
static int disp_test_busy(void);
static int write_bus(unsigned int bus);
static int disp_data (unsigned int data);
static int disp_cmd (unsigned int cmd);
static struct file_operations hg19232_fops = {
open: hg19232_open,
read: hg19232_read,
write: hg19232_write,
release: hg19232_close,
};
static unsigned int data;
static int jhd_initialized = 0;
static void hg19232_hardware_init (void)
{
// I/O init
//pin0--pin11使能
AT91_SYS->PIOB_PER |= JHD_RS | JHD_RW | JHD_DIR | JHD_E | DB0 | DB1 | DB2 | DB3 | DB4 | DB5 |DB6 | DB7;
AT91_SYS->PIOB_OER |= JHD_RS | JHD_RW | JHD_DIR | JHD_E | DB0 | DB1 | DB2 | DB3 | DB4 | DB5 |DB6 | DB7;
AT91_SYS->PIOB_SODR |= JHD_RS | JHD_RW | JHD_DIR | JHD_E | DB0 | DB1 | DB2 | DB3 | DB4 | DB5 |DB6 | DB7;
//**************************************************************************************
// Lcd init
//功能设置,8位数据接口,
mdelay(45);
//Function set
disp_cmd(FUNC_CONFIG|BUS_8BIT);
mdelay(1);
disp_cmd(FUNC_CONFIG|BUS_8BIT);
mdelay(1);
// disp_cmd(FUNC_CONFIG|BUS_8BIT|GMOD_ON);
//Display ON/OFF control ,BCD
disp_cmd(DIS_ON_CUR_OFF_BLIN_OFF);
mdelay(1);
// Display clear
disp_cmd(DISP_CLR);
mdelay(15);
// disp_cmd(0x80);
// mdelay(1);
//Entry mode set
disp_cmd(LCD_AC_INC_SHIFT_OFF);
//************************************************************************************
}
static void disp_refresh()
{
}
static int disp_test_busy(void)
{
unsigned char flag;
//PIO禁止
AT91_SYS->PIOB_PDR |= DB0 | DB1 | DB2 | DB3 | DB4 | DB5 |DB6 | DB7; //set Input
//EA = 0;
//write_bus(0xff);// lockinputdata.
AT91_SYS->PIOB_CODR |= JHD_RS; // select command register. RS=0,为指令
AT91_SYS->PIOB_SODR |= JHD_RW | JHD_DIR; // read mode on.RW=1,读,输出
AT91_SYS->PIOB_SODR |= JHD_E; // read Data... ,高电平
flag = AT91_SYS->PIOB_PSR;//状态寄存器
AT91_SYS->PIOB_CODR |= JHD_E;
//EA = 1;
AT91_SYS->PIOB_PER |= DB0 | DB1 | DB2 | DB3 | DB4 | DB5 |DB6 | DB7;//reset Output
return (flag & DB7)? 1 : 0;
}
// write $bus to DB0-DB7
static int write_bus(unsigned int bus)
{
if ((bus >> 0 & 0x1 ) == 0)
AT91_SYS->PIOB_CODR |= DB0;//置1清除,为0
else
AT91_SYS->PIOB_SODR |= DB0;//置1写入1
if ((bus >> 1 & 0x1 ) == 0)
AT91_SYS->PIOB_CODR |= DB1;
else
AT91_SYS->PIOB_SODR |= DB1;
if ((bus >> 2 & 0x1 ) == 0)
AT91_SYS->PIOB_CODR |= DB2;
else
AT91_SYS->PIOB_SODR |= DB2;
if ((bus >> 3 & 0x1 ) == 0)
AT91_SYS->PIOB_CODR |= DB3;
else
AT91_SYS->PIOB_SODR |= DB3;
if ((bus >> 4 & 0x1 ) == 0)
AT91_SYS->PIOB_CODR |= DB4;
else
AT91_SYS->PIOB_SODR |= DB4;
if ((bus >> 5 & 0x1 ) == 0)
AT91_SYS->PIOB_CODR |= DB5;
else
AT91_SYS->PIOB_SODR |= DB5;
if ((bus >> 6 & 0x1 ) == 0)
AT91_SYS->PIOB_CODR |= DB6;
else
AT91_SYS->PIOB_SODR |= DB6;
if ((bus << 7 & 0x1 ) == 0)
AT91_SYS->PIOB_CODR |= DB7;
else
AT91_SYS->PIOB_SODR |= DB7;
return bus;
}
//数据操作,且为写;即RS=1,RW=0
static int disp_data (unsigned int data)
{
DISP_READY_();//忙等待
//------------------------------------设置命令的执行环境
//设置RS=1,RW=0,写数据,方向写入
AT91_SYS->PIOB_CODR |= JHD_DIR;
AT91_SYS->PIOB_SODR |= JHD_RS ;
AT91_SYS->PIOB_CODR |= JHD_RW ;
write_bus(data); // 将cmd 写入到引脚
AT91_SYS->PIOB_SODR |= JHD_E;
mdelay(1);
AT91_SYS->PIOB_CODR |= JHD_E;
// mdelay(1);
return 0;
}
//执行指令,且为写,即RS=0,RW=0
static int disp_cmd (unsigned int cmd)
{
DISP_READY_();//忙等待
// write_bus(cmd); // 将cmd 写入到引脚
//------------------------------------设置命令的执行环境
//设置RS=0,RW=0,写指令,方向写入
AT91_SYS->PIOB_CODR |= JHD_DIR;
AT91_SYS->PIOB_CODR |= JHD_RW | JHD_RS;
write_bus(cmd); // 将cmd 写入到引脚
AT91_SYS->PIOB_SODR |= JHD_E;
mdelay(1);
AT91_SYS->PIOB_CODR |= JHD_E;
mdelay(1);
return 0;
}
static int hg19232_open (struct inode *inode, struct file *file)
{
MOD_INC_USE_COUNT;
return 0;
}
static int hg19232_close (struct inode *inode, struct file *file)
{
MOD_DEC_USE_COUNT;
return 0;
}
static int hg19232_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
return 0;
}
// 2个字节数据/指令
static int hg19232_write (struct file *file, const char *buf, size_t count, loff_t *ppos)
{
unsigned char choice,disp;
get_user(choice,buf++);//从buf处取一个字节到disp
//DBG_HG19232("choice:%d\n",choice);
switch (choice){
case CMD://指令
//DBG_HG19232("cmd\n");
get_user(disp,buf);//从buf处取一个字节到disp
disp_cmd(disp);//操作指令
break;
case DATA://数据
//DBG_HG19232("data\n");
get_user(disp,buf);//从buf处取一个字节到disp
disp_data(disp);//操作数据
break;
default:
//DBG_HG19232("default\n");
}
return 0;
}
static void __init hg19232_init (void)
{
int i;
if (jhd_initialized == 1)
return 0;
hg19232_hardware_init(); //液晶初始化
i = register_chrdev(HG19232_MAJOR, "hg19232", &hg19232_fops);
if(i<0){//失败
printk(KERN_CRIT"hg19232:i = %d\n",i);
return -EIO;
}
printk(KERN_CRIT"hg19232:hg19232_drv registered:)=\n");
jhd_initialized = 1;
return 0;
}
static void __exit hg19232_cleanup (void)
{
unregister_chrdev(HG19232_MAJOR, "hg19232");
return;
}
module_init(hg19232_init);
module_exit(hg19232_cleanup);
测试程序如下:
#include <stdio.h>
#include <fcntl.h>
#define LCD_CLEAR 1 // clear screen
#define LCD_HOME 2 // cursor home
#define BIT8_BASIC_DOTS 0x30
#define LCD_AC_INC_SHIFT_OFF 0x06 // input set
//--------------------------
#define FUNC_CONFIG (0X1<<5)
#define BUS_8BIT (0x1<<4)
#define GMOD_ON (0X1<<1)
#define RE_ENABLE (0X1<<2)
//---------------------------------
int lcdfd = -1;
int lcd_open()
{
lcdfd = open("/dev/hg19232", O_RDWR);
if (lcdfd == -1)
{
printf("open /dev/hg19232 failed\n");
return EOF;
}
//printf("open hg19232 ok\n");
//init set
// lcd_set(BIT8_BASIC_DOTS);
lcd_set(LCD_CLEAR);
lcd_set(FUNC_CONFIG|BUS_8BIT);//function set
lcd_set(LCD_HOME); //cursor go home
lcd_set(0x04);
lcd_set(LCD_AC_INC_SHIFT_OFF); //input set
lcd_set(LCD_CLEAR);
lcd_set(0x80);
return lcdfd;
}
int lcd_close()
{
if (lcdfd == -1)
return EOF;
close(lcdfd);
return 0;
}
//-----------------------------------------------
//执行数据
void lcd_put(char dat)
{
char buf[2];
buf[0] = 1; //data flag
buf[1] = dat;
write(lcdfd, buf, 2);
}
//执行指令
void lcd_set(char cmd)
{
char buf[2];
buf[0] = 0; //commad flag
buf[1] = cmd;
write(lcdfd, buf, 2);
}
int main()
{
lcd_open();
lcd_put('a');
lcd_close();
}
在测试时,在液晶上显示不了字符‘a';
不知问题出在哪里,向大家求助!! |
阿莫论坛20周年了!感谢大家的支持与爱护!!
一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
|