LCD12864学习

xiaoxiao2021-02-28  76

LCD12864.C

/* 简单理解即是 * CGRAM是留给自己造字的地方 * DDRAM是显示数据地方 * 地址计数器用来存CGRAM以及DDRAM的地址值 * * 对DDRAM的操作基本单位是字(16*16的倍数),写地址只需写入一个起始地址即可 * 对CGRAM的操作x(列)的基本单位是字,y(行)的基本单位是行,写地址需要分别写入起始的y和x * */ #define _LCD_12864_C #include "config.h" #include "Lcd12864.h" /* 等待液晶准备好 */ void LcdWaitReady() { uint8 sta; LCD12864_DB = 0xFF; LCD12864_RS = 0; LCD12864_RW = 1; do { LCD12864_E = 1; sta = LCD12864_DB; LCD12864_E = 0; } while (sta & 0x80); //bit7等于1表示液晶正忙,重复检测直到其等于0为止 } /* 向液晶写入一字节命令,cmd-待写入命令值 */ void LcdWriteCmd(uint8 cmd) { LcdWaitReady(); LCD12864_RS = 0; LCD12864_RW = 0; LCD12864_DB = cmd; LCD12864_E = 1; LCD12864_E = 0; } /* 向液晶写入一字节数据,dat-待写入数据值 */ void LcdWriteDat(uint8 dat) { LcdWaitReady(); LCD12864_RS = 1; LCD12864_RW = 0; LCD12864_DB = dat; LCD12864_E = 1; LCD12864_E = 0; } /* * 函数名:LcdShowString * 描 述:在显示屏上显示一串字符串 * 输 入:str - 待显示字符串指针 * x - 屏幕显示横坐标(以像素为单位) * y - 屏幕显示纵坐标(以像素为单位) * 输 出:无 * 备 注:输入的字符串必须符合C语言规范,即以'\0'-NULL为结束标识; * x、y坐标必须是16的整数倍,因DDRAM地址以全角字符(16*16pixel)为单位。 * x、y坐标同样从0开始数 */ void LcdShowString(uint8 x, uint8 y, uint8 *str) { uint8 addr; //由输入的显示坐标计算DDRAM的地址 x >>= 4; //列对应的字 y >>= 4; //行对应的字 //这个计算666的,,,其实带入坐标就立刻理解其含义了eg (16,32) if (y >= 2) //到了下半屏 { y -= 2; x += 8; //eg(1,2) } addr = y*16 + x; //eg(9,0) 666的公式,位置偏移公式 //由起始DDRAM地址连续写入字符串 LcdWriteCmd(0x30); //启动DDRAM操作 基本指令集 LcdWriteCmd(0x80|addr); //eg 89H while (*str != '\0') { LcdWriteDat(*str); str++; } } /* * 函数名:LcdShowImage * 描 述:在显示屏上显示一幅图像 * 输 入:img - 待显示图像指针 * x - 屏幕显示横坐标(以像素为单位) * y - 屏幕显示纵坐标(以像素为单位) * w - 图像宽度(以像素为单位) * h - 图像高度(以像素为单位) * 输 出:无 * 备 注:x与w必须是16的整数倍,因CGRAM最小寻址单位为2字节;y与h可为0-63的任意值。 */ void LcdShowImage(uint8 x, uint8 y, uint8 w, uint8 h, uint8 *img) { //eg(16,0,96,32,welcome) int16 i; uint8 xi,yi; uint8 xt,yt; x >>= 4; //换算成字,还用于判断上屏还是下屏 w >>= 3; //换算成字节 i = 0; LcdWriteCmd(0x36); //启动CGRAM操作 启动绘图指令 for (yi=0; yi<h; yi++)//行的循环 { yt = y+yi; xt = x; if (yt >= 32) //超出上屏 { yt -= 32; //对应下屏坐标(行,列)=>单位(行,字) xt += 8; } LcdWriteCmd(0x80|yt); //行,第几行 LcdWriteCmd(0x80|xt); //列,第几字 for (xi=0; xi<w; xi++) //上面一个循环已经定位到所在行, {//字是分开高低写入的,所以此处一字节为单位。一个字节完了之后指针自动+1。 LcdWriteDat(img[i++]); } } } /* * 函数名:LcdClearArea * 描 述:清除屏幕上的一块图形显示区域 * 输 入:x - 区域起始横坐标(以像素为单位) * y - 区域起始纵坐标(以像素为单位) * w - 区域宽度(以像素为单位) * h - 区域高度(以像素为单位) * 输 出:无 * 备 注:x与w必须是16的整数倍,因CGRAM最小寻址单位为2字节;y与h可为0-63的任意值。 */ void LcdClearArea(uint8 x, uint8 y, uint8 w, uint8 h) { uint8 xi,yi; uint8 xt,yt; x >>= 4; //右移四位相当于除以2^4即是16 w >>= 3; //右移三位相当于除以2^3即是8 LcdWriteCmd(0x36); //启动CGRAM操作 for (yi=0; yi<h; yi++) { yt = y+yi; xt = x; if (yt >= 32) { yt -= 32; xt += 8; } LcdWriteCmd(0x80|yt); //注意这里要写入两个地址分别是位地址 LcdWriteCmd(0x80|xt); //和字地址 for (xi=0; xi<w; xi++) { LcdWriteDat(0x00); //写入0x00以清除显示 } } } /* 12864液晶初始化函数 */ void InitLcd12864() { uint8 x, y; //字符模式初始化 LcdWriteCmd(0x30); //基本指令集 LcdWriteCmd(0x01); //清零字符显示 LcdWriteCmd(0x02); //地址归位 LcdWriteCmd(0x0C); //开显示 //图形模式初始化 LcdWriteCmd(0x34); //启动扩展指令,关闭图形显示 for (y=0; y<32; y++) //清零图形显示缓冲区 GDRAM { LcdWriteCmd(0x80|y);//写Y坐标,也就是行地址 LcdWriteCmd(0x80|0);//写X坐标,也就是列地址 for (x=0; x<32; x++)//这一行进行写0,写完一个字节地址会自动加1,这里表示写完一行32个字节 { //写完之后跳出循环,到下一行。 LcdWriteDat(0x00); } } LcdWriteCmd(0x36); //开启图形模式显示 }

LCD12864.h

#ifndef _LCD_12864_H #define _LCD_12864_H //12864液晶口线与板载1602液晶相同 #define LCD12864_DB LCD1602_DB #define LCD12864_RS LCD1602_RS #define LCD12864_RW LCD1602_RW #define LCD12864_E LCD1602_E #ifndef _LCD_12864_C #endif void InitLcd12864(); void LcdShowString(uint8 x, uint8 y, uint8 *str); void LcdShowImage(uint8 x, uint8 y, uint8 w, uint8 h, uint8 *img); void LcdClearArea(uint8 x, uint8 y, uint8 w, uint8 h); #endif ReCclay 认证博客专家 嵌入式软件开发 机器/深度学习 全栈技术学习者 大家好,我是博主ReCclay,目前处于研究生阶段,就读于电子科技大学,主攻方向为汽车辅助驾驶算法研究。入站以来,凭借坚持与热爱,以博文的方式分享所学,截止目前累计博文数量达800余篇,累计受益人次达130w+次,涉及领域包括但不限于物联网开发、单片机开发、Linux驱动开发、FPGA开发、前/后端软件开发等。在未来我将继续专注于嵌入式相关领域,学习更多的科技知识,输出更高质量的博文。
转载请注明原文地址: https://www.6miu.com/read-84825.html

最新回复(0)