仅仅使用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); }
|