STC15W4K56S4学习笔记——LCD12864滚动显示

​ 最近在准备学校的单片机校赛,重新回顾了一遍51单片机,上手了STC15W4K56S4试验箱,写一些笔记来记录一下,水平有限,有错误的希望各位大佬指出!

一、硬件

STC15W4K56S4核心板+12864液晶屏

引脚分配:

数据端(D0-D7) <–> P0

RS:命令/数据寄存器选择端 <–> P20

RW:读写控制端 <–> P21

EN:使能端 <–> P22

原理图连接如下:

12864液晶是一种具有4位/8位并行、2线或3线串行多种接口方式的点阵图形液晶显示模块,本实验使用8位并行总线驱动。

对12864的所有操作概括起来有4种:

(1)读忙状态(同时读出指针地址内容):初始化之后每次对12864的读写均要进行忙检测。

(2)写命令:所有的命令可以查看指令表,后续讲解指令的详细用法,写地址也是写指令。

(3)写数据:操作对象有DDRAM(Data Display Ram)、CGRAM(Character Generation Ram )、GDRAM(Graphic Display RAM)。

(4)读数据:操作对象也是DDRAM、CGRAM、GDRAM。

二、软件

lcd12864.c文件

#include "lcd12864.h"/*******************************************************************************
* 函 数 名         : LCD12864_Delay1ms
* 函数功能         : 延时1MS
* 输    入         : c
* 输    出         : 无
*******************************************************************************/void LCD12864_Delay1ms(uint c)
{uchar a,b;for(; c>0; c--){for(b=199; b>0; b--){for(a=1; a>0; a--);}}
}/*******************************************************************************
* 函 数 名         : LCD12864_Busy
* 函数功能         : 检测LCD是否忙
* 输    入         : 无
* 输    出         : 1或0(1表示不忙,0表示忙)
*******************************************************************************///uchar LCD12864_Busy(void)
//{
//  uchar i = 0;// LCD12864_RS = 0;       //选择命令
//  LCD12864_RW = 1;   //选择读取//    LCD12864_EN = 1;
//  LCD12864_Delay1ms(1);
//
//  LCD12864_Delay1ms(10);//    LCD12864_EN = 0;// return 1;
//}/*******************************************************************************
* 函 数 名         : LCD12864_WriteCmd
* 函数功能         : 写命令
* 输    入         : cmd
* 输    出         : 无
*******************************************************************************/void LCD12864_WriteCmd(uchar cmd)
{uchar i;i = 0;LCD12864_Delay1ms(20);LCD12864_RS = 0;     //选择命令LCD12864_RW = 0;     //选择写入LCD12864_EN = 0;     //初始化使能端LCD12864_DATAPORT = cmd;   //放置数据LCD12864_EN = 1;        //写时序LCD12864_Delay1ms(5);LCD12864_EN = 0;
}/*******************************************************************************
* 函 数 名         : LCD12864_WriteData
* 函数功能         : 写数据
* 输    入         : dat
* 输    出         : 无
*******************************************************************************/void LCD12864_WriteData(uchar dat)
{uchar i;i = 0;LCD12864_Delay1ms(20);LCD12864_RS = 1;     //选择数据LCD12864_RW = 0;     //选择写入LCD12864_EN = 0;     //初始化使能端LCD12864_DATAPORT = dat;   //放置数据LCD12864_EN = 1;        //写时序LCD12864_Delay1ms(5);LCD12864_EN = 0;
}/*******************************************************************************
* 函 数 名         : LCD12864_ReadData
* 函数功能         : 读取数据
* 输    入         : 无
* 输    出         : 读取到的8位数据
*******************************************************************************/
#ifdef LCD12864_PICTUREuchar LCD12864_ReadData(void)
{uchar i, readValue;i = 0;LCD12864_Delay1ms(20);LCD12864_RS = 1;       //选择命令LCD12864_RW = 1;LCD12864_EN = 0;LCD12864_Delay1ms(1);  //等待LCD12864_EN = 1;LCD12864_Delay1ms(1);readValue = LCD12864_DATAPORT;LCD12864_EN = 0;return readValue;
}#endif/*******************************************************************************
* 函 数 名         : LCD12864_Init
* 函数功能         : 初始化LCD12864
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/void LCD12864_Init()
{LCD12864_WriteCmd(0x30);  //选择基本指令操作LCD12864_WriteCmd(0x0c);  //显示开,关光标LCD12864_WriteCmd(0x01);  //清除LCD12864的显示内容
}/*******************************************************************************
* 函 数 名         : LCD12864_ClearScreen
* 函数功能         : 在画图模式下,LCD12864的01H命令不能清屏,所以要自己写一个清
*                  * 屏函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
#ifdef LCD12864_PICTUREvoid LCD12864_ClearScreen(void)
{uchar i,j;LCD12864_WriteCmd(0x34);   //开启拓展指令集for(i=0;i<32;i++)            //因为LCD有纵坐标32格所以写三十二次{LCD12864_WriteCmd(0x80+i);       //先写入纵坐标Y的值LCD12864_WriteCmd(0x80);         //再写入横坐标X的值for(j=0;j<32;j++)          //横坐标有16位,每位写入两个字节的的数据,也{                         //就写入32次以为当写入两个字节之后横坐标会自LCD12864_WriteData(0xFF);   //动加1,所以就不用再次写入地址了。}}LCD12864_WriteCmd(0x36);   //0x36扩展指令里面打开绘图显示LCD12864_WriteCmd(0x30);  //恢复基本指令集
}#endif
/*******************************************************************************
* 函 数 名         : LCD12864_SetWindow
* 函数功能         : 设置在基本指令模式下设置显示坐标。注意:x是设置行,y是设置列
* 输    入         : x, y
* 输    出         : 无
*******************************************************************************/void LCD12864_SetWindow(uchar x, uchar y)
{uchar pos;if(x == 0)    // 第一行的地址是80H{x = 0x80;}else if(x == 1)  //第二行的地址是90H{x = 0x90;  }else if(x == 2)  //第三行的地址是88H{x = 0x88;}else if(x == 3){x = 0x98;}pos = x + y;LCD12864_WriteCmd(pos);
}

