打印

新鲜出炉的at91rm9200控制st7920液晶的串行驱动

[复制链接]
1906|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wangkj|  楼主 | 2007-11-9 15:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
仅仅使用pc14,pc15两个GPIO,外加电源线两条。(未测试,供参考)。
最近几天有空了测试
这种液晶是最常见的 12832,12864控制器,他们都是通用的。
硬件:sck - pc14  sid -> pc15 
psb - GND , CS - VCC


/*-------------------------------------------------------------------------------------
date:20071109
author: wkj
ver 1.0
stc7920  lcd driver
---------------------------------------------------------------------------------------*/
#include <sys/types.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/file.h>
#include "gpio.h"
#include "main.h"
#include "io.h"
#include <stdarg.h>
#include <memory.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <signal.h>

//当前像素位置 和当前显示页 
static unsigned char PixX,page;
#define DEBUGMSG(x, y, args...) printf(y, ##args)
void    *map_base;      //phy 0xffff f000 virtual address
//clock input                    同步时钟输入端
#define         E_CLK_0         *((unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_CODR)))) = 0x1<<14; //PC14 as 0; A0=0
#define         E_CLK_1         *((unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_SODR)))) = 0x1<<14; //PC14 as 1; A0=1
#define         RW_SID_0          *((unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_CODR)))) = 0x1<<15; //PC15 as 0 ; RW=0 
#define         RW_SID_1    *((unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_SODR)))) = 0x1<<15; //PC15 as 1 ; RW=1

void delay(unsigned long int n)
{
  unsigned long int i;
  for(i=0; i<n*10; i++) {;}
}

 //串行发送一字节数据
void SendByte(unsigned char dat)
{
     unsigned char i;
     for(i=0;i<8;i++)
           {
                 E_CLK_0;
                 if(dat&0x80)
                    {
                        RW_SID_1;
                    }
                 else 
                    {
                        RW_SID_0;
                    }
                 E_CLK_1;
                 dat=dat<<1;
            }
}
//写控制命令
void SendCMD(unsigned char dat)
{
     SendByte(0xF8);//11111,00,0 RW=0,RS=0 同步标志
     SendByte(dat&0xF0);//高四位
     SendByte((dat&0x0F)<<4);//低四位
}

//写显示数据或单字节字符
void SendDat(unsigned char dat)
{
     SendByte(0xFA);//11111,01,0 RW=0,RS=1
     SendByte(dat&0xF0);//高四位
     SendByte((dat&0x0F)<<4);//低四位
}

/*      写汉字到LCD 指定的位置
     x_add显示RAM的地址
     dat1/dat2显示汉字编码
*/
void display(unsigned char x_add,unsigned char dat1,unsigned char dat2)
{
     SendCMD(x_add);//1xxx,xxxx 设定DDRAM 7位地址xxx,xxxx到地址计数器AC
     SendDat(dat1);
     SendDat(dat2);
}

//初始化 LCM
void initlcm(void)
{
     delay(100);
     SendCMD(0x30);//功能设置,一次送8位数据,基本指令集
     SendCMD(0x0C);//0000,1100  整体显示,游标off,游标位置off
     SendCMD(0x01);//0000,0001 清DDRAM
     SendCMD(0x02);//0000,0010 DDRAM地址归位
     SendCMD(0x80);//1000,0000 设定DDRAM 7位地址000,0000到地址计数器AC
}


//////////////////////////////////////////
unsigned char SetLcdDisplayCharPos(unsigned char row, unsigned char col) 

  if ((row < 2) && (col < 16))//英文字符为2行16列 
  { 
    SendCMD(0x80 + row * 16 + col);//发送设定DDRAM地址row * 16 + col命令 
   return 1; 
  } 
  else  
    return 0; 


void LcdDisplayChar(unsigned char row, unsigned char col, unsigned char * string) 

  if (SetLcdDisplayCharPos(row, col)) 
  { 
    SendDat(*string); 
  } 


unsigned char SetLcdDisplayChinsePos(unsigned char row, unsigned char col) 

  if ((row < 2) && (col < 8))//汉字字符为2行8列(偶数对齐) 
  { 
    SendCMD(0x80 + row * 16 + col * 2);//发送设定DDRAM地址row * 16 + col * 2命令 
   return 1; 
  } 
  else 
    return 0; 


void LcdDisplayChinse(unsigned char row, unsigned char col, unsigned char * string) 

  if (SetLcdDisplayChinsePos(row, col)) 
  { 
    SendDat(*string); 
    SendDat(*(string + 1)); 
  } 


