现在的位置: 首页 > 综合 > 正文

PIC16F877A驱动12864液晶

2018年03月16日 ⁄ 综合 ⁄ 共 6683字 ⁄ 字号 评论关闭

本程序配套液晶为金鹏的12864液晶使用串行模式

头文件

#ifndef LCD12864_H
#define LCD12864_H
#include  "main.h"

//define control port pin
//serial mode
//#define SCLK RD4
//#define STD RD5
//#define LCD_EN RD6
//parallel mode
#define PSB RA0
#define CS RA1
#define STD RA2
#define SCLK RA3
#define RST RA4

//define command word
#define CLR_LCD 0x01 ;
#define CLR_AC 0x02 ;
#define CURSOR_RIGHT 0x14
#define CURSOR_LEFT 0x10
#define CURSOR_ON 0x0F
#define CURSOR_OFF 0x0C
#define DISP_RIGHT 0x1C
#define DISP_LEFT 0x18
#define LCD_BUSY RD7

//define function
#define lcd_enable() CS=1
#define lcd_disable() CS=0
//4个基本函数
void init_lcd() ;
void wr_lcd(uchar flag,uchar data) ;//flag=0 command;flag=1,data
void send_cmd(uchar data ) ;
void send_byte(uchar data) ;
//4个低级封装函数实现字符、字符串的显示、汉字的显示和简单图像的显示
void char_disp(const char data,uchar X,uchar Y) ;
void str_disp(const char *data,uchar X,uchar Y) ;
void chn_disp(const char *data ,uchar add,uchar y,uchar count) ;
void clr_lcd() ;
void pic_disp1(uchar *img) ;
void pic_disp2(uchar *img) ;
void con_disp(uchar x0,uchar y0,uchar x1,uchar y1) ;
//控制显示函数
void shift_cursor(uchar flag,uchar count) ;
void shift_lcd(uchar flag,uchar count) ;
void locate_xy(uchar x,uchar y) ;
void lcd_rol() ;
void clr_ram() ;
//字符串处理
void float_str(uchar *str,float data) ;
void int_str(uchar *str,int data) ;
#endif
子程序

#include "lcd12864.h"
void init_lcd()
{
//init port ;
 ADCON1=0x06 ;//AD端口作为数字量端口
 TRISA=TRISA&0xE0 ;
 RST=0 ;
 DelayMs(20) ;
 RST=1 ;
 DelayMs(20) ;
 PSB=0 ;

 send_cmd(0x38) ;
 DelayUs(72) ;
// send_cmd(0x38,0) ;//8位控制,基本指令集
 send_cmd(0x38) ;
 DelayUs(72) ;
 send_cmd(0x38) ;
 send_cmd(0x38) ;
 send_cmd(0x30) ;
 send_cmd(0x0C) ;
 send_cmd(0x01) ;
 send_cmd(0x06) ;
 clr_lcd() ;
}
//两位小数三位整数的浮点数变为字符串
void float_str(uchar *str,float data)
{
 uchar a[6],flag ;
 int temp ;
 if(data<0)
 {
  *(str++)=0x2D ;
  data=-data ;
 }
 temp=(int)(data*100) ;
 a[5]=temp%10+0x30 ;
 a[4]=temp/10%10+0x30;
 a[3]=0x2E ;
 a[2]=temp/100%10+0x30 ;
 a[1]=temp/1000%10+0x30 ;
 a[0]=temp/10000+0x30 ;
 flag=0 ;
 for(temp=0;temp<6;temp++)
 {
  if((a[temp]==0x30)&&(flag==0))
   continue ;
  else
   flag=1 ;
  *(str++)=a[temp] ;
 }
 *str='/0' ;
}
//注意data的范围为-32767~32767
void int_str(uchar *str,int data)
{
 uchar a[5],flag,temp ;
 if(data<0)
 {
  *(str++)=0x2D ;
  data=-data ;
 }
 a[4]=data%10 +0x30 ;
 a[3]=data/10%10+0x30 ;
 a[2]=data/100%10+0x30 ;
 a[1]=data/1000%10+0x30 ;
 a[0]=data/10000+0x30 ;
 flag=0 ;
 for(temp=0;temp<6;temp++)
 {
  if((a[temp]==0x30)&&(flag==0))
   continue ;
  else
   flag=1 ;
  *(str++)=a[temp] ;
 }
 *str='/0' ;
}

