|
单片机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
|