标题:
51单片机1602液晶显示 有没有大佬给一个程序 试了很多次都不对 求分享
[打印本页]
作者:
liyang129
时间:
2022-5-15 14:14
标题:
51单片机1602液晶显示 有没有大佬给一个程序 试了很多次都不对 求分享
有没有大佬给一个程序 试了很多次 都不对
作者:
lkc8210
时间:
2022-5-16 10:35
试试这个
#include <reg51.h>
#include"intrins.h"
#define LCD_Dat P0
sbit lcd_rs = P2 ^ 0;
sbit lcd_rw = P2 ^ 1;
sbit lcd_e = P2 ^ 2;
void delay(unsigned int x)//t = 18.45 + x * 9.77 us @11.0592Mhz
{
while(x--);
}
void lcd_write_cmd(unsigned char cmd) //写命令函数
{
lcd_rs = 0;
lcd_rw = 0;
LCD_Dat = cmd;
lcd_e = 1;
lcd_e = 0;
delay(3);//>40us
}
void lcd_write_date(unsigned char date) //写数据函数
{
lcd_rs = 1;
lcd_rw = 0;
LCD_Dat = date;
lcd_e = 1;
lcd_e = 0;
delay(3);//>40us
}
void lcd_init() //LCD初始化函数
{
lcd_write_cmd(0x38);
lcd_write_cmd(0x0c);
lcd_write_cmd(0x06);
lcd_write_cmd(0x01);
delay(200);//>1.7ms
}
void lcd_show_char(unsigned char column, unsigned char dat)
{
if(column == 1)
lcd_write_cmd(0x80);
else
lcd_write_cmd(0xC0);
lcd_write_date(dat);
}
void lcd_show_str(unsigned char column, unsigned char *dat)
{
if(column == 1)
lcd_write_cmd(0x80);
else
lcd_write_cmd(0xC0);
do
{
lcd_write_date(*dat);
} while(*dat++);
}
void main()
{
lcd_init();
lcd_show_str(1, "LCD1602 Demo");
lcd_show_str(2, "Hello World!");
while(1)
{
}
}
复制代码
作者:
hy47566398
时间:
2022-5-16 17:26
LCD1602.H
#ifndef __LCD1604__H
#define __LCD1604__H
#include "def.h"
//行控制码1602&1604通用
#define LINE0 0x80
#define LINE1 0xC0
#define LINE2 0x90
#define LINE3 0xD0
#ifdef _USE_SHOP_A_
//P2口接LCD的D0~D7
#define LCD1602_DATA P2
//LCD的RS、RW、E脚
sbit LCD1602_RS = P0^4;
sbit LCD1602_E = P0^5;
sbit LCD1602_RW = P0^6;
//与LCD12864用同一P2口
//置PSB=1插上也能亮
sbit PSB = P0^7;
#endif
#ifdef _LY5A_L2A_
sbit BEEP = P1^5;
#define LED_PORT P2
//P2口接LCD的D0~D7
#define LCD1602_DATA P0
//LCD的RS、RW、E脚
sbit LCD1602_RS = P1^0;
sbit LCD1602_RW = P1^1;
sbit LCD1602_E = P1^2;
//与LCD12864用同一P2口
//置PSB=1插上也能亮
sbit PSB = P1^6;
#endif
//LCD初如化
void LcdInit();
//LCD清屏
void LcdClr();
//清某一行
void LcdClr0();
void LcdClr1();
//void LcdClr2();
//void LcdClr3();
/*****************************************************************************************
* 在指定坐标显示整型数字
*------------------------
* x,y : 横纵屏幕坐标(列,行)
* num : 要显示的整型数字
* nDispW: 要显示的占位宽度(0~16个字符),0-基本的显示,不设定(后两位参就无意义了)
* bRightAlign : 0-左对齐,1-右对齐
* bLeftAdd0 : 右对齐时的数字前导空,左边是否补0,0-不补0,1-补0
*******************************************************************************************/
void LcdDisplayNum(u8 x, u8 y, const long num, u8 nDispW , bool bRightAlign, bool bLeftAdd0);
/**********************************************
* 在指定(列,行)位置显示字符串
**********************************************/
void LcdDisplayStr(u8 x, u8 y, const char *msg);
#endif
复制代码
LCD1604.c
///////////////////////////////////////////////////////////////////////////////////////
// LCD1602&LCD1604字符显示功能
//
// LCD1602_RW 不用功能电路不接入这个脚
//-----------------------------------------------------------------------------------
#include <string.h>
#include <intrins.h>
#include "LCD1602.h"
void delay1Cycle(unsigned int cycle)
{
unsigned int i;
for(i=0; i<cycle; i++)
{
_nop_();
}
}
/*OK
bool LcdBusy()
{
bit b;
LCD1602_RS = 0;
LCD1602_RW = 1;
delay1Cycle(5);
LCD1602_E = 1;
delay1Cycle(5);
b = LCD1602_DATA & 0x80;
LCD1602_E = 0;
return b;
}
*/
//------------------------------------------------
//LCD E口跳变时,LCD显示一个字符/接收一个指令
//RS=0:命令指令,RS=1:显示数据指令
//------------------------------------------------
void LcdWriteInfo( u8 RS, u8 RW, u8 dat )
{
//while(LcdBusy());
LCD1602_RS = RS;
LCD1602_E = 0;
LCD1602_RW = RW;
LCD1602_DATA = dat;
delay1Cycle(5);
LCD1602_E = 1;
delay1Cycle(5);
LCD1602_E = 0;
delay1Cycle(25);
}
//---------------------------
//RS=0,指令寄存器
//RW=0,写数据
//---------------------------
void LcdWriteCom( u8 com )
{
LcdWriteInfo( 0, 0, com );
}
//--------------------------
//RS=1,数据寄存器
//--------------------------
void LcdWriteData(u8 dat)
{
LcdWriteInfo( 1, 0, dat );
}
//---------------
//LCD初如化
//---------------
void LcdInit()
{
//要等待开机启稳
//否则显示错位不全
delay1Cycle(1000);
PSB = 1; //与开发板LCD12864同一数据口
//让12864插上也能有字,但...
LcdWriteCom(0x38); //开显示:0011 1000
LcdWriteCom(0x38); //刚开机,各方电位还不稳定
LcdWriteCom(0x38); //重要的事情说三便
LcdWriteCom(0x0c); //不显示光标:0000 1100
LcdWriteCom(0x06); //光标右移:0000 0110
LcdWriteCom(0x01); //清屏
//别着急,抽根烟
delay1Cycle(1000);
}
//---------------
//LCD清屏
//---------------
/*OK
void LcdClr()
{
LcdWriteCom(0x01); //清屏
}
*/
/**********************************************
* 在指定位置显示字符串
**********************************************/
void LcdDisplayStr(u8 x, u8 y, const char *msg)
{
char *p1 = msg;
char *p2 = 0;
u8 xx, nlen=0;;
if( x>15 || y>3 ) return;
//取显示字串长度
nlen = strlen(msg);
if(nlen==0) return;
if(nlen>32) nlen=32;
//p2-折行字串指针
//只显示一个折行
if(nlen<=16-x)
p2 = 0; //字串只用显示一行
else
p2 = p1 +16 - x; //字串长度过长有折行
//显示列控制码
if(y==0) LcdWriteCom(LINE0+x); //第一行显示
if(y==1) LcdWriteCom(LINE1+x); //第二行
if(y==2) LcdWriteCom(LINE2+x); //第三行
if(y==3)
{ p2 = 0; LcdWriteCom(LINE3+x);} //第四行
for(xx = x; xx<16; xx++)
{
LcdWriteData( *p1 );
p1++;
if(*p1=='\0') break;
}
//有折行时
if(p2!=0)
{
if(y==0) LcdWriteCom(LINE1);
if(y==1) LcdWriteCom(LINE2);
if(y==2) LcdWriteCom(LINE3);
for(xx = 0; x<16; xx++)
{
LcdWriteData( *p2 );
p2++;
if(*p2=='\0') break;
}
}
}
/*****************************************************************************************
* 在指定坐标显示整型数字
*------------------------
* x,y : 横纵屏幕坐标
* num : 显示整型数字
* nDispW: 显示占位宽度,当宽度小于显示数字宽度时,此值无效
* bRightAlign : 0-左对齐,1-右对齐
* bLeftAdd0 : 数字前导空左边是否补0,0-不补0,1-补0
*******************************************************************************************/
void LcdDisplayNum(u8 x, u8 y, const long num, u8 nDispW, bool bRightAlign, bool bLeftAdd0)
{
u8 w=0, i=0;
char num_str[17]={'*'};
char strBuff[17]={0x20};
long tmp = 0;
if(x>15 || y>3) return;
if(nDispW>16) nDispW=16;
//负数不支持左补0
if(num<0) bLeftAdd0 = 0;
tmp = num>0 ? num : num * (-1);
//取字长度,数字到临时字符串中
while(1)
{
w++;
strBuff[i] = tmp%10 + '0';
if(tmp<10) break;
tmp = tmp/10;
i++;
}
//负号(-)
if(num<0) {strBuff[i+1]='-';w++;}
if(nDispW<w) nDispW=0;
//宽度内填空格
if(nDispW>0)
{
for(i=0; i<nDispW; i++)
num_str[i] = 0x20;
}
//左补0的条件:给定宽度是否右对齐
if(bLeftAdd0==1 && nDispW>0 && bRightAlign==1 )
{
for(i=0; i<nDispW; i++)
num_str[i] = '0';
}
if(nDispW>0)
{
if(bRightAlign)
memcpy(num_str, strBuff, w);
else
memcpy(num_str+nDispW-w, strBuff, w);
}
else
{
memcpy(num_str, strBuff, w);
}
//应以最宽的值
w = (nDispW > w ? nDispW : w);
if(y==0) LcdWriteCom(LINE0+x);
if(y==1) LcdWriteCom(LINE1+x);
if(y==2) LcdWriteCom(LINE2+x);
if(y==3) LcdWriteCom(LINE3+x);
for( i=w; i>0; i-- )
{//LCD显示
LcdWriteData( num_str[i-1] );
}
}
/********************
*清行
********************
OK
void LcdClrLine(u8 y)
{
u8 x;
if(y>3) return;
//
if(y==0) LcdWriteCom(LINE0); //第一行
if(y==1) LcdWriteCom(LINE1); //第二行
if(y==2) LcdWriteCom(LINE2); //第三行
if(y==3) LcdWriteCom(LINE3); //第四行
for(x = 0; x<16; x++)
{
LcdWriteData( 0x20 );
}
}
void LcdClr0()
{
LcdClrLine(0);
}
void LcdClr1()
{
LcdClrLine(1);
}
/*OK
void LcdClr2()
{
LcdClrLine(2);
}
void LcdClr3()
{
LcdClrLine(3);
}
*/
复制代码
def.h
#ifndef __DEF__H__
#define __DEF__H__
#include <reg52.h>
#ifndef u8
#define u8 unsigned char
#endif
#ifndef bool
#define bool bit
#define false 0
#define true 1
#endif
#ifndef u16
#define u16 unsigned int
#endif
#ifndef u32
#define u32 unsigned long
#endif
#ifndef NULL
#define NULL 0
#endif
#define ON 1
#define OFF 0
#define _ON 0
#define _OFF 1
//ShopAxxx开发板
#ifdef _USE_SHOP_A_
sbit BEEP = P1^2; //1 - off 蜂鸣器
sbit RELAY = P1^0; //1 - off 继电器
sbit _LE = P1^5; //0 - off 74HC573(/LE),控制P2口的LED
#endif
#endif
复制代码
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1