|  | 
 
| 这是我在linux下编写的一个lcd(16*2)驱动程序,参考了lumit网站上的lcd程序,其中的初始化程序,已经可以清屏.但是向lcd中写数据时,发现仍然显示清屏,并不显示我所要写的数据,看了好几天了,没进展,呵呵,版主帮忙看看吧,谢谢!  ,在这个程序里面,我在初始化函数里面包含了lcd的初始化及向其里面写数据,没有单独编写向lcd写数据的函数,可以只看这个init_chardev函数,其他的程序可以不看. 
 /*#if defined(CONFIG_MODVERSIONS) && ! defined(MODVERSIONS)
 
 *#include <linux/modversions.h>
 
 *#define MODVERSIONS
 
 *#endif
 */
 #ifdef MODULE
 #include <linux/module.h>
 #include <linux/version.h>
 char kernel_version[]=UTS_RELEASE;
 #else
 #define MOD_INC_USE_COUNT
 #define MOD_DEC_USE_COUNT
 #endif
 
 #include <linux/kernel.h>
 #include <linux/fs.h>
 
 #include <asm/uaccess.h> /* for put_user */
 
 #define IOPMOD (*(volatile unsigned *)0x3ff5000)
 #define IOPDATA (*(volatile unsigned *)0x3ff500
  
 
 #define LCD_MAX_LINES              2
 
 #define LCD_MIN_LINES               1
 
 #define LCD_MAX_COLUMNS         16
 
 #define LCD_MIN_COLUMNS          1
 
 #define ERROR   0xff
 #define OK       0
 
 #define UINT8 unsigned short
 
 /* Prototypes - this would normally go in a .h file
 
 */
 
 void init_chardev(void);
 
 void cleanup_module(void);
 
 static int device_open(struct inode *, struct file *);
 
 static int device_release(struct inode *, struct file *);
 
 static ssize_t device_read(struct file *, char *, size_t, loff_t *);
 
 static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
 #define SUCCESS 0
 
 #define DEVICE_NAME "chardev" /* Dev name as it appears in /proc/devices */
 
 #define BUF_LEN 80            /* Max length of the message from the device */
 
 /* Global variables are declared as static, so are global within the file. */
 
 static int Major; /* Major number assigned to our device driver */
 
 static int Device_Open = 0; /* Is device open? Used to prevent multiple */
 
 /*access to the device */
 
 static char msg[BUF_LEN]; /* The msg the device will give when asked */
 
 static char *msg_Ptr;
 
 static struct file_operations fops = {
 
 .read = device_read,
 
 .write = device_write,
 
 .open = device_open,
 
 .release = device_release
 
 };
 
 /*            Functions
 
 */
 
 void init_chardev(void)
 
 {
 int data,led,i;
 char *ch= "--- C U M T ---";
 char val;
 Major =register_chrdev(254, DEVICE_NAME, &fops);
 
 if (Major < 0) {
 
 printk ("Registering the character device failed with %d\n", Major);
 
 /*return Major;*/
 
 }
 
 
 printk("I was assigned major number 254. To talk to\n");
 
 printk("<1>the driver, create a dev file with\n");
 
 printk("'mknod /dev/hello c 254 0'.\n");
 
 printk("<1>Try various minor numbers. Try to cat to\n");
 
 printk("the device file.\n");
 
 printk("<1>Remove the device file and module when done.\n");
 
 /*    *(volatile unsigned *)0x3FF303c &= 0xffff0000; */
 *(volatile unsigned *)0x3FF303c |= 0x3fd;
 led=0x8;
 IOPMOD=0xffffffff;
 IOPDATA=~led;
 
 
 *(volatile unsigned *)0x3FF3008 |= 0xf58;
 led=0x8;
 IOPMOD=0xffffffff;
 IOPDATA=~led;
 
 *(volatile unsigned *)0x3FF3010 |= 0x100000;
 *(volatile UINT8 *)0x3FD0000= 0x38;
 
 for(i=0;i<3000;i++)
 ;
 
 
 
 *(volatile UINT8 *)0x3FD0000= 0xf;
 
 for(i=0;i<3000;i++)
 ;
 
 
 
 *(volatile UINT8 *)0x3FD0000= 0x1;
 
 for(i=0;i<3000;i++)
 ;
 
 *(volatile UINT8 *)0x3FD0000= 0x6;
 
 for(i=0;i<3000;i++)
 ;
 
 /*  val = 0xff << 7 ;    */
 
 /*  *(volatile UINT8 *) 0x3FD0000 = val;   */
 
 for(i=0;i<1000;i++)
 ;
 /*  *(volatile UINT8 *)0x3FD0002 = 'a';
 
 */
 
 while(*ch != '\0')
 {
 for(i=0;i<1000;i++)
 ;
 
 *(volatile UINT8 *)0x3FD0002 = *ch;
 ch++;
 
 }
 /*return 0;*/
 
 }
 
 void cleanup_module(void)
 
 {
 
 /* Unregister the device */
 
 int ret = unregister_chrdev(Major, DEVICE_NAME);
 
 if (ret < 0) printk("Error in unregister_chrdev: %d\n", ret);
 
 }
 
 /*           Methods
 
 */
 
 /* Called when a process tries to open the device file, like
 
 * "cat /dev/chardev"
 
 */
 
 static int device_open(struct inode *inode, struct file *file)
 
 {
 
 static int counter = 0;
 
 if (Device_Open) return -EBUSY;
 
 Device_Open++;
 
 sprintf(msg,"I already told you %d times Hello world!\n", counter++);
 
 msg_Ptr = msg;
 
 MOD_INC_USE_COUNT;
 
 return SUCCESS;
 
 }
 
 /* Called when a process closes the device file.
 
 */
 
 static int device_release(struct inode *inode, struct file *file)
 
 {
 
 Device_Open--; /* We're now ready for our next caller */
 
 /* Decrement the usage count, or else once you opened the file, you'll
 
 *never get get rid of the module. */
 
 MOD_DEC_USE_COUNT;
 
 return 0;
 
 }
 
 /* Called when a process, which already opened the dev file, attempts to
 
 *read from it.
 
 */
 
 static ssize_t device_read(struct file *filp,
 
 char *buffer, /* The buffer to fill with data */
 
 size_t length, /* The length of the buffer */
 
 loff_t *offset) /* Our offset in the file */
 
 {
 
 /* Number of bytes actually written to the buffer */
 
 int bytes_read = 0;
 
 /* If we're at the end of the message, return 0 signifying end of file */
 if (*msg_Ptr == 0) return 0;
 
 /* Actually put the data into the buffer */
 
 while (length && *msg_Ptr) {
 
 /* The buffer is in the user data segment, not the kernel segment;
 
 * assignment won't work. We have to use put_user which copies data from
 
 * the kernel data segment to the user data segment. */
 
 put_user(*(msg_Ptr++), buffer++);
 
 length--;
 
 bytes_read++;
 
 }
 
 /* Most read functions return the number of bytes put into the buffer */
 
 return bytes_read;
 
 }
 
 /* Called when a process writes to dev file: cat /mnt/test > /dev/chardev */
 
 static ssize_t device_write(struct file *filp,
 
 const char *buff,
 
 size_t len,
 
 loff_t *off)
 
 {
 
 printk ("<1>No such file or directory.\n");
 
 return -EINVAL;
 
 }
 
 
     | 
 |