您现在的位置是:首页 > 单片机

单片机12864 c程序

2020-01-24 02:15:10

单片机12864 c程序-MSP430与12864连接驱动程序(KS0108)

#i nclude "MSP430x14x.h" // Standard EquaTIons
#i nclude "math.h"
#i nclude "stdlib.h"
#i nclude "stdio.h"
#i nclude "string.h"
#i nclude "ctype.h"
#i nclude "HZTable.h"
#i nclude "ASCII816.h"
#define uint unsigned int
#define uchar unsigned char
//**********************************************
#define RS BIT0
#define RW BIT1
#define E BIT2
#define CS1 BIT3
#define CS2 BIT4
#define RST BIT5
#define EL BIT6 //背光
//数据线:p4口 ,控制线: p5口
//**********************************************
uchar cradd1,cradd2;
uchar item1[5]={0,1,2,3,50}; //欢迎使用
uchar item2[5]={4,5,6,7,50}; //请等待……

//=======================================================
void short_delay(uint i)
{ uint j;
for(j=0;j<=i;j++);
}
void delayms(uchar TIckms)
{ uchar count,i;
_NOP();
_NOP();
_NOP();

for(i=TIckms;i>0;i--)
{ for(count=0;count<=58;count++) {;}
_NOP();
}
}
//**************************************************
void prl0(uchar com1)// 写指令代码子程序(左)
{
P5DIR|=0X7F; //P5为输出口
P5OUT|=CS1; //csa=1 
P5OUT&=~CS2; //csb=0
P5OUT&=~RS; 
P5OUT|=RW; //RS=0,R/W=1,以便读液晶状态
P4DIR=0x00; //P4口为输入口
do
{
P5OUT|=E; //E=1
cradd1=P4IN;
P5OUT&=~E; //E=0 
}
while((cradd1&0x80)!=0);
P5OUT&=~RW; //rw=0
P4DIR=0xff; //P4口为输出口
P4OUT=com1;
P5OUT|=E; //E=1
P5OUT&=~E; //E=0 
}
//**************************************************
void prl1(uchar dat1)// 写显示数据子程序(左)

