12864液晶顯示屏單片機驅動,單片機型號是合泰HT66F70A
完整代碼下載:
12864驅動1.zip
(41.58 KB, 下載次數(shù): 114)
2016-4-17 17:15 上傳
點擊文件名下載附件
c語言版本的程序:
- #include <HT66F70A.H>
- #include "delay.h"
- #define IO_12864 _pc //定義12864的數(shù)據(jù)端口
- #define IO_12864_C _pcc
-
- #define RS_12864 _pd5 //定義命令數(shù)據(jù)寄存器選擇端
- #define RW_12864 _pd6 //定義定義讀寫控制端
- #define E_12864 _pd7 //定義使能端
- #define RST_12864 _pd4 //定義復位端
- //#define CS2 _pd3
- //#define CS1 _pd2
- void delay_12864(unsigned int ); //延時子函數(shù)原型
- /*void busychk_12864(void); //忙檢測子函數(shù)原型*/
- void wrtcom_12864(unsigned char); //寫命令子函數(shù)原型
- unsigned char reddat_12864(void); //讀數(shù)據(jù)子函數(shù)原型
- void wrtdat_12864(unsigned char); //寫數(shù)據(jù)子函數(shù)原型
- //void choose_12864(unsigned char i); //選屏
- //void drawpic_12864( unsigned char*); //繪圖子函數(shù)原型
- //void drawdot_12864(unsigned char,unsigned char,unsigned char);//畫點子函數(shù)原型
- //void drawrec_12864(unsigned char,unsigned char,unsigned char,unsigned char,unsigned char); //畫矩形子函數(shù)原型
- void clnGDR_12864(void); //清空GDRAM子函數(shù)原型
- void inputchars_12864(unsigned char,unsigned char,unsigned char*);//輸入短字符串子函數(shù)原型
- void scroll_12864(unsigned char*); //輸入長字符串卷動子函數(shù)原型
- void initial_12864(void); //12864初始化子函數(shù)原型
- void main()
- {
- unsigned char uctech[] = {"wweerrtt"};
- _pcc=0;
- _pdc=0;
- //_pcpu=0xff;
- _pc=0;
- _pd=0;
- initial_12864();
- clnGDR_12864();
- inputchars_12864(1,1,uctech);
-
- }
- /*********** 延時子程序,最大延遲時間為65ms***************/
-
- void delay_12864(unsigned int del){
- unsigned int i;
- for(i = 0; i < del; i++){;}
- }
- /***************忙檢測,若忙則等待,最長等待時間為60ms**********/
-
- //
- //void busychk_12864(void){
- //unsigned int timeout = 0;
- //IO_12864_C=1;/////////
- //E_12864 = 0;
- //RS_12864 = 0;
- //RW_12864 = 1;
- //E_12864 = 1;
- //while((IO_12864 & 0x80) && ++timeout != 0); //忙狀態(tài)檢測,等待超時時間為60ms
- //E_12864 = 0;
- //}
- /****************寫命令子程序*********************/
-
-
-
- void wrtcom_12864(unsigned char com){
- //busychk_12864();
- IO_12864_C=0; ///////////////////////////
- delay_12864(5000);////////
- E_12864 = 0;
- RS_12864 = 0;
- RW_12864 = 0;
- E_12864 = 1;
- IO_12864 = com;
- delay_12864(5000); //使能延時50us!!!注意這里,如果是較快的CPU應該延時久一些
- E_12864 = 0;
- }
- /**************************讀數(shù)據(jù)子程序,返回一個字節(jié)的數(shù)據(jù)****************/
-
-
- unsigned char reddat_12864(void){
- unsigned char temp;
- //busychk_12864();
- delay_12864(5000);/////////////
- E_12864 = 0;
- IO_12864_C=0;/////////////////////
- IO_12864 = 0xff; //IO口置高電平,讀引腳
- RS_12864 = 1;
- RW_12864 = 1;
- E_12864 = 1;
- delay_12864(5000); //使能延時50us!!!注意這里,如果是較快的CPU應該延時久一些
- IO_12864_C=1;////////////////////////
- temp = IO_12864;
- return temp;
- }
- /*****************寫數(shù)據(jù)子程序***********************/
-
-
-
- void wrtdat_12864(unsigned char dat){
- //busychk_12864();
- IO_12864_C=0;//////////////////
- delay_12864(5000);/////////////
- E_12864 = 0;
- RS_12864 = 1;
- RW_12864 = 0;
- E_12864 = 1;
- IO_12864 = dat;
- delay_12864(5000); //使能延時50us!!!注意這里,如果是較快的CPU應該延時久一些
- E_12864 = 0;
- }
- /***************選屏****************/
-
-
- //void choose_12864(unsigned char i)//i是要寫的屏.0是左屏,1是右屏,2是雙屏;
- //{ //此處在硬件上運行時i的電平全部與程序相反;
- // switch (i) //此版本為仿真版;
- // {
- // case 0: CS1=0;CS2=1;break; //比如此處如果要在電路上運行則應該改為CS=1;CS2=0;
- // case 1: CS1=1;CS2=0;break;
- // case 2: CS1=0;CS2=0;break;
- // default: break;
- // }
- //}
- /************顯示圖片函數(shù),參數(shù)時圖片的地址,圖片必須是128*64像素的逐行逐行的點陣信息。****************/
-
-
-
- //void drawpic_12864( unsigned char *pPicture ){
- //unsigned char j, k ;
- //wrtcom_12864(0x34); //在寫GDRAM的地址之前一定要打開擴充指令集,否則地址寫不進去!
- //for( j = 0 ; j < 32 ; j++ )
- //{
- //wrtcom_12864(0x80 + j) ; //寫Y 坐標
- //wrtcom_12864(0x80) ; //寫X 坐標
- //for( k = 0 ; k < 16 ; k++ ) //寫一整行數(shù)據(jù)
- //{
- //wrtdat_12864( *pPicture++ );
- //}
- //}
- //for( j = 0 ; j < 32 ; j++ )
- //{
- //wrtcom_12864(0x80 + j) ; //寫Y 坐標
- //wrtcom_12864(0x88) ; //寫X 坐標
- //for( k = 0 ; k < 16 ; k++ ) //寫一整行數(shù)據(jù)
- //{
- //wrtdat_12864( *pPicture++ ) ;
- //}
- //}
- //wrtcom_12864(0x36); //打開繪圖顯示
- //wrtcom_12864(0x30); //返回基本指令集
- //}
- //
- ////畫點函數(shù),左上角為參考點(0,0)
- ////右下角為(127,63),點坐標形式為(行坐標,列坐標)
- ////參數(shù)type用于設置畫黑點、白點或取反(黑變白,白變黑)
- ////type = 0為白色,1 為黑色,2為取反
- ////畫完點不開啟顯示,需要自行開啟繪圖顯示
- //void drawdot_12864(unsigned char y,unsigned char x,unsigned char type){
- //unsigned char X,Y,k; //X存儲行地址,Y存儲列地址,k存儲點在字中的位置(0~15從左至右)
- //unsigned char DH,DL;
- //if(y >= 0 && y <= 63 && x >= 0 && x <= 127) {
- //if(y < 32){ //確定所畫點的地址行與列地址
- //X = 0x80 + (x >> 4);
- //Y = 0x80 + y;
- //}else{
- //X = 0x88 + (x >> 4);
- //Y = 0x80 + (y - 32);
- //}
- //wrtcom_12864(0x34); //開啟擴展指令,關閉繪圖顯示
- //wrtcom_12864(Y); //寫行位地址
- //wrtcom_12864(X); //寫列字地址
- //DH = reddat_12864(); //假讀
- //DH = reddat_12864(); //讀高字節(jié)
- //DL = reddat_12864(); //讀低字節(jié)
- //k = x % 16;
- //switch(type){ //判斷類型,是黑點還是白點還是取反
- //case 0: //畫白點
- // if(k < 8){
- //DH &= ~(0x01 << (7 - k));
- //}else{
- //DL &= ~(0x01 << (7 - (k % 8)));
- //}
- //break;
- //case 1: //畫黑點
- //if(k < 8){
- //DH |= (0x01 << (7 - k));
- //}else{
- //DL |= (0x01 << (7 - (k % 8)));
- //}
- //break;
- //case 2: //對點取反
- //if(k < 8){
- //DH ^= (0x01 << (7 - k));
- //}else{
- //DL ^= (0x01 << (7 - (k % 8)));
- //}
- //break;
- //default:
- //break;
- //}
- //wrtcom_12864(Y); //寫行位地址
- //wrtcom_12864(X); //寫列字地址
- //wrtdat_12864(DH); //回寫高字節(jié)
- //wrtdat_12864(DL); //回寫低字節(jié)
- //
- //wrtcom_12864(0x36); //開啟繪圖顯示
- //wrtcom_12864(0x30); //轉回普通指令
- //}
- //}
- //
- // /**********************畫矩形子函數(shù),參數(shù)為(點1行坐標,點1列坐標,點2行坐標,點2列坐標,*********
- // **********************線條顏色(0為白,1為黑,2對原色取反))*************************************/
- //
- //
- //
- //void drawrec_12864(unsigned char y1,unsigned char x1,unsigned char y2,unsigned char x2,unsigned char type){
- //unsigned char largex,largey,smallx,smally;
- //unsigned char i;
- //if(x1 > x2){
- //largex = x1;
- //smallx = x2;
- //}else{
- //largex = x2;
- //smallx = x1;
- //}
- //if(y1 > y2){
- //largey = y1;
- //smally = y2;
- //}else{
- //largey = y2;
- //smally = y1;
- //}
- ////畫4條矩形邊框
- //for(i = smallx; i < largex; i++){
- //drawdot_12864(largey,i,type);
- //}
- //for(i = largey; i > smally; i--){
- //drawdot_12864(i,largex,type);
- //}
- //for(i = largex; i > smallx; i--){
- //drawdot_12864(smally,i,type);
- //}
- //for(i = smally; i < largey; i++){
- //drawdot_12864(i,smallx,type);
- //}
- //wrtcom_12864(0x30); //返回普通指令
- //}
- /*****************清空GDRAM,往GDRAM內部寫滿0x00*************/
-
-
- void clnGDR_12864(void){
- unsigned char j,k;
- wrtcom_12864(0x34);//在寫GDRAM的地址之前一定要打開擴充指令集,否則地址寫不進去!
- for( j = 0 ; j < 32 ; j++ )
- {
- wrtcom_12864(0x80 + j) ; //寫Y 坐標
- wrtcom_12864(0x80) ; //寫X 坐標
- for( k = 0 ; k < 32 ; k++ ) //寫一整行數(shù)據(jù)
- {
- wrtdat_12864( 0x00 );
- }
- }
- wrtcom_12864(0x30); //返回基本指令集
- }
- /***********************寫入短字符串函數(shù),參數(shù)分別為顯示行(0~3),顯示列(0~7),字符串首地址
- 字符串只會在一行顯示,超過的不顯示**********************************/
-
-
- void inputchars_12864(unsigned char y,unsigned char x,unsigned char *dataaddr){
- unsigned char i,address=0;
- switch (y){ //設置字符顯示起始地址
- case 0: address = 0x80 + x;
- break;
- case 1: address = 0x90 + x;
- break;
- case 2: address = 0x88 + x;
- break;
- case 3: address = 0x98 + x;
- break;
- default: break;
- }
- wrtcom_12864(0x30);
- wrtcom_12864(address);
- for(i = x;i < 8; i++){
- if(*dataaddr != '\0'){
- wrtdat_12864(*dataaddr++);
- }
- }
- }
- /******************長字符串顯示卷屏函數(shù)**************************/
-
-
-
- void scroll_12864(unsigned char *ser){
- //addr存儲地址的中間變量,flag卷屏地址,hang要寫數(shù)據(jù)的行,
- //over寫完字符串后繼續(xù)寫的空字符計數(shù)
- unsigned char i,addr,flag,hang,over,*ptdat;
- ptdat = ser; //獲得字符串首地址
- over = 0; //寫入空字符串(寫完字符串后)數(shù)目初始化為0
- wrtcom_12864(0x80); //寫第一行字符
- for(i = 0; i < 16; i++){
- if(*ptdat != '\0'){
- wrtdat_12864(*ptdat++);
- }else{
- wrtdat_12864(0x20);
- over++;
- }
- }
- wrtcom_12864(0x90); //寫第二行字符
- for(i = 0; i < 16; i++){
- if(*ptdat != '\0'){
- wrtdat_12864(*ptdat++);
- }else{
- wrtdat_12864(0x20);
- over++;
- }
- }
- wrtcom_12864(0x88); //寫第三行字符
- for(i = 0; i < 16; i++){
- if(*ptdat != '\0'){
- wrtdat_12864(*ptdat++);
- }else{
- wrtdat_12864(0x20);
- over++;
- }
- }
- wrtcom_12864(0x98); //寫第四行字符
- for(i = 0; i < 16; i++){
- if(*ptdat != '\0'){
- wrtdat_12864(*ptdat++);
- }else{
- wrtdat_12864(0x20);
- over++;
- }
- }
- ptdat = ptdat - 32;
- wrtcom_12864(0xa0); //寫第三行DDRAM,寫入內容為第三行字符串和第五行字符串
- for(i = 0; i < 16; i++){ //寫第三行字符串
- if(*ptdat != '\0'){
- wrtdat_12864(*ptdat++);
- }else{
- wrtdat_12864(0x20);
- over++;
- }
- }
- ptdat = ptdat + 16;
- for(i = 0; i < 16; i++){ //寫第五行字符串
- if(*ptdat != '\0'){
- wrtdat_12864(*ptdat++);
- }else{
- wrtdat_12864(0x20);
- over++;
- }
- }
- wrtcom_12864(0x0c); //開顯示
- if(over > 15){;} //顯示字符不足4行,不卷動
- else //顯示字符大于4行,繼續(xù)寫字符,同時開啟卷動
- {
- hang = 4;
- flag = 0x01;
- while(1){
- switch(hang){ //設置寫入DDRAM的地址
- case 1: addr = 0x80; break;
- case 2: addr = 0x90; break;
- case 3: addr = 0xa0; break;
- case 4: addr = 0xb0; break;
- }
- switch(hang){ //設置要寫數(shù)據(jù)的下一行
- case 1: hang = 2; break;
- case 2: hang = 3; break;
- case 3: hang = 4; break;
- case 4: hang = 1; break;
- }
- ptdat = ptdat - 32;
- for(i = 0; i < 8; i++){
- wrtcom_12864(0x34); //打開擴展指令
- wrtcom_12864(0x03); //允許輸入卷動地址
- wrtcom_12864(0x40 + flag++); //設置卷動地址
- wrtcom_12864(0x30); //回到基本指令
- wrtcom_12864(addr + i);
- delay_12864(20000);
- if(*ptdat != '\0'){
- wrtdat_12864(*ptdat++); //連續(xù)寫入兩個字節(jié)之高字節(jié)
- }else{
- wrtdat_12864(0x20);
- }
- if(*ptdat != '\0'){
- wrtdat_12864(*ptdat++); //連續(xù)寫入兩個字節(jié)之低字節(jié)
- }else{
- wrtdat_12864(0x20);
- }
- }
- ptdat = ptdat + 16;
- for(i = 8; i < 16; i++){
- wrtcom_12864(0x34); //打開擴展指令
- wrtcom_12864(0x03); //允許輸入卷動地址
- if(flag == 64){flag = 0;}
- wrtcom_12864(0x40 + flag); //設置卷動地址
- flag++;
- wrtcom_12864(0x30); //回到基本指令
- wrtcom_12864(addr + i);
- delay_12864(20000);
- if(*ptdat != '\0'){
- wrtdat_12864(*ptdat++); //連續(xù)寫入兩個字節(jié)之高字節(jié)
- }else{
- over++; //寫完最后一行字符,需要再卷動16次才能顯示出來。
- wrtdat_12864(0x20);
- }
- if(*ptdat != '\0'){
- wrtdat_12864(*ptdat++); //連續(xù)寫入兩個字節(jié)之低字節(jié)
- }else{
- wrtdat_12864(0x20);
- }
- }
- if(over < 8){;} //最后一行顯示完畢則停止卷動
- else {break;}
- }
- }
- }
- /***********************初始化12864子函數(shù)***********************************/
-
-
-
-
-
- void initial_12864(void){
- delay_12864(40000);
- RST_12864 = 1;
- RST_12864 = 0; //復位
- delay_12864(500);
- RST_12864 = 1;
- wrtcom_12864(0x30); //設置為基本指令集動作
- delay_12864(100);
- wrtcom_12864(0x30); //設置為基本指令集動作
- delay_12864(37);
- wrtcom_12864(0x08); //設置顯示、光標、閃爍全關。
- delay_12864(100);
- wrtcom_12864(0x01); //清屏,并且DDRAM數(shù)據(jù)指針清零
- delay_12864(1000);
- wrtcom_12864(0x06); //進入模式設置
- wrtcom_12864(0x0c); //開顯示
- }
復制代碼
匯編語言版本的程序:
- ; Generated by holtek-gcc v3.13, Wed Apr 13 19:10:57 2016
- ;
- ; Configuration:
- ; with long instruction
- ; Multi-ROM, Multi-RAM
- ; bits_per_rom_unit:16
- ; with mp1
- ; with tbhp, address(0x9)
- ; Use tabrd-const
- ;
- ; SFR address of long-instruction arch:
- ; mp0 = -1,1,0
- ; mp1 = 4,3,2
- ; mp2 = 14,13,12
- ; tbp = 9,7,8
- ; acc = 5
- ; pcl = 6
- ; status = 10
- ; bp = 11
- ; intc = 48
- ;
- ; use 'tabrdc' instead of 'tabrd'
- ;
- #pragma translator "holtek-gcc 4.6.4" "3.13" "build 20130711"
- ; Rebuild 26
- ir equ [2]
- mp equ [3]
- sbp equ [4]
- acc equ [5]
- bp equ [11]
- tblp equ [7]
- tbhp equ [9]
- status equ [10]
- c equ [10].0
- ac equ [10].1
- z equ [10].2
- ov equ [10].3
- cz equ [10].6
- sc equ [10].7
- intc equ [48]
- extern ra:byte
- extern rb:byte
- extern rc:byte
- extern rd:byte
- extern re:byte
- extern rf:byte
- extern rg:byte
- extern rh:byte
- extern _Crom2Prom:near
- extern _Crom2PromNext:near
- @HCCINIT .section 'data'
- @HCCINIT0 .section 'data'
- #pragma debug scope 1 1
復制代碼
|