單片機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
?? 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
? 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
評論
查看更多