找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2863|回复: 0
打印 上一主题 下一主题
收起左侧

合泰单片机HT66F70A LCD12864液晶屏驱动c语言

[复制链接]
跳转到指定楼层
楼主
ID:205348 发表于 2017-6-1 12:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#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);     //开显示
}











分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表