void LcdDisplayString(unsigned char * string) 

  while(*string) SendDat(*string ++); 



//////////////////////////////////////////

FILE *f;
int n,fd;
main(void)
{
char num,status=0;
int i,j,count;
int ch;       
 
printf("start ");
if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1){
     DEBUGMSG(DEBUG_ERR, "gpio: Error opening /dev/mem ");
     exit(-1);
        }
        //map 0xffff
map_base      = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, AT91_SYS);//AT91_SYS = 0xffff f000
    
*((volatile unsigned int*)(map_base + ((PIOC_OFFSET + AT91_PIO_PER )))) = (0x1<<15)|(0x1<<14); //PC15 PC14 as gpio ;1 bit set to GPIO and zero bit no effect
*((volatile unsigned int*)(map_base + ((PIOC_OFFSET + AT91_PIO_OER )))) = (0x1<<15)|(0x1<<14);;//as output
*((volatile unsigned int*)(map_base + ((PIOC_OFFSET + AT91_PIO_PUER )))) = (0x1<<15)|(0x1<<14);;//use up resistor

     initlcm();
     SendCMD(0x81);//1000,0001 设定DDRAM 7位地址000,0001到地址计数器AC
     SendDat(0x33);
     SendDat(0x42);
     SendDat(0x43);
     SendDat(0x44);
     SendCMD(0x00);

  SetLcdDisplayChinsePos(0, 0);//汉字定位到上行左端 
  LcdDisplayString("汉字显示演示程序"); 
           delay(65535);
  SetLcdDisplayCharPos(1,0);//字符定位到下行左端 
  LcdDisplayString("0123456789ABCDEF"); 

           delay(65535);

     for(;;)
     {
           delay(100);
           display(0x80,0xb0,0xb2);
           display(0x81,0xbb,0xD5);
           display(0x82,0xb5,0xe7);
           display(0x83,0xc1,0xA6);
           display(0x84,0xc5,0xe0);
           display(0x85,0xD1,0xb5);
           display(0x86,0xd6,0xD0);
           display(0x87,0xd0,0xc4);
           delay(65000);
           SendCMD(0x00);
           delay(100);
           display(0x90,0xb0,0xb2);
           display(0x91,0xbb,0xD5);
           display(0x92,0xb5,0xe7);
           display(0x93,0xc1,0xA6);
           display(0x94,0xc5,0xe0);
           display(0x95,0xD1,0xb5);
           display(0x96,0xd6,0xD0);
           display(0x97,0xd0,0xc4);
           delay(65000);
           SendCMD(0x00);
           delay(100);
           display(0x88,0xb0,0xb2);
           display(0x89,0xbb,0xD5);
           display(0x8A,0xb5,0xe7);
           display(0x8B,0xc1,0xA6);
           display(0x8C,0xc5,0xe0);
           display(0x8D,0xD1,0xb5);
           display(0x8E,0xd6,0xD0);
           display(0x8F,0xd0,0xc4);
           delay(65000);
           SendCMD(0x00);
           delay(100);
           display(0x98,0xb0,0xb2);
           display(0x99,0xbb,0xD5);
           display(0x9A,0xb5,0xe7);
           display(0x9B,0xc1,0xA6);
           display(0x9C,0xc5,0xe0);
           display(0x9D,0xD1,0xb5);
           display(0x9E,0xd6,0xD0);
           display(0x9F,0xd0,0xc4);
           delay(65000);
           SendCMD(0x00);
     }
   close(fd);
}

相关帖子

沙发
john_light| | 2007-11-9 17:01 | 只看该作者

最近正在看内核模块的编程部分

路过支持一下。

使用特权

评论回复
板凳
wangkj|  楼主 | 2007-11-10 10:45 | 只看该作者

显示结果

使用特权

评论回复
地板
wangkj|  楼主 | 2007-11-10 10:48 | 只看该作者

lcd有反应了,但是不正常

成功了50%

使用特权

评论回复
5
wangkj|  楼主 | 2007-11-10 12:50 | 只看该作者

正常的程序

cs接vcc;sid,clk 10K上拉


/*-------------------------------------------------------------------------------------
date:20071109
author: wkj
ver 1.0
stc7920  lcd driver
---------------------------------------------------------------------------------------*/
#include <sys/types.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/file.h>
#include "gpio.h"
#include "main.h"
#include "io.h"
#include <stdarg.h>
#include <memory.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <signal.h>