void wr_lcd(uchar flag,uchar data)
{
 uchar temp,i ,j ;
 DelayUs(1) ;
 temp=data ;
 CS=1 ;
 SCLK=0 ;
 STD=1 ;
 for(i=0;i<5;i++)
 {
  SCLK=1 ;
  SCLK=0 ;
 }
 STD=0 ;
 SCLK=1 ;
 SCLK=0 ;
 STD=flag ;
 SCLK=1 ;
 SCLK=0 ;
 STD=0 ;
 SCLK=1 ;
 SCLK=0 ;
 for(i=0;i<2;i++)
 {
  for(j=0;j<4;j++)
  {
   if(temp&0x80)
    STD=1 ;
   else
        STD=0 ;
   SCLK=1 ;
   SCLK=0 ;
   temp=temp<<1 ;
  }
  STD=0 ;
  for(j=0;j<4;j++)
  {
   SCLK=1 ;
   SCLK=0 ;
  }
 }
}

void send_cmd(uchar data)
{
 wr_lcd(0,data) ;
}
void send_byte(uchar data)
{
 wr_lcd(1,data) ;
}
void char_disp(const char data,uchar X,uchar Y)
{
// send_cmd(0x30,1) ;//8端口控制,使用基本指令集
 X=X&0x07 ;
 Y=Y&0x03 ;
 switch(Y)
 {
  case 0 :
   Y=0x80 ;
   break ;
  case 1 :
   Y=0x90 ;
   break ;
  case 2 :
   Y=0x88 ;
   break ;
  case 3 :
   Y=0x98 ;
   break ;
  default :
   break ;
 }
 send_cmd(X+Y) ;//设置DDRAM地址
 send_byte(data) ;
}

void shift_cursor(uchar flag,uchar count)
{
 uchar i;
 if(flag)
 {
  for(i=0;i<count;i++)
   send_cmd(0x10) ;
 }
 else
 {
  for(i=0;i<count;i++)
   send_cmd(0x14) ;
 }
}

void shift_lcd(uchar flag,uchar count)
{
 uchar i;
 if(flag)
 {
  for(i=0;i<count;i++)
   send_cmd(0x18) ;
 }
 else
 {
  for(i=0;i<count;i++)
   send_cmd(0x1c) ;
 }
}
//右半屏显示适用于(64*64)图形
void pic_disp1(uchar *img)
{
 uchar i,j ;
 send_cmd(0x34) ;//关显示
 for(j=0;j<32;j++)
 {
  send_cmd(0x80+j) ;
  send_cmd(0x80) ;
  for(i=0;i<2;i++)
  {
   send_byte(img[j*16+i*2]) ;
   send_byte(img[j*16+i*2+1]) ;
  }
 }

 send_cmd(0x0c) ;//close blind cursor
 send_cmd(0x36) ;
  send_cmd(0x30);
}
void pic_disp2(uchar *img)
{
 uchar i,j ;
 send_cmd(0x34) ;//关显示
 for(j=32;j<64;j++)
 {
  send_cmd(0x80+j-32) ;
  send_cmd(0x88) ;
  for(i=0;i<4;i++)
  {
   send_byte(img[j*16+i*2]) ;
   send_byte(img[j*16+i*2+1]) ;   
  }
 }
 send_cmd(0x30);
 send_cmd(0x0c) ;//close blind cursor
 send_cmd(0x36) ;//开显示
}
//清屏
void clr_lcd()
{
 uchar i,j ;
 send_cmd(0x30) ;
 send_cmd(0x01) ; 
 send_cmd(0x34) ;
 for(j=0;j<32;j++)
 {
  send_cmd(0x80+j) ;//设置列地址
  send_cmd(0x80) ;//设置行起始地址
  for(i=0;i<8;i++)
  {
   send_byte(0x00) ;
   send_byte(0x00) ;
  }
 }

 for(j=32;j<64;j++)
 {
  send_cmd(0x80+j-32) ;
  send_cmd(0x88) ;
  for(i=0;i<8;i++)
  {
   send_byte(0x00) ;
   send_byte(0x00) ;   
  }
 }
 send_cmd(0x36) ;
 send_cmd(0x30);
 send_cmd(0x0c) ;//close blind cursor
}
void str_disp(const char *data,uchar X,uchar Y)
{
 X=X&0x07 ;//don't outweigh the numbers of one line
 Y=Y&0x03 ;
 switch(Y)
 {
  case 0:
   Y=0x80 ;
   break ;
  case 1 :
   Y=0x90 ;
   break ;
  case 2 :
   Y=0x88 ;
   break ;
  case 3 :
   Y=0x98 ;
   break ;
  defualt :
   break ;
 }
 send_cmd(Y+X) ;
 while(*data!='/0')
 {
  send_byte(*data++) ;
 }
}