P5DIR|=0X7F; //P5为输出口
P5OUT|=CS1; //csa=1 
P5OUT&=~CS2; //csb=0
P5OUT&=~RS; 
P5OUT|=RW; //RS=0,R/W=1,以便读液晶状态
P4DIR=0x00; //P4口为输入口
do
{
P5OUT|=E; //E=1
cradd1=P4IN;
P5OUT&=~E; //E=0 
}
while((cradd1&0x80)!=0);
P5OUT|=RS; //rs=1 
P5OUT&=~RW; //rw=0
P4DIR=0xff; //P4口为输出口
P4OUT=dat1;
P5OUT|=E; //E=1
P5OUT&=~E; //E=0 
}
//**************************************************
void prr0(uchar com2)// 写指令代码子程序(右)
{
P5DIR|=0X7F; //P5为输出口
P5OUT&=~CS1; //csa=0 
P5OUT|=CS2; //csb=1
P5OUT&=~RS; 
P5OUT|=RW; //RS=0,R/W=1,以便读液晶状态
P4DIR=0x00; //P4口为输入口
do
{
P5OUT|=E; //E=1
cradd1=P4IN;
P5OUT&=~E; //E=0 
}
while((cradd1&0x80)!=0);
P5OUT&=~RW; //rw=0
P4DIR=0xff; //P4口为输出口
P4OUT=com2;
P5OUT|=E; //E=1
P5OUT&=~E; //E=0 
}
//*************************************************
void prr1(uchar dat2)// 写显示数据子程序(右)
{
P5DIR|=0X7F; //P5为输出口
P5OUT&=~CS1; //csa=0 
P5OUT|=CS2; //csb=1
P5OUT&=~RS; 
P5OUT|=RW; //RS=0,R/W=1,以便读液晶状态
P4DIR=0x00; //P4口为输入口
do
{
P5OUT|=E; //E=1
cradd1=P4IN;
P5OUT&=~E; //E=0 
}
while((cradd1&0x80)!=0);
P5OUT|=RS; //rs=1 
P5OUT&=~RW; //rw=0
P4DIR=0xff; //P4口为输出口
P4OUT=dat2;
P5OUT|=E; //E=1
P5OUT&=~E; //E=0 
}
//****************************************************
//读显示数据子程序 (左屏)
//****************************************************
uchar ReadDatal(void)
{
uchar Rdata;
P5DIR|=0X7F; //P5为输出口
P5OUT|=CS1; //csa=1 
P5OUT&=~CS2; //csb=0
P5OUT&=~RS; 
P5OUT|=RW; //RS=0,R/W=1,以便读液晶状态
P4DIR=0x00; //P4口为输入口
do
{
P5OUT|=E; //E=1
cradd1=P4IN;
P5OUT&=~E; //E=0 
}
while((cradd1&0x80)!=0);

P5OUT|=RS; //RS=1
//P5OUT|=RW; //R/W=1
P5OUT|=E; //E=1
Rdata=P4IN;
P5OUT&=~E; //E=0 
return Rdata; 
}
//****************************************************
//读显示数据子程序 (右屏)
//****************************************************
uchar ReadDatar(void)
{
uchar Rdata;
P5DIR|=0X7F; //P5为输出口
P5OUT&=~CS1; //csa=0 
P5OUT|=CS2; //csb=1
P5OUT&=~RS; 
P5OUT|=RW; //RS=0,R/W=1,以便读液晶状态
P4DIR=0x00; //P4口为输入口
do
{
P5OUT|=E; //E=1
cradd1=P4IN;
P5OUT&=~E; //E=0 
}
while((cradd1&0x80)!=0);

P5OUT|=RS; //RS=1
//P5OUT|=RW; //R/W=1
P5OUT|=E; //E=1
Rdata=P4IN;
P5OUT&=~E; //E=0 
return Rdata; 
}
//**********************************************
//**********************************************
void clsr(void) //清屏 
{ uchar i,j;
for(i=0;i<8;i++)
{ prl0(i|0xb8); //设置页地址
prr0(i|0xb8);
prl0(0x40);
prr0(0x40);
for(j=0;j<64;j++) //设置列地址
{ prl1(0x00); //写0x00
prr1(0x00);
}
}
}
//**********************************************
void allon(void) //满屏
{ uchar i,j;
for(i=0;i<8;i++)
{ prl0(i|0xb8);
prr0(i|0xb8);
prl0(0x40);
prr0(0x40);
for(j=0;j<64;j++)
{ prl1(0xff); //写0xff
prr1(0xff);
}
}
}
//***********************************************
void stripe(void)
{ uchar i,j;
for(i=0;i<8;i++)
{ prl0(i|0xb8);
prr0(i|0xb8);
prl0(0x40);
prr0(0x40);
for(j=0;j<64;j++)
{ prl1(0xaa);
prr1(0xaa); // 写0xaa
}
}
}
//***********************************************
void stripe1(void)
{ uchar i,j;
for(i=0;i<8;i++)
{ prl0(i|0xb8);
prr0(i|0xb8);
prl0(0x40);
prr0(0x40);
for(j=0;j<64;j++)
{ prl1(0x55); // 写0x55
prr1(0x55);
}
}
}

//***************************************************

//***************************************************
void hzw_pr(uchar colum2,uchar page2,uchar code2)// 写汉字
//page2:页 colum2:列 code2:代码 code2=0,1,2,3……表示第几个汉字
{ uchar i,j,colum;
uchar *hzp; 

uchar flag;
hzp=&HZTable[code2][0];
for(j=0;j<2;j++)
{ prl0(page2|0xb8); //页
prr0(page2|0xb8);
colum=colum2;
if(colum2>63) //右屏
{ colum=colum-64;
prr0(colum|0x40); 
flag=1;
}
else //左屏
{prl0(colum|0x40);
flag=0;
}
//*********************
for(i=0;i<16;i++)
{
if(flag==0)
{
prl1(*hzp);
}
else
{prr1(*hzp);}
hzp++;
if(colum==64) //列=64
{
colum=0;
if(flag==0)
{
flag=1;
prr0(colum|0x40);
}
else{break;}
}
colum++;
}
page2++;
}
}
//***********************************************
void w_hzstr(uchar colum4,uchar page4,uchar *str1)// 写汉字字符串 
{
while(*str1!=50)
{
hzw_pr( colum4, page4,*str1) ;
colum4=colum4+16;
str1++;
}
}
//***************************************************
//init_xt2; 初始化XT2 晶振为4MHZ
//*****************************************************
void init_xt2(void)
{
unsigned int iq0;

//使用XT2振荡器
BCSCTL1&=~XT2OFF; //打开XT2振荡器
do
{
IFG1 &= ~OFIFG; // 清除振荡器失效标志
for (iq0 = 0xFF; iq0 > 0; iq0--); // 延时,等待XT2起振
} while ((IFG1 & OFIFG) != 0); // 判断XT2是否起振

BCSCTL2 =SELM_2+SELS; //选择MCLK、SMCLK为XT2,
BCSCTL2 |=DIVM_1; //MCLK 2分频SMCLK=MCLK=2MHZ
}
//***********************************************
//主程序
//***********************************************

