flyxyh 发表于 2005-9-12 21:34:14

版主帮我看看这个lcd的程序噢

这是我在linux下编写的一个lcd(16*2)驱动程序,参考了lumit网站上的lcd程序,其中的初始化程序,已经可以清屏.但是向lcd中写数据时,发现仍然显示清屏,并不显示我所要写的数据,看了好几天了,没进展,呵呵,版主帮忙看看吧,谢谢! :P ,在这个程序里面,我在初始化函数里面包含了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 *)0x3ff5008)


    #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; /* 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;

}

:P:P

limingth 发表于 2005-9-13 00:37:49

不同液晶型号,驱动有些相似,但未必可以通用。
lumit4510 上最早用的是 FM1602C 的 16×2 的字符液晶,但调试了很久也没有正确显示,后来换成 GMC1602C 同样的 16×2 的字符液晶,程序一个字没改就可以用了。

flyxyh 发表于 2005-9-13 20:50:03

噢,不好意思,我是说斑竹帮我看看向lcd写数据这个地方有没有问题呢?这种写法对吗?

limingth 发表于 2005-9-13 23:15:23

哪儿是你所说的 “向lcd写数据这个地方” ?:?

flyxyh 发表于 2005-9-14 10:01:36

while(*ch != '\0')
{
for(i=0;i<1000;i++)
;

*(volatile UINT8 *)0x3FD0002 = *ch;
ch++;

}
这个地方

limingth 发表于 2005-9-14 11:21:28

这种写法没问题,可以参考看Learn lumit Step 19 里面关于写 lcd 的格式。

int lcd_write( unsigned char * buf, int count )
{       
        int i = 0;
        for( i = 0; i<count; i++ )
        {
                *(unsigned char *)LDATAWR = *(buf+i);
                lcd_ioctl( LCD_WAIT, 3 );
        }
        return count;
}
页: [1]
查看完整版本: 版主帮我看看这个lcd的程序噢