Chinaunix

标题: linux下通过并行口控制1602LCM的代码 [打印本页]

作者: leadgenius    时间: 2010-01-09 06:59
标题: linux下通过并行口控制1602LCM的代码
linux下并行口操作和字符型LCM显示控制

备注:源文件已上传到资源中心

注释慢慢补
代码:

#include
#include  /* for libc5 */
#include  /* for glibc */
#define THEPORTS 0x3FF
#define DATAPORT 0x378
#define STATPORT 0x379
#define CTRLPORT 0x37A
#define DELAYTIME 1000
// 0xC0: to make the first bit 0, to STROBE of patport is SET, to gave E_1602 a 1, The default.
#define CTRLPORT_INIT 0xC0
#define CTRLPORT_ZRS 0x02
#define CTRLPORT_ZE 0x01
#define LCDCMD_CLEAN 0x01  // ctrl cmd #1
#define LCDCMD_CURSOR_RET 0x02  // ctrl cmd #2
#define LCDCMD_DISPMODE 0x04  // ctrl cmd #3
#define LCDCMD_DISPMODE_CURSOR_MVRIGHTAUTO 0x02
#define LCDCMD_DISPMODE_TEXT_MVABLE 0x01
#define LCDCMD_DISPSWITCH 0x08  // ctrl cmd #4
#define LCDCMD_DISPSWITCH_DISPON 0x04
#define LCDCMD_DISPSWITCH_CURSORON 0x02
#define LCDCMD_DISPSWITCH_CURSORTWINKLE 0x01
#define LCDCMD_CONTENTMV 0x10  // ctrl cmd #5
#define LCDCMD_CONTENTMV_TEXTMV 0x08
#define LCDCMD_CONTENTMV_CURSORMV 0x04
#define LCDCMD_FUNCSET 0x20  // ctrl cmd #6
#define LCDCMD_FUNCSET_8BITBUS 0x10
#define LCDCMD_FUNCSET_2LINES 0x08
#define LCDCMD_FUNCSET_5x10C 0x40
// ctrl cmd #7 is not USEd
#define LCDCMD_POSISET 0x80  // ctrl cmd #8
#define LCDCMD_POSISET_1LINE 0x00
#define LCDCMD_POSISET_2LINE 0x40
//typedef struct TEXTMAP {
//}Textmap;
//static Textmap text_map = {
// };
void Write_Command(unsigned char cmd)
{
unsigned char ctrlbyte;
outb(cmd, DATAPORT);
// clr autofeed to RS_1602. clr XX to RW_1602. clr strobe to E_1602
ctrlbyte = CTRLPORT_INIT | CTRLPORT_ZRS;
outb(ctrlbyte, CTRLPORT);
ctrlbyte = CTRLPORT_INIT | CTRLPORT_ZRS | CTRLPORT_ZE;
outb(ctrlbyte, CTRLPORT);
usleep(DELAYTIME);
outb(CTRLPORT_INIT, CTRLPORT); // set strobe to E_1602 an AUTOFEED to RS_1602
}
void Write_Data(char data)
{
unsigned char ctrlbyte;
outb(data, DATAPORT);
// set autofeed to RS_1602. clr XX to RW_1602. clr strobe to E_1602
ctrlbyte = CTRLPORT_INIT | CTRLPORT_ZE;
outb(ctrlbyte, CTRLPORT);
usleep(DELAYTIME);
outb(CTRLPORT_INIT, CTRLPORT); // set strobe to E_1602 an AUTOFEED to RS_1602
}
void Write_Text(char *t)
{
while(*t != 0)
{
  Write_Data(*t++);
}
}
int main(int argc, char **argv)
{
int ret;
if(argc  \n", argv[0]);
  fprintf(stderr, "or\nUsage Format: %s 0 \n", argv[0]);
  fprintf(stderr, "\t must > 0, for 1602 should  will be shown in the line.\n");
  fprintf(stderr, "\t:\n");
  fprintf(stderr, "\t\"init\" must be used before all LCD operations, do once enough\n");
  fprintf(stderr, "\t\"clean\" will clean the content the LCD shown\n");
  fprintf(stderr, "\nExample: %s 2 \"Hello World !\"\n", argv[0]);
  return 1;
}
ret = ioperm(0x00, THEPORTS, 1);
if(-1 == ret)
{
  printf("\r\n ioperm return -1");
  return 1;
}
// init CTRLPORT
outb(CTRLPORT_INIT, CTRLPORT);
if(argv[1][0] == '1')
{
  Write_Command(LCDCMD_POSISET);
  Write_Text(argv[2]);
}
else if(argv[1][0] == '2')
{
  Write_Command(LCDCMD_POSISET | LCDCMD_POSISET_2LINE);
  Write_Text(argv[2]);
}
else if(argv[1][0] == '0')
{
  if(!strcmp(argv[2], "init"))
  {
   Write_Command(LCDCMD_CLEAN);
   Write_Command(LCDCMD_FUNCSET | LCDCMD_FUNCSET_8BITBUS | LCDCMD_FUNCSET_2LINES);
   Write_Command(LCDCMD_DISPSWITCH | LCDCMD_DISPSWITCH_DISPON);
   Write_Command(LCDCMD_DISPMODE | LCDCMD_DISPMODE_CURSOR_MVRIGHTAUTO);
  }
  else if(!strcmp(argv[2], "clean"))
  {
   Write_Command(LCDCMD_CLEAN);
  }
  else
   fprintf(stderr, "Unknown preCMD type found!\n");
}
else
{
  fprintf(stderr, "Unknown preCMD type found!\n");
}
}


附图





本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/2244/showart_2144215.html




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2