12864.h #ifndef __12864_H__ #define __12864_H__ #include<reg52.h> #include <intrins.h> /*************************************** 利用I/O口模擬點陣液晶所需時序 點陣液晶控制端口定義,需根據硬件適當改變 ****************************************/ sbit LCD_RS = P2^0;//控制端口定義 sbit LCD_RW = P2^1; sbit LCD_E = P2^2; sbit LCD_CSA = P2^3;//H選通,即高電平有效 sbit LCD_CSB = P2^4; #define LCD_Data P0//LCD數據端口8位 #define R 1 #define L 2 /***************************************** 函數聲明 *****************************************/ void ReadStatusLCD(unsigned char select);//從LCD讀出忙標志位 unsigned char ReadDataLCD(unsigned char select);//從LCD讀出數據 void WriteDataLCD(unsigned char WDLCD,unsigned char select);//向LED寫入數據 void WriteCommandLCD(unsigned char WCLCD , unsigned char BusyC,unsigned char select);//向LCD寫入命令 void LcdReset(void) ;//初始化函數,完成液晶模塊的初始設置 void clear_LCD(unsigned char select);//清屏函數 void Clr_All_Lcd(void);//全清屏函數 void set_XY(unsigned char Column,unsigned char Page);//設置數據寫入或讀出的地址,通過頁號和列數可以唯一確定一個地址 void xy_Write(unsigned char Column,unsigned char Page,unsigned char dataW);//向指定行列寫數據 void LcmPutDots(unsigned char Column,unsigned char Page, unsigned char DotByte );//顯示點 void whiteword(unsigned char Column,unsigned char Page, const unsigned char puts[][16] );//顯示16×16點陣的編碼 void WhiteWord_Com(unsigned char Column,unsigned char Page,unsigned char C_num, unsigned char V_num, unsigned char * puts );//通用的顯示函數 void Drawing_dot(unsigned char x,unsigned char y); void Drawing_line_vertical(unsigned x); #endif 12864.c /**************************************************** LCD12864點陣液晶屏, 通過I/O口直接控制,采用模擬時序控制 ****************************************************/ #include"12864.h" #include<math.h> /*********************************************************** 功能:從LCD讀取狀態位 變量:select用于選擇LCD屏的左右,1選擇左屏,2選擇右屏 ***********************************************************/ void ReadStatusLCD(unsigned char select) { switch(select) { case 1:{LCD_CSA=1;LCD_CSB=0;break;}//左 case 2:{LCD_CSA=0;LCD_CSB=1;break;}//右 default: break; } LCD_Data = 0xff;//置位輸入口,已實現輸入 LCD_RS=0;LCD_RW=1;LCD_E=1;//高電平讀取數據 //_nop_(); //若晶振速度高,可在此作延時處理 while(LCD_Data&0x80);//最高位為忙標志,檢測忙信號狀態 LCD_E=0; //_nop_(); //若晶振速度高,可在此作延時處理 } /*********************************************************** 功能:從LCD讀取數據 變量:select用于選擇LCD屏的左右,1選擇左屏,2選擇右屏 ***********************************************************/ unsigned char ReadDataLCD(unsigned char select) { unsigned char dataR; LCD_Data = 0xff;//置位輸入口,已實現輸入 switch(select) { case 1:{LCD_CSA=1;LCD_CSB=0;break;}//左 case 2:{LCD_CSA=0;LCD_CSB=1;break;}//右 default: break; } LCD_RW=1;LCD_RS=1;LCD_E = 1;// 操作允許脈沖信號,高電平讀出 //_nop_(); //若晶振速度高,可在此作延時處理 dataR = LCD_Data; LCD_E= 0; return dataR; } /*********************************************************** 功能: 向LCD寫入數據 參數: WDLCD待寫入的字符數據 select用于選擇LCD屏的左右,1選擇左屏,2選擇右屏 ***********************************************************/ void WriteDataLCD(unsigned char WDLCD,unsigned char select) { switch(select) { case 1:{LCD_CSA=1;LCD_CSB=0;break;}//左 case 2:{LCD_CSA=0;LCD_CSB=1;break;}//右 default: break; } ReadStatusLCD(select);//檢測忙標志 LCD_RS = 1;LCD_RW = 0; LCD_Data = WDLCD; LCD_E = 1; //_nop_(); //若晶振速度高,可在此作延時處理 LCD_E = 0; //下降沿寫入數據 //_nop_(); //若晶振速度高,可在此作延時處理 } /*********************************************************** 功能:向LCD寫入命令 參數: WDLCD待寫入的字符數據 BusyC是否要檢查忙標志位選擇標志,1為進行,0為不檢測 select用于選擇LCD屏的左右,1選擇左屏,2選擇右屏 ***********************************************************/ void WriteCommandLCD(unsigned char WCLCD , unsigned char BusyC,unsigned char select) { if(BusyC) ReadStatusLCD(select);//根據需要檢測忙 switch(select) { case 1:{LCD_CSA=1;LCD_CSB=0;break;}//左 case 2:{LCD_CSA=0;LCD_CSB=1;break;}//右 default: break; } LCD_Data = WCLCD; LCD_RS = 0;LCD_RW = 0;LCD_E = 1; //_nop_(); //若晶振速度高,可在此作延時處理 LCD_E = 0; } /****************************************************************************** 功能:清顯示RAM區(清屏) 參數:select為驅動控制器選擇 1為左 2為右 ********************************************************************************/ void clear_LCD(unsigned char select) { unsigned char i,j; for(i=0;i<8;i++) { //8頁,換頁清零 WriteCommandLCD( 0xb8|i,1 ,select);//頁面地址設置,并分別寫入左右模塊中 WriteCommandLCD( 0x40,1 ,select);//列地址設置,設置為0列,并分別寫入左右三個模塊中 for(j=0;j<64;j++) { //頁內清零 WriteDataLCD( 0 ,select); } } } /***************************************************************************** 功能:清LCD左右屏 *****************************************************************************/ void Clr_All_Lcd(void) { clear_LCD(1); clear_LCD(2); } /****************************************************************************** 功能:LCD初始化,分為左,右模塊初始化 參數:select為驅動控制器選擇 1為左 2為右 ********************************************************************************/ void LcdReset(void) { unsigned char i; for(i=0;i<5;i++) { WriteCommandLCD( 0xc0,0 ,R);//設置顯示起始行為第一行,并分別寫入左右模塊中,不檢測忙標志 WriteCommandLCD( 0xc0,0 ,L); //_nop_(); //若晶振速度高,可在此作延時處理 } WriteCommandLCD( 0xc0,1 ,R);//設置顯示起始行為第一行,并分別寫入左右模塊中,檢測忙標志 WriteCommandLCD( 0xc0,1 ,L); WriteCommandLCD( 0x3f,1 ,R);//開顯示設置,并分別寫入左右模塊中 WriteCommandLCD( 0x3f,1 ,L); clear_LCD(R);//清左屏 clear_LCD(L);//清右屏 } /****************************************************************************** 功能:設置數據寫入或讀出的地址,通過頁號和列數可以唯一確定一個地址 參數:Column表示列號,Page表示頁號 ********************************************************************************/ void set_XY(unsigned char Column,unsigned char Page) { unsigned char x,y; unsigned char select; switch (Column&0x40) //完成左右屏的判斷 ,根據列號完成區分,<64為左屏,>=64為右屏 { case 0x00: {select = 1;ReadStatusLCD(select);break;}/*為左區 */ case 0x40: {select = 2;ReadStatusLCD(select);break;}/*為右區 */ } x = Column&0x3F|0x40; /* col.and.0x3f.or.Set Y Address*/ y = Page&0x07|0xB8; /* row.and.0x07.or.set Page */ WriteCommandLCD( y,1 ,select);//設置頁面地址 WriteCommandLCD( x,1 ,select);//設置列地址 } /****************************************************************************** 功能:根據地址值(頁數和列號),寫入數據,即寫入顯示緩沖區,便可以顯示在LCD屏上 參數:Column表示列號,Page表示頁號,dataW表示待寫入的數據 ********************************************************************************/ void xy_Write(unsigned char Column,unsigned char Page,unsigned char dataW) { set_XY(Column,Page); LCD_RW=0; LCD_RS=1; _nop_();//若晶振速度高,可在此作延時處理 LCD_Data = dataW;// 送數據 _nop_(); //若晶振速度高,可在此作延時處理 LCD_E = 1; _nop_(); //若晶振速度高,可在此作延時處理 LCD_E= 0; // 操作允許脈沖信號,下降沿寫入 } /****************************************************************************** 功能: 用于顯示點陣 參數:Column表示列號,Page表示頁號, ********************************************************************************/ void LcmPutDots(unsigned char Column,unsigned char Page, unsigned char DotByte ) { unsigned char i; i=Column; for(;Page<8;Page++) { for(;Column<128;Column++) { xy_Write(Column,Page,DotByte); //DotByte = ~DotByte; } Column=i; } } /****************************************************************************** 功能:在指定列,指定頁顯示待顯示的點陣編碼,用于顯示16*16點陣碼 參數:Column表示列號,Page表示頁號,puts待顯示的點陣編碼首指針 ********************************************************************************/ void whiteword(unsigned char Column,unsigned char Page, const unsigned char puts[][16] ) { unsigned char i,j; for(i=0;i<2;i++)//此處的2為控制點陣行數,實際點陣行數為2*8=16行,此處的16(對應的點行數)應為8的倍數 { for(j=0;j<16;j++)//此處控制每行顯示的列數 { xy_Write(Column+j,Page+i,puts[i][j]); } } } /****************************************************************************** 功能:在指定列,指定頁顯示待顯示指定點陣的編碼 參數:Column表示列號,Page表示頁號,C_num為顯示點陣的行數(物理行 8的倍數),V_num為列(物理列)puts待顯示的點陣編碼首指針 ********************************************************************************/ void WhiteWord_Com(unsigned char Column,unsigned char Page,unsigned char C_num,unsigned char V_num, unsigned char * puts) { unsigned char i,j; for(i=0;i<(C_num/8);i++)//此處的2為控制點陣行數,實際點陣行數為2*8=16行,此處的16(對應的點行數)應為8的倍數 { for(j=0;j<V_num;j++)//此處控制每行顯示的列數 { xy_Write(Column+j,Page+i,*(puts+i*V_num+j));//注意地址的變化規律 } } } /****************************************************************************** 功能:繪點 參數:Column表示列號,Page表示頁號,C_num為顯示點陣的行數(物理行 8的倍數),V_num為列(物理列)puts待顯示的點陣編碼首指針 ********************************************************************************/ void Drawing_dot(unsigned char x,unsigned char y) { unsigned char y_byte,x_bit,y_bit,reverse_y;//此處y_byte為page,y_bit為具體行號,x_bit為行號 unsigned char dot; reverse_y=63-y; x_bit=x; y_byte=reverse_y/8; y_bit=y%8; // for(;x_bit<128;x_bit++) if(y_bit==0) dot=0x80; if(y_bit==1) dot=0x40; if(y_bit==2) dot=0x20; if(y_bit==3) dot=0x10; if(y_bit==4) dot=0x08; if(y_bit==5) dot=0x04; if(y_bit==6) dot=0x02; if(y_bit==7) dot=0x01; xy_Write(x_bit,y_byte,dot); /* reverse_y=64-y; if(y_bit==7) y_byte=y_byte-1; y_bit=y%8; if(y_byte==(-1)) break;*/ } /****************************************************************************** 功能:繪垂直直線 參數:x表示列號 ********************************************************************************/ void Drawing_line_vertical(unsigned char x) { xy_Write(x,0,0xff); xy_Write(x,1,0xff); xy_Write(x,2,0xff); xy_Write(x,3,0xff); xy_Write(x,4,0xff); xy_Write(x,5,0xff); xy_Write(x,6,0xff); xy_Write(x,7,0xff); } 主程序.c /********************************************************************************************** 12864液晶屏上顯示"南京絕妙科技發展有限公司,025-84532868 開發板歡迎使用","0~9",刷新后重顯。 *************************************************************************************************/ #include<reg52.h> #include<math.h> #include"12864.h" #include"zifulib.h" #define uint unsigned int #define uchar unsigned char sbit adrd=P3^7; //IO口定義 sbit adwr=P3^6; sbit cs=P2^5; unsigned adval; /*********************************************************** 功能:延時程序 入口參數: 日期: ***********************************************************/ void DelayMs(unsigned char count) { unsigned int temp; while(count--) { for(temp=5000;temp;temp--) ; } } void adc() // 主程序 { //********************* 啟動adc0804 **********************// adrd=1; cs=0; adwr=1; adwr=0; _nop_(); adwr=1; //********************* 讀取adc0804 **********************// DelayMs(1); cs=0; adrd=0; //重新打開有AD片選信號鎖存器的鎖存端 adval=P1; //同時把AD的值送八個發光二極顯示 } /************************************* 顯示公司名稱,電話等信息 *************************************/ /*void Dis_Information(void) { whiteword(16,0,nan);//南 whiteword(32,0,jing);//京 whiteword(48,0,jue);//絕 whiteword(64,0,miao);//妙 whiteword(80,0,ke);//科 whiteword(96,0,ji);//技 whiteword(16,2,fa);//發 whiteword(32,2,zhan);//展 whiteword(48,2,you);//有 whiteword(64,2,xian);//限 whiteword(80,2,gong);//公 whiteword(96,2,si);//司 WhiteWord_Com(16,4,16,8,shuzi[0]);//0 WhiteWord_Com(24,4,16,8,shuzi[2]);//2 WhiteWord_Com(32,4,16,8,shuzi[5]);//5 //WhiteWord_Com(40,4,16,8,heng);//- WhiteWord_Com(48,4,16,8,shuzi[8]);//8 WhiteWord_Com(56,4,16,8,shuzi[4]);//4 WhiteWord_Com(64,4,16,8,shuzi[5]);//5 WhiteWord_Com(72,4,16,8,shuzi[3]);//3 WhiteWord_Com(80,4,16,8,shuzi[2]);//2 WhiteWord_Com(86,4,16,8,shuzi[8]);//8 WhiteWord_Com(92,4,16,8,shuzi[6]);//6 WhiteWord_Com(100,4,16,8,shuzi[8]);//8 whiteword(16,6,kai);//開 whiteword(32,6,fa);//發 whiteword(48,6,ban);//板 whiteword(64,6,huan);//歡 whiteword(80,6,ying);//迎 whiteword(96,6,shi);//使 whiteword(112,6,yong);//用 } */ /************************************** 主函數 ***************************************/ void main(void) { unsigned char x,i,k;//x繪圖坐標 xdata unsigned char y[128];//每個x對應的y坐標 float x_float; //unsigned x_move;//圖像向右移動 //unsigned char i,j; //DelayMs(1);//如果上電速度過快,可做適當延時,以等待LCD完成復位 LcdReset(); //DelayMs(1);//可做適當延時,以等待LCD初始化完成 whiteword(48,0,xin); whiteword(64,0,dian); whiteword(80,0,tu); whiteword(96,0,yi); DelayMs(50); while(1) { for(k=0;k<128;k++) { x_float=2*3.14*k/32; y[0]=sin(x_float);//畫出sin正弦波形 for(i=128;i>0;i--)//實現波形的移動 { y[i]=y[i-1]; } Clr_All_Lcd(); for(x=0;x<128;x++) { Drawing_dot(x,20+y[x]); } } // adc(); //y=adval/2; /*LcmPutDots(15,2, 0xff);// DelayMs(50); Clr_All_Lcd(); Dis_Information();//顯示公司信息 DelayMs(100); Clr_All_Lcd(); for(j=0;j<4;j++) { for(i=0;i<10;i++) { WhiteWord_Com((i+j)*8+j,j*2,16,8,shuzi[i]); } DelayMs(10); Clr_All_Lcd(); } DelayMs(10); Clr_All_Lcd();*/ } } 字庫文件.h #ifndef __ZIFULIB_H__ #define __ZIFULIB_H__ /**************************************************** *****************************************************/ //******心 code unsigned char xin[2][16]={ 0x00,0x00,0x80,0x00,0x00,0xE0,0x02,0x04,0x18,0x00,0x00,0x00,0x40,0x80,0x00,0x00, 0x10,0x0C,0x03,0x00,0x00,0x3F,0x40,0x40,0x40,0x40,0x40,0x78,0x00,0x01,0x0E,0x00 }; //******電 code unsigned char dian[2][16]={ 0x00,0x00,0xF8,0x88,0x88,0x88,0x88,0xFF,0x88,0x88,0x88,0x88,0xF8,0x00,0x00,0x00, 0x00,0x00,0x1F,0x08,0x08,0x08,0x08,0x7F,0x88,0x88,0x88,0x88,0x9F,0x80,0xF0,0x00 }; //******圖 code unsigned char tu[2][16]={ 0x00,0xFE,0x02,0x42,0x22,0x32,0x5E,0x92,0x52,0x32,0x12,0x02,0x02,0xFE,0x00,0x00, 0x00,0xFF,0x42,0x42,0x42,0x51,0x55,0x64,0x69,0x41,0x42,0x42,0x42,0xFF,0x00,0x00 }; //******儀 code unsigned char yi[2][16]={ 0x00,0x80,0x60,0xF8,0x07,0x00,0x1C,0xE0,0x01,0x06,0x00,0xE0,0x1E,0x00,0x00,0x00, 0x01,0x00,0x00,0xFF,0x00,0x80,0x40,0x20,0x13,0x0C,0x13,0x20,0x40,0x80,0x80,0x00 }; /*************************** 阿拉伯數字 ***************************/ code unsigned char shuzi[10][16]={ /*-- 文字: 0 --*/ /*-- 楷體_GB231212; 此字體下對應的點陣為:寬x高=8x16 --*/ 0x00,0x00,0xF0,0x08,0x08,0x18,0xE0,0x00,0x00,0x00,0x0F,0x10,0x20,0x10,0x0F,0x00, /*-- 文字: 1 --*/ /*-- 楷體_GB231212; 此字體下對應的點陣為:寬x高=8x16 --*/ 0x00,0x00,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x10,0x00,0x00,0x00, /*-- 文字: 2 --*/ /*-- 楷體_GB231212; 此字體下對應的點陣為:寬x高=8x16 --*/ 0x00,0x30,0x08,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x18,0x14,0x13,0x10,0x08,0x00, /*-- 文字: 3 --*/ /*-- 楷體_GB231212; 此字體下對應的點陣為:寬x高=8x16 --*/ 0x00,0x00,0x10,0x08,0x88,0x78,0x00,0x00,0x00,0x00,0x10,0x20,0x20,0x11,0x0E,0x00, /*-- 文字: 4 --*/ /*-- 楷體_GB231212; 此字體下對應的點陣為:寬x高=8x16 --*/ 0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x03,0x02,0x02,0x02,0x1F,0x02,0x00, /*-- 文字: 5 --*/ /*-- 楷體_GB231212; 此字體下對應的點陣為:寬x高=8x16 --*/ 0x00,0x00,0x70,0x48,0xC8,0x88,0x00,0x00,0x00,0x10,0x10,0x20,0x10,0x0F,0x00,0x00, /*-- 文字: 6 --*/ /*-- 楷體_GB231212; 此字體下對應的點陣為:寬x高=8x16 --*/ 0x00,0x00,0xE0,0x90,0x88,0x80,0x00,0x00,0x00,0x07,0x18,0x20,0x20,0x19,0x06,0x00, /*-- 文字: 7 --*/ /*-- 楷體_GB231212; 此字體下對應的點陣為:寬x高=8x16 --*/ 0x00,0x10,0x08,0x08,0x88,0x78,0x00,0x00,0x00,0x00,0x00,0x18,0x07,0x00,0x00,0x00, /*-- 文字: 8 --*/ /*-- 楷體_GB231212; 此字體下對應的點陣為:寬x高=8x16 --*/ 0x00,0x00,0x78,0x88,0x88,0x78,0x00,0x00,0x00,0x0C,0x12,0x21,0x21,0x1E,0x00,0x00, /*-- 文字: 9 --*/ /*-- 楷體_GB231212; 此字體下對應的點陣為:寬x高=8x16 --*/ 0x00,0x60,0x98,0x08,0x08,0xF8,0xC0,0x00,0x00,0x00,0x21,0x12,0x09,0x07,0x00,0x00 }; #endif |