void chn_disp(const char *data,uchar X,uchar Y,uchar count)
{
 uchar i ;
 switch(Y)
 {
  case 0:
   Y=0x80 ;
   break ;
  case 1 :
   Y=0x90 ;
   break ;
  case 2 :
   Y=0x88 ;
   break ;
  case 3 :
   Y=0x98 ;
   break ;
  defualt :
   break ;
 }

 send_cmd(Y+X) ;
 for(i=0;i<count*2;i++)
  send_byte(*data++) ;
}
void locate_xy(uchar X,uchar Y)
{
 X=X&0x07 ;
 Y=Y&0x03 ;
 switch(Y)
 {
  case 0:
   Y=0x80 ;
   break ;
  case 1 :
   Y=0x90 ;
   break ;
  case 2 :
   Y=0x88 ;
   break ;
  case 3 :
   Y=0x98 ;
   break ;
  defualt :
   break ;
 }
 send_cmd(Y+X) ;
}
void con_disp(uchar x0,uchar y0,uchar x1,uchar y1)
{
 ;
}
void lcd_rol()
{
 uchar i;
 send_cmd(0x03) ;
 for(i=0;i<64;i++)
 {
   send_cmd(0xC0+i) ;

  DelayMs(200) ;
 }
}
void clr_ram()
{
 send_cmd(0x01) ;
}

下面是测试程序

#include <stdio.h>
#include <stdlib.h>

#include "main.h"
#include "t232.h"
#include "lcd12864.h"
t232_frame tframe ;
void interrupt main_int()
{
 t232_int(&tframe) ;
}
void init_all()
{
 asm("clrwdt");  
 init_232() ;
 init_lcd() ;
 init_t232_frame(&tframe) ;

}
const uchar tab5[]={
0X00,0X03,0X80,0X00,0X00,0X0F,0XE0,0X00,0X00,0X3F,0XF8,0X00,0X60,0XFF,0XFE,0X00,
0X40,0XFF,0XF8,0X00,0X40,0XCF,0XE0,0X00,0X47,0XFF,0XBC,0X3E,0X44,0X01,0X60,0X60,
0X44,0X00,0X00,0X40,0X44,0X44,0X20,0X44,0X44,0X44,0X60,0X44,0X44,0X44,0X40,0X44,
0X44,0X44,0X04,0X04,0X00,0X40,0X00,0X40,0X06,0X62,0X00,0X70,0X3F,0XFB,0X1F,0XCC,
0XFF,0XFF,0X7F,0XE0,0XFF,0XF8,0X1F,0XF0,0XFF,0XE0,0X7F,0XF0,0XFF,0X80,0XFF,0XC0,
0XCF,0X00,0XCE,0X00,0XC3,0X00,0XC7,0X00,0XF0,0X00,0XC3,0X00,0XFC,0X00,0XC0,0X00,
0XCC,0X00,0XE0,0X00,0XC0,0X00,0X73,0X00,0XC0,0X01,0XFF,0X00,0XC0,0X07,0XFE,0X03,
0XF0,0X1F,0XF8,0X0F,0XFC,0X7F,0XFE,0X3F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
};

void main()
{
 const uchar data0[]="山东轻工业学院" ;
 const uchar data1[]="欢迎你!" ;
    const uchar *data2="Waiting...." ;
 const uchar *temp ;
 uchar i ,j;
 init_all() ;

// str_disp("Waiting.......",0,2) ;
 for(j=0;j<2;j++)
 {
  i=1 ;
  send_cmd(0x8A) ;
  temp=data2 ;
  while(*temp!='/0')
  {
   send_byte(*temp++) ;
   DelayMs(50) ;
  }
  DelayMs(500) ;
  DelayMs(500) ;
  clr_ram() ;
  DelayMs(10) ;
 }
 clr_ram() ;
 DelayMs(100) ;
 chn_disp("山东轻工业学院",0,0,7) ;
 chn_disp(data1,2,1,4) ;
// chn_disp("下一步",5,3,3) ;
 str_disp("NEXT",5,3) ;
 while(1)
 {
  locate_xy(5,3) ;
  send_cmd(0x0E) ;
  DelayUs(50) ;
  locate_xy(6,3) ;
  send_cmd(0x0E) ;
  DelayUs(50) ;
 }
 while(1)   
 {
  ;
 }
}

 

抱歉!评论已关闭.