完全使用3个IO口驱动LCD1602
8051三线传送数据到74HC595,驱动LCD1602.利用位变量可位操作,程序更加简单。根据网上别人的程序改编而来。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
/*hc595->1602管脚连接bin(D7,D6,D5,D4,0,E,RW,RS)*/
#include <reg52.h>
//8051->hc595引脚定义
sbit LCD1602_SHCP=P3^6; //in clock
sbit LCD1602_DS=P3^4; //in data
sbit LCD1602_STCP=P3^5; //out clock
//两种数据类型
typedef unsigned char uchar;
typedef unsigned int uint;
//定义数据槽
//uchar RS,RW,E,D4,D5,D6,D7;
bdata uchar sendData;
sbit RS = sendData^0;
sbit RW = sendData^1;
sbit E = sendData^2;
单片机源程序如下:
- #include <reg52.h>
- #include "lcd595.h"
- const uchar type_t[]={
- 0x1f,0x02,0x02,0x02,
- 0x02,0x02,0x02,0x00
- };
- const uchar line1[]="Have a nice day!";
- const uchar line2[]="HE Wcommands";
- void main()
- {
- uchar i;
- LcdInit();
- LcdWriteCGRAM(0x00,type_t);
- LcdWriteData(0x00);
- LcdWriteCom(0x81);
- LcdPrintf("HE With");
- LcdWriteCom(0xc0);
- LcdPrintf("Commands");
- Lcd1602_Delay1ms(1000);
- LcdWriteCom(0x01);
- while(1){
- for(i=0;i<16;i++){
- LcdWriteCom(0x80+i);
- LcdWriteData(line1[i]);
- Lcd1602_Delay1ms(100);
- }
- Lcd1602_Delay1ms(500);
- LcdWriteCom(0xc1);
- LcdWriteData(0x00);
- Lcd1602_Delay1ms(100);
- for(i=0;i<12;i++){
- LcdWriteCom(0xc2+i);
- LcdWriteData(line2[i]);
- Lcd1602_Delay1ms(100);
- }
- LcdWriteCom(0x01);
- Lcd1602_Delay1ms(100);
- }
- }
复制代码- /*hc595->1602管脚连接bin(D7,D6,D5,D4,0,E,RW,RS)*/
- #include <reg52.h>
- //8051->hc595引脚定义
- sbit LCD1602_SHCP=P3^6; //in clock
- sbit LCD1602_DS=P3^4; //in data
- sbit LCD1602_STCP=P3^5; //out clock
- //两种数据类型
- typedef unsigned char uchar;
- typedef unsigned int uint;
- //定义数据槽
- //uchar RS,RW,E,D4,D5,D6,D7;
- bdata uchar sendData;
- sbit RS = sendData^0;
- sbit RW = sendData^1;
- sbit E = sendData^2;
- sbit D4 = sendData^3;
- sbit D5 = sendData^4;
- sbit D6 = sendData^5;
- sbit D7 = sendData^6;
- void Lcd1602_Delay1ms(uint c); //延时函数,延时1ms
- void LCD1602_DATAPINS(uchar value); //更改74HC595连接LCD1602的数据
- void LcdCalc(uchar i); //确定4位总线
- void LcdWriteCom(uchar com); //向LCD写入一个字节的命令
- void LcdWriteData(uchar dat); //向LCD写入一个字节的数据
- void LcdInit(); //初始化LCD屏
- void LcdPrintf(uchar *s); //向屏幕输出字符
- void LcdWriteCGRAM(uchar index,uchar *p); //建立一个自定义字符
- void LCDPrintNum(uint num,uchar wei); //显示数字
- /*******************************************************************************
- * 函 数 名 : Lcd1602_Delay1ms
- * 函数功能 : 延时函数,延时1ms
- * 输 入 : c
- * 输 出 : 无
- * 说 名 : 该函数是在12MHZ晶振下,12分频单片机的延时。
- *******************************************************************************/
- void Lcd1602_Delay1ms(uint c) //误差 0us
- {
- uchar a,b;
- for(;c>0;c--){
- for(b=199;b>0;b--){
- for(a=1;a>0;a--);
- }
- }
- }
- /*******************************************************************************
- * 函 数 名 : LCD1602_DATAPINS
- * 函数功能 : 更改74HC595连接LCD1602的数据
- * 输 入 : value
- * 输 出 : 无
- 74HC595传送数据的常用写法
- *******************************************************************************/
- void LCD1602_DATAPINS(uchar value)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- LCD1602_DS=value&0x80;//取数据高位
- if(LCD1602_DS==0x80){ //判断数据高位是否为1
- LCD1602_DS=1;//如果高位为1,DS置1
- }
- else{
- LCD1602_DS=0;//否则DS置0
- }
- LCD1602_SHCP=0;
- LCD1602_SHCP=1;//上升沿使这一位写入移位寄存器
- value<<=1;//数据左移1位,数据的第7位变为最高位,循环第8次时数据的最低位也变成最高位
- }
- LCD1602_STCP=0;
- LCD1602_STCP=1;//给STCP一个上升沿,将for循环中输入的数据移入输出锁存寄存器,刷新输出数据
- }
- void LcdWriteCom(uchar com) //写入命令
- {
- //LcdCalc(com>>4); //发送高四位
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
Keil代码与Proteus仿真下载:
利用可位寻址变量-hc595-1602.zip
(102.37 KB, 下载次数: 30)
|