lcd12864.h文件

#ifndef __LCD12864_H
#define __LCD12864_H//---包含头文件---//
#include "stc15f2k60s2.h"//---重定义关键词---//
#ifndef uchar
#define uchar unsigned char
#endif#ifndef uint
#define uint unsigned int
#endif//---定义使用的IO口---//
#define LCD12864_DATAPORT P0      //数据IO口sbit LCD12864_RS  =  P2^0;      //(数据命令)寄存器选择输入    TFT_D10  A8
sbit LCD12864_RW  =  P2^1;      //液晶读/写控制               TFT_D8   A9
sbit LCD12864_EN  =  P2^2;      //液晶使能控制               TFT_D9   A10//---声明全局函数---//
void LCD12864_Delay1ms(uint c);
//uchar LCD12864_Busy(void);
void LCD12864_WriteCmd(uchar cmd);
void LCD12864_WriteData(uchar dat);
void LCD12864_Init();
void LCD12864_ClearScreen(void);
void LCD12864_SetWindow(uchar x, uchar y);#endif

main.c文件

#include "stc15f2k60s2.h"
#include <intrins.h>
#include "lcd12864.h"/***************
12864液晶实验
从下到上滚动显示字符串
***************/unsigned char code CharCode1[]="2020";
unsigned char code CharCode2[]="1010";//针对STC15W4K56S4系列IO口初始化
//io口初始化 P0~7 为准双向IO口
void IO_init(void)
{P0M0 = 0X00;      P0M1 = 0X00;P1M0 = 0X00;    P1M1 = 0X00;P2M0 = 0X00;    P2M1 = 0X00;P3M0 = 0X00;  P3M1 = 0X00;P4M0 = 0X00;  P4M1 = 0X00;   P5M0 = 0X00;   P5M1 = 0X00;   P6M0 = 0X00;   P6M1 = 0X00;   P7M0 = 0X00;   P7M1 = 0X00;
}/*****
12864显示字符串函数
字符串从下往上依次间隔500ms滚动显示
********/
void display()
{uchar i,j,k;LCD12864_Init();for(k=5;k>=1;k--){i=0;j=0;LCD12864_WriteCmd(0x01);         //清除LCD12864的显示内容if(k!=5)                         //令k不等于5,因为lcd的行只有0.1.2.3,k=5时,{                                //k-1=4,会出现错误,所以当k=5时将不会执行以下函数。LCD12864_SetWindow(k-1, 0);  //设置在基本指令模式下设置显示的坐标,k-1取3.2.1.0while(CharCode1[i]!='\0')    //当不是字符串结束符时,执行循环{LCD12864_WriteData(CharCode1[i]);  //向12864写数据i++;                               //每次只能写一个,所以要++,依次写进去}}if(k!=1)                        //k不等于1时执行以下函数{LCD12864_SetWindow(k-2, 0);   //k-2依次为3.2.1.0,即从最下面往上显示while(CharCode2[j]!='\0')     //当不是字符串结束符时,执行循环{LCD12864_WriteData(CharCode2[j]);  //向12864写数据j++;                               //自加依次写数据}}LCD12864_Delay1ms(5000);               //延时500ms}}void main()
{IO_init();  //针对STC15W4K56S4 IO口初始化//设置STC单片机的P20 P21 22为推挽输出P2M1 &= ~(1<<2),P2M0 |=  (1<<2); P2M1 &= ~(1<<1),P2M0 |=  (1<<1); P2M1 &= ~(1<<0),P2M0 |=  (1<<0);  LCD12864_Init();while(1){display(); }
}

(1)STC15W4K56S4系列IO口初始化解释:

STC单片机有四种工作模式:

准双向口,推挽输出,高阻输入,开漏输出

如果要设置为后面3种,则需要配置寄存器来设置,通过M0,M1来设置IO口模式

M0 M1

0 0 准双向口

0 1 高阻输入

1 0 推挽输出

1 1 开漏输出

P2M1 &= ~(1<<0),P2M0 |=  (1<<0); //设置STC单片机的P20为推挽输出

P2M1 &= ~(1<<0):1左移0位,再非,与之后赋值给P2的M1,即把P20的M1设置为0

同理P2M0 |= (1<<0),把P20的M0设置为1,所P20口为推挽输出

(2)lcd12864滚动显示:

首先初始化12864函数后,进入一个for循环,此循环执行5次,每次进去都会进行一次清屏,显示一次清除一次,每次开始的位置不一样,从而达到滚动的效果。

LCD12864_SetWindow(x, y)函数设置显示的位置,x为行(取0.1.2.3四个值),y为列。

此函数为显示两行字符滚动,所以设置了两个if条件,因为在最上面或者最下面的时候,总会有一行没能显示,所以要判断能显示那串字符串的条件,不然x的值设定会不存在,显示的时候会出错。之前写的时候就是没有主要到这个,没有进行判断,还困惑了好久。

我这个是第一串字符从最后一行往上显示,第二串紧跟着,最后是第二串在最上面(第一行)显示,想要其他效果改变显示的坐标就可以。

for(k=5;k>=1;k--){i=0;j=0;LCD12864_WriteCmd(0x01);         //清除LCD12864的显示内容if(k!=5)                         //令k不等于5,因为lcd的行只有0.1.2.3,k=5时,{                                //k-1=4,会出现错误,所以当k=5时将不会执行以下函数。LCD12864_SetWindow(k-1, 0);  //设置在基本指令模式下设置显示的坐标,k-1取3.2.1.0while(CharCode1[i]!='\0')    //当不是字符串结束符时,执行循环{LCD12864_WriteData(CharCode1[i]);  //向12864写数据i++;                               //每次只能写一个,所以要++,依次写进去}}if(k!=1)                          //k不等于1时执行以下函数{LCD12864_SetWindow(k-2, 0);   //k-2依次为3.2.1.0,即从最下面往上显示while(CharCode2[j]!='\0')     //当不是字符串结束符时,执行循环{LCD12864_WriteData(CharCode2[j]);  //向12864写数据j++;                               //自加依次写数据}}LCD12864_Delay1ms(5000);               //延时500ms}}

(3)延时函数

LCD12864_Delay1ms(5000);               //延时500ms

这个延时是500ms,因为单片机设置为24MHz的晶振,12T模式,所以一个机器周期为(1s/24MHz)*12=0.5us

void LCD12864_Delay1ms(uint c)
{uchar a,b;for(; c>0; c--){for(b=199; b>0; b--){for(a=1; a>0; a--);}}
}

所以 LCD12864_Delay1ms()的延时就是:0.5*200=100us,

LCD12864_Delay1ms(5000) 就是5000*100us=500ms

三、实验效果

欢迎大家指出错误的地方哦,第一次写博客,写得不是很好,参考参考就行,希望以后能坚持下去,在CSDN记录自己的学习笔记。

STC15W4K56S4学习笔记——LCD12864滚动显示相关推荐

  1. android 全局 窗口,学习笔记:WindowManager显示Android全局悬浮窗口

    我用Android手机装了个电商软件,抢购用.自己手机的状态栏不能显示秒级别的时间,只能精确到分钟.为了能准确的把握抢购时间,自己边学习边开发了一个时间显示悬浮窗. WindowManager 参考文 ...

  2. Qt5.9学习笔记2-输入/显示/按钮/菜单/时间/字体/图片

    一般属性在类的接口中有读取函数和设置函数,对于设置属性函数就是属性名前加set 如QSpinBox类中有属性value用来显示组件当前值,可以使用setValue()方法来设置该组件的值. 1.输入组 ...

  3. STM32学习笔记一一TFTLCD 显示

    前言: 为了方便查看博客,特意申请了一个公众号,附上二维码,有兴趣的朋友可以关注,和我一起讨论学习,一起享受技术,一起成长. 1.TFTLCD 简介 TFT-LCD 即薄膜晶体管液晶显示器.TFT-L ...

  4. cocos2dx 字体外发光_《Cocos2d-x游戏开发实战精解》学习笔记2--在Cocos2d-x中显示一行文字...

    在Cocos2d-x中要显示文字就需要用到Label控件.在3.x版本的Cocos2d中,舍弃了之前版本所使用的LabelTTF.LabelAtlas.LabelBMFont 3个用于显示文字的类,而 ...

  5. 四、pink老师的学习笔记——元素的显示与隐藏

    1. 元素的显示与隐藏 目的 让一个元素在页面中消失或者显示出来 场景 类似网站广告,当我们点击关闭就不见了,但是我们重新刷新页面,会重新出现! 1.1 display 显示(重点) display ...

  6. Qt学习笔记——打开并显示图片

    使用控件QLabel mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #inclu ...

  7. joomla3.4.1学习笔记(一)——后台显示自定义模板

    必须的两个文件index.php和templateDetails.xml,新手可以从joomla自带的模板中复制,将两个文件放到文件夹中,压缩成zip文件. 后台--扩展管理器--安装,选择你的zip ...

  8. CSS学习笔记之土豆网显示隐藏小练习 3.9

    实现效果: 原先半透明的黑色遮罩看不见, 鼠标经过大盒子就显示出来. 利用绝对定位和diplay可以实现 代码: <!DOCTYPE html> <html lang="e ...

  9. [JQuery 学习笔记] 隐藏和显示 hide() 和 show()

    hide()  和 show() 方法 <!DOCTYPE html> <html lang="en"> <head><meta char ...

最新文章

  1. 参考-这个符号在PHP中是什么意思?
  2. nodejs-REPL/回调函数/事件循环
  3. 狗屎一样的代码如何重构?
  4. 如何在IDEA 中使用Git
  5. Product settype list tool - report PROD_DISPLAY_SETTYPE
  6. Java包的命名规则
  7. [转载]高性能托管应用程序设计入门
  8. codeblocks中文编码问题
  9. cdecl.org 翻译C声明的网站
  10. HttpURLConnection模拟form表单提交文件
  11. Steam DS4手柄
  12. 台式计算机屏幕出现数字模拟,电脑显示器黑屏左上角显示数字模拟什么回事
  13. 企业支付宝 异名网银u盾快速充值功能开通方式(支付宝企业商户资金充值方法)
  14. Recoil - Facebook 官方 React 状态管理器
  15. 【Proteus仿真】Arduino UNO利用Stepper库实现uln2003驱动步进电机转动
  16. matlab 2ask,(最新整理)基于MATLAB的2ASK和2FSK调制仿真(通信原理实验报告)
  17. 苹果ios微信浏览器视频自动播放
  18. 【HBase】HBase phoenix 安装使用
  19. Linux 日志查看
  20. 学生考勤系统设计c语言源程序文件的后缀是,C++学生考勤系统(含源代码).doc

热门文章

  1. 04 pandas 分组
  2. html5画布作品,HTML5 Canvas 画布(示例代码)
  3. 分享如何监听按下键盘任意组合键
  4. 从社会数据到社会智慧的社会计算:新技术、新哲学、新文科
  5. Web_sql之宽字节注入(DAY7)
  6. Java反编译插件JODE介绍
  7. R语言snow包并行计算
  8. 使用midi接口制作模拟电钢琴
  9. 入行IT,学哪个技术前景更好?
  10. 【githubshare】推荐 GitHub 上一本开源自然数和计算机程序、欧几里得算法、递归的形式与结构、斐波那契数列、罗素悖论