//µ±Ç°ÏñËØλÖàºÍµ±Ç°ÏÔʾҳ 
static unsigned char PixX,page;
#define DEBUGMSG(x, y, args...) printf(y, ##args)
void    *map_base;      //phy 0xffff f000 virtual address
//clock input                    Í¬²½Ê±ÖÓÊäÈë¶Ë
#define         E_CLK_0         *((unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_CODR)))) = 0x1<<14; //PC14 as 0; A0=0
#define         E_CLK_1         *((unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_SODR)))) = 0x1<<14; //PC14 as 1; A0=1
#define         RW_SID_0          *((unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_CODR)))) = 0x1<<15; //PC15 as 0 ; RW=0 
#define         RW_SID_1    *((unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_SODR)))) = 0x1<<15; //PC15 as 1 ; RW=1

void delay(unsigned long int n)
{
  unsigned long int i;
  for(i=0; i<n*10; i++) {;}
}

 //´®Ðз¢ËÍÒ»×Ö½ÚÊý¾Ý
void SendByte(unsigned char dat)
{
     unsigned char i;
     for(i=0;i<8;i++)
           {
           printf("1 ");
                 E_CLK_0;
           printf("2 ");
                 if(dat&0x80)
                    {
           printf("3 ");
                        RW_SID_1;
           printf("4 ");
                    }
                 else 
                    {
           printf("5 ");
                        RW_SID_0;
                    }
                 E_CLK_1;
           printf("8 ");
                 dat=dat<<1;
            }
}
//д¿ØÖÆÃüÁî
void SendCMD(unsigned char dat)
{
     SendByte(0xF8);//11111,00,0 RW=0,RS=0 Í¬²½±êÖ¾
     SendByte(dat&0xF0);//¸ßËÄλ
     SendByte((dat&0x0F)<<4);//µÍËÄλ
}

//дÏÔʾÊý¾Ý»òµ¥×Ö½Ú×Ö·û
void SendDat(unsigned char dat)
{
     SendByte(0xFA);//11111,01,0 RW=0,RS=1
     SendByte(dat&0xF0);//¸ßËÄλ
     SendByte((dat&0x0F)<<4);//µÍËÄλ
}

/*      Ð´ºº×Öµ½LCD Ö¸¶¨µÄλÖÃ
     x_addÏÔʾRAMµÄµØÖ·
     dat1/dat2ÏÔʾºº×Ö±àÂë
*/
void display(unsigned char x_add,unsigned char dat1,unsigned char dat2)
{
     SendCMD(x_add);//1xxx,xxxx É趨DDRAM 7λµØÖ·xxx,xxxxµ½µØÖ·¼ÆÊýÆ÷AC
     SendDat(dat1);
     SendDat(dat2);
}

//³õʼ»¯ LCM
void initlcm(void)
{

     delay(100);
     SendCMD(0x30);//¹¦ÄÜÉèÖã¬Ò»´ÎËÍ8λÊý¾Ý£¬»ù±¾Ö¸Á
     SendCMD(0x0C);//0000,1100  ÕûÌåÏÔʾ£¬Óαêoff£¬ÓαêλÖÃoff
     SendCMD(0x01);//0000,0001 ÇåDDRAM
     SendCMD(0x02);//0000,0010 DDRAMµØÖ·¹éλ
     SendCMD(0x80);//1000,0000 É趨DDRAM 7λµØÖ·000£¬0000µ½µØÖ·¼ÆÊýÆ÷AC
}


//////////////////////////////////////////
unsigned char SetLcdDisplayCharPos(unsigned char row, unsigned char col) 

  if ((row < 2) && (col < 16))//Ó¢ÎÄ×Ö·ûΪ2ÐÐ16ÁР
  { 
    SendCMD(0x80 + row * 16 + col);//·¢ËÍÉ趨DDRAMµØÖ·row * 16 + colÃüÁî 
   return 1; 
  } 
  else  
    return 0; 


void LcdDisplayChar(unsigned char row, unsigned char col, unsigned char * string) 

  if (SetLcdDisplayCharPos(row, col)) 
  { 
    SendDat(*string); 
  } 


unsigned char SetLcdDisplayChinsePos(unsigned char row, unsigned char col) 

  if ((row < 2) && (col < 8))//ºº×Ö×Ö·ûΪ2ÐÐ8ÁÐ(żÊý¶ÔÆë) 
  { 
    SendCMD(0x80 + row * 16 + col * 2);//·¢ËÍÉ趨DDRAMµØÖ·row * 16 + col * 2ÃüÁî 
   return 1; 
  } 
  else 
    return 0; 


