您现在的位置: 主页 > 嵌入式开发入门到精通 > 单片机技术进阶 > 基于S3C2440的LCD1602驱动的设计 -
本文所属标签:
为本文创立个标签吧:

基于S3C2440的LCD1602驱动的设计 -

来源: 网络用户发布,如有版权联系网管删除 2018-09-07 

[导读]开发目标平台:linux-2.6.28+S3C2440+CRAMFS/YAFFS2  开发环境:UBUNTU-9.04+arm-linux-gcc-3.4.1  这次需要在s3c2440上开发一个简单的字符型LCD驱动,具体情况如下:  LCD1602共有16根管脚,控制信号3根RS,RW

开发目标平台:linux-2.6.28+S3C2440+CRAMFS/YAFFS2

本文引用地址: http://www.21ic.com/app/mcu/201807/784686.htm

  开发环境:UBUNTU-9.04+arm-linux-gcc-3.4.1

  这次需要在s3c2440上开发一个简单的字符型LCD驱动,具体情况如下:

  LCD1602共有16根管脚,控制信号3根RS,RW,RE,数据线8根DB0~DB7,可以支持8位数据格式和4位数据格式。

  RS:寄存器选择1:数据;0:指令【由GPIO控制】

  R/W:读、写操作选择1:读;0:写【我的硬件里直接置低电平】

  RE:使能信号【由GPIO控制】

  数据线DB4~DB7,分别连接4根GPIO口,DB0~DB3置高。

  首先内核注册驱动函数:

  static int __init mylcd_init(void)

  {

  int i;

  int ret = 0;

  for(i = 0;i < MAX_NUM;i++){

  s3c2410_gpio_cfgpin(plcd[i].pin,plcd[i].pin_out);

  }

  //初始化GPIO为输出

  ret =register_chrdev(LCD_MAJOR,DEVICE_NAME,&mylcd_fops);

  if(ret < 0){

  printk(KERN_WARNING "Cannot register driver of mylcdn");

  return ret;

  }

  printk(DEVICE_NAME " Init Is Okn");

  return 0;

  }

  驱动注销函数

  static void __exit mylcd_exit(void)

  {

  unregister_chrdev(LCD_MAJOR,DEVICE_NAME);

  printk(KERN_INFO " remove driver of myLCDn");

  }

  module_init(mylcd_init);

  module_exit(mylcd_exit);

  MODULE_LICENSE("GPL");

  MODULE_AUTHOR("qlx-1983@163.com");

  MODULE_DESCRIPTION("mylcd driver for s3c2440");

  驱动文件操作结构体,我对外提供IOCTL接口:

  static struct file_operations mylcd_fops = {

  .owner = THIS_MODULE,

  .ioctl = mylcd_ioctl,

  .open = mylcd_open,

  .release = mylcd_release

  };

  驱动的open和release函数的实现:

  static int mylcd_open(struct inode *inode,struct file *file)

  {

  return 0;

  }

  static int mylcd_release(struct inode *inode,struct file *file)

  {

  return 0;

  }

ioctl函数的实现:

  static int mylcd_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned int arg)

  {

  if(_IOC_TYPE(cmd) != GPIO_IOF_MAGIC)

  {

  return -ENOTTY;

  }

  if(_IOC_NR(cmd) >= GPIO_MAXNR)

  {

  return -ENOTTY;

  }

  switch(cmd)

  {

  case LCD_INIT: //初始化

  myLcd_port_init();

  break;

  case LCD_SCREEN_CLEAR: //清屏

  myLcd_Screen_Clear();

  break;

  case LCD_CURSOR_RETURN: //归位

  myLcd_Cursor_Home();

  break;

  case LCD_DDRAM_AD_SET: //设置DDRAM地址

  myLcd_ddram_ad_set(arg);

  break;

  case LCD_DATA_WRITE: //写数据

  myLcd_data_write(arg);

  break;

  default:

  break;

  }

  return 0;

  }

  因为我对LCD的功能要求比较简单,所以,只是提供了上面这些功能,当然,LCD1602还有很多接口可以对外提供,如果你感兴趣,可以补充一下!

  另外,附上针对这个LCD我写的上层接口函数:

  int OpenLcd(const char *lcd_name)

  {

  int Lcd_fd;

  if(access(lcd_name,F_OK) == 0){

  printf("%s Can Be opened!n",lcd_name);

  }else{

  system("mknod /dev/myLcd c 204 0");

  }

  Lcd_fd = open(lcd_name,O_RDWR);

  if(Lcd_fd < 0){

  printf("Open %s Is Failed!n");

  return 0;

  }

  printf("Open The Screen!n");

  return Lcd_fd;

  }

 void CloseLcd(int Lcd_fd)

  {

  printf("Close The Screen!n");

  close(Lcd_fd);

  }

  void InitLcd(int Lcd_fd)

  {

  printf("Init The Screen!n");

  ioctl(Lcd_fd,LCD_INIT,0);

  }

  void ClearLcd(int Lcd_fd)

  {

  printf("Clear The Screen!n");

  ioctl(Lcd_fd,LCD_SCREEN_CLEAR,0);

  ioctl(Lcd_fd,LCD_CURSOR_RETURN,0);

  }

  void PrintfLcd(int Lcd_fd,const char *src,unsigned int pos)

  {

  int src_len = 0;

  int i;

  src_len = strlen(src);

  if((pos >= 0)&&(pos <= 32)){

  if(src_len <= (32-pos)){

  ioctl(Lcd_fd,LCD_DDRAM_AD_SET,pos);

  for(i = 0;i < src_len ;i++){

  ioctl(Lcd_fd,LCD_DATA_WRITE,src[i]);

  }

  }else{

  printf("The Lcd Is Not Enough Lengthn");

  }

  }else{

  printf("The Pos Is Out Size Of Addressn");

  }

  }

  以下是测试应用程序:

  int main(int argc, char *argv[])

  {

  int Lcd_fd;

  Lcd_fd = OpenLcd(DEV_NAME);

  InitLcd(Lcd_fd);

  PrintfLcd(Lcd_fd,"AAAABBB",0);

  PrintfLcd(Lcd_fd,"FFFFFFFFFFF",16);

  sleep(10);

  ClearLcd(Lcd_fd);

  PrintfLcd(Lcd_fd,"AAAABBB",0);

  PrintfLcd(Lcd_fd,"DDDDDDDD",16);

  CloseLcd(Lcd_fd);

  }




              查看评论 回复



嵌入式交流网主页 > 嵌入式开发入门到精通 > 单片机技术进阶 > 基于S3C2440的LCD1602驱动的设计 -
 

"基于S3C2440的LCD1602驱动的设计 -"的相关文章

网站地图

围观()