void main(void)

uchar a;
// uchar i,j;
WDTCTL=WDTPW+WDTHOLD;
init_xt2();
P5DIR|=0X7F; //P5为输出口
P5OUT&=~RST; //rst=0 
delayms(10); //1ms
P5OUT|=RST; //rst=1
P5OUT&=~EL; //EL=0 背光=0
do

prl0(0xc0);prr0(0xc0); //显示开始行
prl0(0x3f);prr0(0x3f); //开显示
//P5OUT&=~EL; //EL=0 背光=0
//******************************************************
clsr(); // clear screen 
//写汉字字符串1 欢迎使用
//写汉字字符串2 请等待… 
w_hzstr(32,2,item1);w_hzstr(32,5,item2); 
delayms(100); 
for(a=0;a<50;a++)
{ delayms(100);}

prl0(0xc0);prr0(0xc0);


clsr(); 

allon(); // fill screen 

delayms(100);
for(a=0;a<25;a++)
{ delayms(100);}
prl0(0xc0);prr0(0xc0);
clsr(); // clear screen 
delayms(100);
for(a=0;a<25;a++)
{ delayms(100);}


/* stripe screen */
prl0(0xc0);prr0(0xc0);
stripe();
delayms(100);
for(a=0;a<20;a++)
{ delayms(100);}
prl0(0xc0);prr0(0xc0);
stripe1();
delayms(100);
for(a=0;a<50;a++)
{ delayms(100);}

    }while(1);
}

12864液晶控制程序

//注意字符或图片取模方式为字节倒序,纵向取模

//字模精灵下载

//2005.6.修改了部分显示函数,使用时不再用考虑左右屏
#include "lcdriver.h"

//lcdriver.c

void Delay(long v)
{
        while(--v);
}

 

void Write_Command(uchar cmdcode,uchar cs1,uchar cs2) //写命令到LCD
{
 
 CS1=(cs1?1:0);
 CS2=(cs2?1:0);
 
 DI=0;
 RW=0;
 lcd_data_bus=cmdcode;//写命令

 E=0;
 Delay(1);
 E=1;
 E=0;

}

void Write_Data(uchar disp_data,uchar cs1,uchar cs2) //写数据到LCD
{
 CS1=(cs1?1:0);
 CS2=(cs2?1:0);
 
 DI=1;
 RW=0;
 lcd_data_bus=disp_data;//写显示数据

 E=0;
 Delay(1);
 E=1;
 E=0;
}

uchar Read_data(uchar cs1,uchar cs2)//read data from lcd
{
 unsigned char get_data;

 CS1=(cs1?1:0);
 CS2=(cs2?1:0);
 
 DI=1;
 RW=1;

 E=1;
 Delay(1);
 E=0;
 E=1;
 E=0;
 get_data=lcd_data_bus;
 
 return get_data;

}

void Lcd_Init()   //初始化LCD屏
{
 
 RST=0;  //复位  如是上电复位就不用
 Delay(100);
 RST=1;
 Delay(100);
 Write_Command(Disp_Off,1,1);   //关显示
 Write_Command(Row_Add+0,1,1);
 Write_Command(Start_Line+0,1,1); //设置首行为起始行
 Write_Command(Col_Add+0,1,1);
 Write_Command(Disp_On,1,1);   //开显示
}

void Clr_Screen(void)
{
    uchar row,col;

 for(row=0;row<8;row++)
 {
  for(col=0;col<128;col++)
  {
      lcd_row_col_data(row,col,0x00);
  }
 }
}
/*
void Full_Screen(void)
{
    uchar row,col;

 for(row=0;row<8;row++)
 {
  for(col=0;col<128;col++)
  {
      lcd_row_col_data(row,col,0xFF);
  }
 }
}
*/
uchar read_lcd_data(uchar row,uchar col)//新增函数 从lcd读取数据
{
 uchar get_data;
 Write_Command(Row_Add+row,1,1);
 if(col<64)
 { 
  Write_Command(Col_Add+col,1,0);
  get_data=Read_Data(1,0);
 }
 else
 {
  Write_Command(Col_Add+col-64,0,1);
  get_data=Read_Data(0,1);
 }
 return get_data;    
}

