标题:
很详细的LCD12864伪菜单单片机程序,同时实现任意位置的反白
[打印本页]
作者:
全力
时间:
2017-12-23 08:32
标题:
很详细的LCD12864伪菜单单片机程序,同时实现任意位置的反白
LCD伪菜单程序,我觉得注释还是写的很详细滴。同时实现任意位置的反白,我查了很多资料,发现12864的字符RAM和绘图RAM之间的异或关系
0.png
(12.76 KB, 下载次数: 36)
下载附件
2017-12-23 14:58 上传
单片机源程序如下:
#include <reg52.h>
#include <intrins.h>
#include "Delay.h"
#include "key.h"
#define uint unsigned int
#define uchar unsigned char
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();};
uchar code DIS1[] = {" 菜单查询 "};//一行一共有16个字符,空格也占一个字符位
uchar code DIS2[] = {" 地图导航 "};
uchar code DIS3[] = {" 语音导航 "};
uchar code DIS4[] = {" 商品查询 "};
/************* 12864LCD引脚定义 *************/
#define LCD_data P0 //数据口
sbit LCD_RS = P2^6; //寄存器选择输入
sbit LCD_RW = P2^5; //液晶读/写控制
sbit LCD_EN = P2^7; //液晶使能控制
sbit LCD_PSB = P3^2; //串/并方式控制
//sbit LCD_RST = P3^7; //液晶复位端口
/************* LCD12864字符 *************/
uchar code Photo_inverse_1[] ={ //将第一行进行反白
/*-- 调入了一幅图像:这是您新建的图像 --*/
/*-- 宽度x高度=128x16 --*/
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
……字库请下载附件……
0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
};
/*******************************************************************/
/* */
/*检查LCD忙状态 */
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 */
/* */
/*******************************************************************/
bit lcd_busy() //定义了一个函数返回值类型lcd_busy()该函数只会有两个值,一个是0,一个是1
{ //位定义:bit的值只有两个,分别是0和1 如果P0&0x80的值为真,通过位定义(bit定义),那么result的值就是1。如果P0&0x80的值为假,通过位定义(bit定义),那么result的值就是0。
bit result;
LCD_RS = 0; //时序图:
LCD_RW = 1;
LCD_EN = 1;
delayNOP();
result = (bit)(P0&0x80); //把P0口读到的数据与0x80相与(0x80是1000 0000即判断最高位P0^7的状态是0还是1) 开发板原理图上8个数据口都是连在P0口上
//读取P0^7引脚上的状态 1&1=1 1&0=0
/*此程序是判断液晶忙程序,rs = 0;rw = 1;ep = 1;为读状态字功能,
而状态字一共有8位,STA0~STA7,其中,STA0~STA6表示当前数据地址指针的数值,
STA7是读写操作使能,1表示禁止,也就是禁止操作液晶,也就是液晶忙,此时result为1,
反之,0表示允许,因此只需要状态字STA0~STA7中的最高位,你的程序中是通过P0控制状态字,
因此,就有result = (bit)(P0 & 0x80)*/
LCD_EN = 0; //EN信号下降沿锁存DB7~DB0
return(result); //返回0或者1
}
/*******************************************************************/
/* */
/*写指令数据到LCD */
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */
/* */
/*******************************************************************/
void lcd_wcmd(uchar cmd) //write_cmd写命令 想要对液晶进行操作,肯定先要在它空闲的时候操作
{
while(lcd_busy()); //等待lcd_busy()=0;是不是检测忙标志BF,因为BF=1,表示模块内部执行命令,不接受任何外部指令;BF=0,说明随时可以接收外部指令
LCD_RS = 0; //RS为0表示DB7~DB0为显示指令数据
LCD_RW = 0; //RW为0表示数据被写到IR或者DR
LCD_EN = 0; //E下降沿锁存DB7~DB0
_nop_();
_nop_();
P0 = cmd;
delayNOP();
LCD_EN = 1; //E下降沿锁存DB7~DB0
delayNOP();
LCD_EN = 0;
}
/*******************************************************************/
/* */
/*写显示数据到LCD */
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */
/* */
/*******************************************************************/
void lcd_wdat(uchar dat) //write_data写数据
{
while(lcd_busy());
LCD_RS = 1; //RS = 1;表示DB7~DB0为显示数据
LCD_RW = 0; //DB7~DB0数据被读入IR
LCD_EN = 0;
P0 = dat;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
/*******************************************************************/
/* */
/* LCD初始化设定 */
/* */
/*******************************************************************/
void lcd_init()
{
LCD_PSB = 1; //PSB为高电平--并口方式:并口快,需要8+3条io口,读写快,特别适合图形方式;数据是从并口DB0-DB7(7-14)脚传输数据的
//PSB为低电平--串口方式:占用Io口少,最少好像是两条,cs需要特殊处理一下,控制起来比较好使,占用单片机资源多,当然也有些小技巧可以解决
//串口方式,是从串口4(RS/CS并行的指令/数据选择信号);串行的片选信号、5(R/W/SID)并行的读写选择信号,串行的数据口,6(E/CLK)并行的使能信号
// LCD_RST = 0; //液晶复位
// delay(3);
// LCD_RST = 1; //复位置高
// delay(3);
lcd_wcmd(0x34); //扩充指令操作
delay(5);
lcd_wcmd(0x30); //基本指令操作
delay(5);
lcd_wcmd(0x0C); //显示开,关光标,不反白
delay(5);
lcd_wcmd(0x01); //清除LCD的显示内容(清屏)指针归位,设置地址指针魏00H
delay(5);
// lcd_wcmd(0x06); //指定在资料的读取和写入时,设定游标的移动方向及指定显示的一位,光标先从右向左加1位移动
// delay(5);
}
/*********************************************************/
/* */
/* 设定显示位置 */
/* */
/*********************************************************/
void lcd_pos(uchar X,uchar Y) //汉字显示坐标函数 X代表第几行 Y代表第几列
{
uchar pos;
if (X==1) //1代表第一行
{X=0x80;}
else if (X==2) //2代表第二行
{X=0x90;}
else if (X==3) //3代表第三行
{X=0x88;}
else if (X==4) //4代表第四行
{X=0x98;}
pos = X+Y ; //pos = 0x80+0 = 0x80
lcd_wcmd(pos); //显示地址
}
/*********************************************************
* *
* 闪烁函数 *
* *
*********************************************************/
void lcdflag() //效果:闪三下
{
lcd_wcmd(0x08);
delay(400);
lcd_wcmd(0x0c);
delay(400);
lcd_wcmd(0x08);
delay(400);
lcd_wcmd(0x0c);
delay(400);
lcd_wcmd(0x08);
delay(200);
lcd_wcmd(0x0c);
delay(5);
lcd_wcmd(0x01);
delay(5);
}
/*********************************************************
* *
* 图形显示 *
* *
*********************************************************/
void photodisplay(uchar *bmp)
{
uchar i,j;
lcd_wcmd(0x34); //写数据时,关闭图形显示
for(i=0;i<32;i++)
{
lcd_wcmd(0x80+i); //先写入水平坐标值
lcd_wcmd(0x80); //写入垂直坐标值
for(j=0;j<16;j++) //再写入两个8位元的数据
lcd_wdat(*bmp++);
delay1(1);
}
for(i=0;i<32;i++)
{
lcd_wcmd(0x80+i);
lcd_wcmd(0x88);
for(j=0;j<16;j++)
lcd_wdat(*bmp++);
delay1(1);
}
lcd_wcmd(0x36); //写完数据,开图形显示
}
/*********************************************************
* *
* 清屏函数 *
* *
*********************************************************/
void clr_screen()
{
lcd_wcmd(0x34); //扩充指令操作
delay(5);
lcd_wcmd(0x30); //基本指令操作
delay(5);
lcd_wcmd(0x01); //清屏
delay(5);
}
/**********************************************************
; 显示字符表代码
**********************************************************/
void bytecode()
{
uchar s;
clr_screen(); //清屏
lcd_wcmd(0x80); //设置显示位置为第一行
for(s=0;s<16;s++)
{
lcd_wdat(0x30+s);
}
lcd_wcmd(0x90); //设置显示位置为第二行
for(s=0;s<16;s++)
{
lcd_wdat(0x40+s);
}
lcd_wcmd(0x88); //设置显示位置为第三行
for(s=0;s<16;s++)
{
lcd_wdat(0x50+s);
}
lcd_wcmd(0x98); //设置显示位置为第四行
for(s=0;s<16;s++)
{
lcd_wdat(0x60+s);
}
}
/*********************************************************
* *
* 用于检测程序能不能跑起来。。。没啥用 就是测试 *
* *
*********************************************************/
void lcd_action_up()
{
uchar i;
lcd_pos(1,0); //设置显示位置为第一行 输出第一个数组
for(i=0;i<16;i++)
{
lcd_wdat(DIS1[i]);
delay(1);
}
for(i=0;i<16;i++)
{
lcd_wdat(DIS2[i]);
delay(1);
}
for(i=0;i<16;i++)
{
lcd_wdat(DIS3[i]);
delay(1);
}
for(i=0;i<16;i++)
{
lcd_wdat(DIS4[i]);
delay(1);
}
photodisplay(Photo_inverse_5); //反白设置
delay(3000);
}
void lcd_action_down()
{
uchar i;
lcd_pos(1,0); //设置显示位置为第一行 输出第一个数组
for(i=0;i<16;i++)
{
lcd_wdat(DIS1[i]);
delay(1);
}
for(i=0;i<16;i++)
{
lcd_wdat(DIS2[i]);
delay(1);
}
for(i=0;i<16;i++)
{
lcd_wdat(DIS3[i]);
delay(1);
}
for(i=0;i<16;i++)
{
lcd_wdat(DIS4[i]);
delay(1);
}
photodisplay(Photo_inverse_6); //反白设置
delay(3000);
}
void lcd_action_enter()
{
uchar i;
lcd_pos(1,0); //设置显示位置为第一行 输出第一个数组
for(i=0;i<16;i++)
{
lcd_wdat(DIS1[i]);
delay(1);
}
for(i=0;i<16;i++)
{
lcd_wdat(DIS2[i]);
delay(1);
}
for(i=0;i<16;i++)
{
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
/*******************************************************************************
* 描述: *
* 12864标准字库液晶演示 数据p0,控制p2 *
********************************************************************************/
#include <reg51.h>
#include <intrins.h>
#include "LCD12864.h"
#include "Delay.h"
#include "key.h"
#define uchar unsigned char
#define uint unsigned int
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();};
/*********************************************************
* *
* 主函数 *
* *
*********************************************************/
void main()
{
delay(1000); //上电,等待稳定
lcd_init(); //初始化LCD
while(1)
{
Menu_temp_judge();
}
}
复制代码
#include <reg52.h>
#include "LCD12864.h"
#include "Delay.h"
#define uint unsigned int
#define uchar unsigned char
sbit key_UP = P1^0;
sbit key_Down = P1^1;
sbit key_Enter = P1^2;
sbit key_Cancel = P1^3;
uchar fresh_keytemp; //用于保存从按键判断函数uchar keyscan()的返回值
uchar keyscan()
{
uchar keytemp;
if (key_UP == 0) //反白上移
{
delays(10);
if (key_UP == 0)
{
delays (10);
while(!key_UP); //按键的完整操作是:按键按下再松开,算按一次
/*按键按下后的具体指令位置*/
keytemp = 1; //键码值为1,对应UP键
}
}
if (key_Down == 0)
{
delays(10);
if (key_Down == 0)
{
delays (10);
while(!key_Down); //按键的完整操作是:按键按下再松开,算按一次
/*按键按下后的具体指令位置*/
keytemp = 2; //键码值为2,对应Down键
}
}
if (key_Enter == 0)
{
delays(10);
if (key_Enter == 0)
{
delays (10);
while(!key_Enter); //按键的完整操作是:按键按下再松开,算按一次
/*按键按下后的具体指令位置*/
keytemp = 3; //键码值为3,对应Enter键
}
}
if (key_Cancel == 0)
{
delays(10);
if (key_Cancel == 0)
{
delays (10);
while(!key_Cancel); //按键的完整操作是:按键按下再松开,算按一次
/*按键按下后的具体指令位置*/
keytemp = 4; //键码值为4,对应Cancel键
}
}
return keytemp;
}
void Menu_temp_judge()
{
fresh_keytemp = keyscan();
if (fresh_keytemp == 1) //按键效果:对应菜单1
{
/*替换成相应的函数*/
lcd_action_up();
}
else if(fresh_keytemp == 2) //按键效果:对应菜单二
{
lcd_action_down();
}
else if(fresh_keytemp == 3) //按键效果:对应菜单三
{
lcd_action_enter();
}
else if(fresh_keytemp == 4) //按键效果:对应菜单四
{
lcd_action_cancel();
}
else
{
//空
}
// delay(20);
}
复制代码
所有资料51hei提供下载:
成功实现LCD12864任意一行中间四个汉字的反白.zip
(70.62 KB, 下载次数: 164)
2017-12-23 08:30 上传
点击文件名下载附件
伪菜单和反白
下载积分: 黑币 -5
作者:
来生只想做头猪
时间:
2018-11-8 20:48
载了打不开。。。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1