12864液晶显示屏单片机驱动,单片机型号是合泰HT66F70A
完整代码下载:
12864驱动1.zip
(41.58 KB, 下载次数: 114)
c语言版本的程序:
- #include <HT66F70A.H>
- #include "delay.h"
- #define IO_12864 _pc //定义12864的数据端口
- #define IO_12864_C _pcc
-
- #define RS_12864 _pd5 //定义命令数据寄存器选择端
- #define RW_12864 _pd6 //定义定义读写控制端
- #define E_12864 _pd7 //定义使能端
- #define RST_12864 _pd4 //定义复位端
- //#define CS2 _pd3
- //#define CS1 _pd2
- void delay_12864(unsigned int ); //延时子函数原型
- /*void busychk_12864(void); //忙检测子函数原型*/
- void wrtcom_12864(unsigned char); //写命令子函数原型
- unsigned char reddat_12864(void); //读数据子函数原型
- void wrtdat_12864(unsigned char); //写数据子函数原型
- //void choose_12864(unsigned char i); //选屏
- //void drawpic_12864( unsigned char*); //绘图子函数原型
- //void drawdot_12864(unsigned char,unsigned char,unsigned char);//画点子函数原型
- //void drawrec_12864(unsigned char,unsigned char,unsigned char,unsigned char,unsigned char); //画矩形子函数原型
- void clnGDR_12864(void); //清空GDRAM子函数原型
- void inputchars_12864(unsigned char,unsigned char,unsigned char*);//输入短字符串子函数原型
- void scroll_12864(unsigned char*); //输入长字符串卷动子函数原型
- void initial_12864(void); //12864初始化子函数原型
- 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); //忙状态检测,等待超时时间为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;
- }
- /**************************读数据子程序,返回一个字节的数据****************/
-
-
- 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;
- }
- /*****************写数据子程序***********************/
-
-
-
- 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;
- // }
- //}
- /************显示图片函数,参数时图片的地址,图片必须是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++ ) //写一整行数据
- //{
- //wrtdat_12864( *pPicture++ );
- //}
- //}
- //for( j = 0 ; j < 32 ; j++ )
- //{
- //wrtcom_12864(0x80 + j) ; //写Y 坐标
- //wrtcom_12864(0x88) ; //写X 坐标
- //for( k = 0 ; k < 16 ; k++ ) //写一整行数据
- //{
- //wrtdat_12864( *pPicture++ ) ;
- //}
- //}
- //wrtcom_12864(0x36); //打开绘图显示
- //wrtcom_12864(0x30); //返回基本指令集
- //}
- //
- ////画点函数,左上角为参考点(0,0)
- ////右下角为(127,63),点坐标形式为(行坐标,列坐标)
- ////参数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(); //读高字节
- //DL = reddat_12864(); //读低字节
- //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); //回写高字节
- //wrtdat_12864(DL); //回写低字节
- //
- //wrtcom_12864(0x36); //开启绘图显示
- //wrtcom_12864(0x30); //转回普通指令
- //}
- //}
- //
- // /**********************画矩形子函数,参数为(点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++ ) //写一整行数据
- {
- wrtdat_12864( 0x00 );
- }
- }
- wrtcom_12864(0x30); //返回基本指令集
- }
- /***********************写入短字符串函数,参数分别为显示行(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++);
- }
- }
- }
- /******************长字符串显示卷屏函数**************************/
-
-
-
- void scroll_12864(unsigned char *ser){
- //addr存储地址的中间变量,flag卷屏地址,hang要写数据的行,
- //over写完字符串后继续写的空字符计数
- unsigned char i,addr,flag,hang,over,*ptdat;
- ptdat = ser; //获得字符串首地址
- over = 0; //写入空字符串(写完字符串后)数目初始化为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行,继续写字符,同时开启卷动
- {
- 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){ //设置要写数据的下一行
- 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++); //连续写入两个字节之高字节
- }else{
- wrtdat_12864(0x20);
- }
- if(*ptdat != '\0'){
- wrtdat_12864(*ptdat++); //连续写入两个字节之低字节
- }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++); //连续写入两个字节之高字节
- }else{
- over++; //写完最后一行字符,需要再卷动16次才能显示出来。
- wrtdat_12864(0x20);
- }
- if(*ptdat != '\0'){
- wrtdat_12864(*ptdat++); //连续写入两个字节之低字节
- }else{
- wrtdat_12864(0x20);
- }
- }
- if(over < 8){;} //最后一行显示完毕则停止卷动
- else {break;}
- }
- }
- }
- /***********************初始化12864子函数***********************************/
-
-
-
-
-
- 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数据指针清零
- 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
复制代码
|