void lcd_dot_disp(uchar x,uchar y)//新增函数 以点形式显示x 0-127; y 0-63  左下角为坐标原点
{
 uchar byte_dot[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
 
 if(((x==127)&&(y==0))||(x==126)&&(y==0)||(x==125)&&(y==0)||(x==124)&&(y==0)) //避免显示小图标
  return;
                              
 Write_Command(Start_Line,1,1);
 
 if(y<8)
 {
  lcd_row_col_data(7,x,byte_dot[y]);
  return;
 }
 else if(y<16)
 {
  lcd_row_col_data(6,x,byte_dot[y-8]);
  return;
 }
 else if(y<24)
 {
  lcd_row_col_data(5,x,byte_dot[y-16]);
  return;
 }
 else if(y<32)
 {
  lcd_row_col_data(4,x,byte_dot[y-24]);
  return;
 }
 else if(y<40)
 {
  lcd_row_col_data(3,x,byte_dot[y-32]);
  return;
 }
 else if(y<48)
 {
  lcd_row_col_data(2,x,byte_dot[y-40]);
  return;
 }
 else if(y<56)
 {
  lcd_row_col_data(1,x,byte_dot[y-48]);
  return;
 }
 else if(y<64)
 {
  lcd_row_col_data(0,x,byte_dot[y-56]);
  return;
 }
}

void lcd_row_col_data(uchar row,uchar col,uchar disp_data)//新增函数2005.6 以字节形式显示
{
 Write_Command(Row_Add+row,1,1);
 if(col<64)
 {
  Write_Command(Col_Add+col,1,0);
  Write_Data(disp_data,1,0);
 }
 else
 {
  Write_Command(Col_Add+col-64,0,1);
  Write_Data(disp_data,0,1);
 }   
}

void signal_disp(uchar t,uchar on_off)   //右上角标志显示
{

  Write_Command(Row_Add+8,0,1);
  Write_Command(Col_Add+59+t,0,1);
  Write_Data(on_off?0x80:0x00,0,1);
  
}

void Ch_Display(uchar row, uchar col, uchar const *ch_data,uchar w,uchar dir) //--指定位置显示字符w*16-////////row*col /////////////max=8*128//2005.6精简
{
 uchar j,i=0;
 for(j=0;j<2;j++)
 {
  for(i=0;i<w;i++)
  {      
   if(dir==1)
    lcd_row_col_data(j+row,col+i,~ch_data[2*i+j]);//反显
   else
    lcd_row_col_data(j+row,col+i,ch_data[2*i+j]);//正显
  } 
 }
}

void Ch_Display_8(uchar row, uchar col, uchar const *ch_data,uchar w,uchar dir) //--指定置显示字符///////////

////////w*8---------row*col max=8*128//2005.6精简
{
 uchar i=0;
 
 for(i=0;i<w;i++)
 {      
  if(dir==1)
   lcd_row_col_data(row,col+i,~ch_data[2*i]);//反显
  else
   lcd_row_col_data(row,col+i,ch_data[2*i]);//正显
 } 

}


void Bmp_display(uchar const *bmp)//2005.6精简 //显示128*64位图
{
 uchar j,k;
 
 Write_Command(Start_Line,1,1);
 
 for(k=0;k<8;k++)
 {  
  for(j=0;j<128;j++)
   lcd_row_col_data(k,j,bmp[8*j+k]);  
 }
}

//以下程序待检测(430单片机上可以用 )
/*
void Fun_display(uchar const *bmp) //动画效果--右移
{
 char j,k,x=64;
  
 while(x--)
 {

  Write_Command(Row_Add,1,1);
  Write_Command(Col_Add,1,1);
  for(k=0;k<8;k++)
  {
  
   Write_Command(Row_Add+k,1,0); //先写左屏
   for(j=0;j<64;j++)
   {
    if(8*j+k+8*(x-1)>1023)// 先要判断是否超出128*64的范围
      Write_Data(0x00,1,0);//
    else
     Write_Data(bmp[8*j+k+8*(x-1)],1,0);
   }
  
  
   Write_Command(Row_Add+k,0,1);  //写右屏
   for(j=0;j<64;j++)
   {
    if((8*j+k+512+8*(x-1))>1023) //先要判断是否超出128*64的范围 
            Write_Data(0x00,0,1);
    else
     Write_Data(bmp[8*j+k+512+8*(x-1)],0,1);
  
   }   
  }
 }
}

void Fun2_display(uchar const *bmp)  //动画--下移--
{
 char j,k,x=63;
 
 while(x--)
 {
  Write_Command(Col_Add,1,1);
  for(k=7;k>=0;k--)
  {
   Write_Command(Row_Add+k,1,0);
   for(j=0;j<64;j++)
   {
    if(8*j+k+x>1023)
      Write_Data(0x00,1,0);// 先要判断是否超出128*64的范围
    else
     Write_Data(bmp[8*j+k+x],1,0);
   }

   Write_Command(Row_Add+k,0,1);
   for(j=0;j<64;j++)
   {
    if((8*j+k+512+x)>1023) //先要判断是否超出128*64的范围 
     Write_Data(0x00,0,1);
    else
     Write_Data(bmp[8*j+k+512+x],0,1);
   }
  }

         Delay(50000);
 }
}

void Fun3_display(uchar const *bmp,uint h)  //动画--上移 该函数实现了显示大于128*64图象的方法,
{           //现在只能实现显示128*h的图象
 char j,k;          //并且h为8的倍数
 uint a, b,c,x;
 x=h-1;
 a=h/8;
 b=128*a-1;
 c=64*a;
 
 while(x--)
 {
  Write_Command(Col_Add,1,1);
  for(k=7;k>=0;k--)
  {
   Write_Command(Row_Add+k,1,0);
   for(j=0;j<64;j++)
   {
    if(a*j+k-x>b)      //x前的系数如为-1则是上移,是+1为下移;
      Write_Data(0x00,1,0);  //先要判断是否超出128*h的范围
    else
     Write_Data(bmp[a*j+k-x],1,0);
   }
   Write_Command(Row_Add+k,0,1);
   for(j=0;j<64;j++)
   {
    if((a*j+k+c-x)>b)     //先要判断是否超出128*h的范围 
     Write_Data(0x00,0,1);
    else
     Write_Data(bmp[a*j+k+c-x],0,1);
   }
  }
  Delay(40000) ;
 }
}

void Fun4_display(uchar const *bmp)
{
 char j,k,x=64;
 
 while(x--)
 {
    Write_Command(Col_Add,1,1);
  for(k=7;k>=0;k--)
  {

   Write_Command(Row_Add+k,1,0);
   for(j=0;j<64;j++)
   {
    if(16*j+k+3*x>2047)
      Write_Data(0x00,1,0);// 先要判断是否超出128*64的范围
    else
     Write_Data(bmp[16*j+k+3*x],1,0);
    }
 
   Write_Command(Row_Add+k,0,1);
   for(j=0;j<64;j++)
   {
    if((16*j+k+1024+3*x)>2047) //先要判断是否超出128*64的范围 
     Write_Data(0x00,0,1);
    else
     Write_Data(bmp[16*j+k+1024+3*x],0,1);
   }
  }

  Delay(10000);
 }
}
*/
//上面程序的.h文件

#ifndef LCDRIVER
#define LCDRIVER
#include "init.h"

/*-----------定义寄存器的指令代码----------*/
#define Disp_On  0x3f
#define Disp_Off 0x3e
#define Col_Add  0x40
#define Row_Add 0xb8
#define Start_Line 0xc0

#define signal1 1
#define signal2 2
#define signal3 3
#define signal4 4

#define ON  1
#define OFF 0

#define lcd_data_bus P2

sbit DI =P3^1;
sbit RW =P3^3;
sbit E =P3^7;
sbit CS1=P3^4;
sbit CS2=P3^5;
sbit RST=P3^0; //复位

void Delay (long v) ;

void Write_Command(uchar cmdcode,uchar cs1,uchar cs2) ;  //写命令到LCD
void Write_Data(uchar Dispdata,uchar cs1,uchar cs2) ;  //写数据到LCD
uchar Read_Data(uchar cs1,uchar cs2);      //read data from lcd
void Lcd_Init(void) ;          //初始化LCD屏
void Clr_Screen(void)  ;         //清屏
//void Full_Screen(void);         //满屏
uchar read_lcd_data(uchar row,uchar col);     //新增函数 读数据从lcd
void lcd_row_col_data(uchar row,uchar col,uchar disp_data); //新增函数 字节形式显示
void signal_disp(uchar t,uchar on_off);      //右上角标志显示
void lcd_dot_disp(uchar x,uchar y);       //新增函数 以点形式显示 x 0-127; y 0-63 左下角为原点
void Ch_Display_8(uchar row, uchar col, uchar const *ch_data,uchar w,uchar dir);//指定位置显示字符w*8
void Ch_Display(uchar row, uchar col, uchar const *ch_data,uchar w,uchar dir); //指定位置显示字符w*16
void Bmp_display(uchar const *bmp);            //显示128*64位图

/*
void Fun_display(uchar const *bmp);            //动画效果-----右移
void Fun2_display(uchar const *bmp);           //动画--下移
void Fun3_display(uchar const *bmp,uint h) ;         //动画--上移//该函数实现了显示大于128*64图象的方法, 现在只能实现显示128*h的图象

void Fun4_display(uchar const *bmp);
*/
#endif