void LcdDisplayChinse(unsigned char row, unsigned char col, unsigned char * string) 

  if (SetLcdDisplayChinsePos(row, col)) 
  { 
    SendDat(*string); 
    SendDat(*(string + 1)); 
  } 


void LcdDisplayString(unsigned char * string) 

  while(*string) SendDat(*string ++); 



//////////////////////////////////////////

FILE *f;
int n,fd;
main(void)
{
char num,status=0;
int i,j,count;
int ch;       
printf("start ");
if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1){
     DEBUGMSG(DEBUG_ERR, "gpio: Error opening /dev/mem ");
     exit(-1);
        }
        //map 0xffff
map_base      = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, AT91_SYS);//AT91_SYS = 0xffff f000
    
*((volatile unsigned int*)(map_base + ((PIOC_OFFSET + AT91_PIO_PER )))) = (0x1<<15)|(0x1<<14); //PC15 PC14 as gpio ;1 bit set to GPIO and zero bit no effect
*((volatile unsigned int*)(map_base + ((PIOC_OFFSET + AT91_PIO_OER )))) = (0x1<<15)|(0x1<<14);;//as output
*((volatile unsigned int*)(map_base + ((PIOC_OFFSET + AT91_PIO_PUER )))) = (0x1<<15)|(0x1<<14);;//use up resistor
/*
for(;;){
printf("0xff ");
SendByte(0xff);
printf("before delay ");
delay(10000000);
printf("0x00 ");
SendByte(0x00);
delay(10000000);

printf("E_CLK_0 ");
E_CLK_0;
delay(10000000);
printf("E_CLK_1 ");
E_CLK_1;
delay(10000000);

*/
     initlcm();
     SendCMD(0x81);//1000,0001 É趨DDRAM 7λµØÖ·000£¬0001µ½µØÖ·¼ÆÊýÆ÷AC
     SendDat(0x33);
     SendDat(0x42);
     SendDat(0x43);
     SendDat(0x44);
     SendCMD(0x00);

  SetLcdDisplayChinsePos(0, 0);//ºº×Ö¶¨Î»µ½ÉÏÐÐ×ó¶Ë 
  LcdDisplayString("ºº×ÖÏÔʾÑÝʾ³ÌÐò"); 
    delay(65535);
    SetLcdDisplayCharPos(1,0);//×Ö·û¶¨Î»µ½ÏÂÐÐ×ó¶Ë 
    LcdDisplayString("0123456789ABCDEF"); 
    delay(65535);
   
printf("2, ");
     for(;;)
     {
printf("3, ");
           delay(100);
           display(0x80,0xb0,0xb2);
           display(0x81,0xbb,0xD5);
           display(0x82,0xb5,0xe7);
           display(0x83,0xc1,0xA6);
           display(0x84,0xc5,0xe0);
           display(0x85,0xD1,0xb5);
           display(0x86,0xd6,0xD0);
           display(0x87,0xd0,0xc4);
           delay(65000);
           SendCMD(0x00);
           delay(100);
           display(0x90,0xb0,0xb2);
           display(0x91,0xbb,0xD5);
           display(0x92,0xb5,0xe7);
           display(0x93,0xc1,0xA6);
           display(0x94,0xc5,0xe0);
           display(0x95,0xD1,0xb5);
           display(0x96,0xd6,0xD0);
           display(0x97,0xd0,0xc4);
           delay(65000);
           SendCMD(0x00);
           delay(100);
           display(0x88,0xb0,0xb2);
           display(0x89,0xbb,0xD5);
           display(0x8A,0xb5,0xe7);
           display(0x8B,0xc1,0xA6);
           display(0x8C,0xc5,0xe0);
           display(0x8D,0xD1,0xb5);
           display(0x8E,0xd6,0xD0);
           display(0x8F,0xd0,0xc4);
           delay(65000);
           SendCMD(0x00);
           delay(100);
           display(0x98,0xb0,0xb2);
           display(0x99,0xbb,0xD5);
           display(0x9A,0xb5,0xe7);
           display(0x9B,0xc1,0xA6);
           display(0x9C,0xc5,0xe0);
           display(0x9D,0xD1,0xb5);
           display(0x9E,0xd6,0xD0);
           display(0x9F,0xd0,0xc4);
           delay(65000);
           SendCMD(0x00);
     }
   close(fd);
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

581

主题

9976

帖子

23

粉丝