我需要有一个1602的程序,PIC单片机的,最好有解释

我需要有一个1602的程序,PIC单片机的,最好有解释,第1张

请参考北航的《PIC16系列单片机C程序设计与PROTEUS仿真》一书,书中有PIC单片机与1604连接的完整线路,完整的C程序,并有1602,1604的详细介绍。

1602和1604只是在行数的差别,一个是2行的,一个是4行的,命令和接线都是一样的。

你好回答如下:

程序C和H文件:

#ifndef LCD_CHAR_1602_2005_4_9

#define LCD_CHAR_1602_2005_4_9

#include <intrinsh>

//Port Definitions

sbit LcdRs  = P2^0;

sbit LcdRw  = P2^1;

sbit LcdEn   = P2^2;

sfr  DBPort  = 0x80;  //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0数据端口

//内部等待函数

unsigned char LCD_Wait(void)

{

LcdRs=0;

LcdRw=1; _nop_();

LcdEn=1; _nop_();

//while(DBPort&0x80);//在用Proteus仿真时,注意用屏蔽此语句,在调用GotoXY()时,会进入死循环,

//可能在写该控制字时,该模块没有返回写入完备命令,即DBPort&0x80==0x80

//实际硬件时打开此语句

LcdEn=0;

return DBPort;

}

//向LCD写入命令或数据

#define LCD_COMMAND   0      // Command

#define LCD_DATA   1      // Data

#define LCD_CLEAR_SCREEN 0x01      // 清屏

#define LCD_HOMING    0x02      // 光标返回原点

void LCD_Write(bit style, unsigned char input)

{

LcdEn=0;

LcdRs=style;

LcdRw=0;  _nop_();

DBPort=input; _nop_();//注意顺序

LcdEn=1;  _nop_();//注意顺序

LcdEn=0;  _nop_();

LCD_Wait();

}

//设置显示模式

#define LCD_SHOW   0x04    //显示开

#define LCD_HIDE   0x00    //显示关

#define LCD_CURSOR   0x02  //显示光标

#define LCD_NO_CURSOR  0x00    //无光标

#define LCD_FLASH   0x01    //光标闪动

#define LCD_NO_FLASH  0x00    //光标不闪动

void LCD_SetDisplay(unsigned char DisplayMode)

{

LCD_Write(LCD_COMMAND, 0x08|DisplayMode);

}

//设置输入模式

#define LCD_AC_UP   0x02

#define LCD_AC_DOWN   0x00      // default

#define LCD_MOVE   0x01      // 画面可平移

#define LCD_NO_MOVE   0x00      //default

void LCD_SetInput(unsigned char InputMode)

{

LCD_Write(LCD_COMMAND, 0x04|InputMode);

}

//移动光标或屏幕

/

#define LCD_CURSOR  0x02

#define LCD_SCREEN  0x08

#define LCD_LEFT  0x00

#define LCD_RIGHT  0x04

void LCD_Move(unsigned char object, unsigned char direction)

{

if(object==LCD_CURSOR)

LCD_Write(LCD_COMMAND,0x10|direction);

if(object==LCD_SCREEN)

LCD_Write(LCD_COMMAND,0x18|direction);

}

/

//初始化LCD

void LCD_Initial()

{

LcdEn=0;

LCD_Write(LCD_COMMAND,0x38);           //8位数据端口,2行显示,57点阵

LCD_Write(LCD_COMMAND,0x38);

LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR);    //开启显示, 无光标

LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);   //清屏

LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE);       //AC递增, 画面不动

}

//

void GotoXY(unsigned char x, unsigned char y)

{

if(y==0)

LCD_Write(LCD_COMMAND,0x80|x);

if(y==1)

LCD_Write(LCD_COMMAND,0x80|(x-0x40));

}

void Print(unsigned char str)

{

while(str!='\0')

{

LCD_Write(LCD_DATA,str);

str++;

}

}

/

void LCD_LoadChar(unsigned char user[8], unsigned char place)

{

unsigned char i;

LCD_Write(LCD_COMMAND,0x40|(place8));

for(i=0; i<8; i++)

LCD_Write(LCD_DATA,user[i]);

}

/

//

#endif

#include <REGX52H>

#include "LCD1602h"

unsigned char TempBuffer[10];

void IntToStr(unsigned int t, unsigned char str, unsigned char n)

{

unsigned char a[5]; char i, j;

a[0]=(t/10000)%10;         //取得整数值到数组

a[1]=(t/1000)%10;

a[2]=(t/100)%10;

a[3]=(t/10)%10;

a[4]=(t/1)%10;

for(i=0; i<5; i++)         //转成ASCII码

a[i]=a[i]+'0';

for(i=0; a[i]=='0' && i<=3; i++);

for(j=5-n; j<i; j++)       //填充空格

{ str=' ';  str++; }

for(; i<5; i++)

{ str=a[i]; str++; }  //加入有效的数字

str='\0';

}

void Delay1ms(unsigned int count)

{

unsigned int i,j;

for(i=0;i<count;i++)

for(j=0;j<120;j++);

}

main()

{

unsigned int Count = 0;

LCD_Initial();

GotoXY(0,0);

Print("The 1602LCD Test");

GotoXY(0,1);

Print("zhaoyao");

while(1)

{

IntToStr(Count++,&TempBuffer[0],5);

GotoXY(3,1);

Print(&TempBuffer[0]);

Delay1ms(100);

}

}

1硬件连接接触不良、虚焊。

2LCD初始化函数写的不好,偶尔上电后初始化失败,就不能显示。建议上电延时一段时间,待LCD稳定后在执行初始化函数。

3程序上要注意读写时序,加入适当的延时时间。

4调节LCD第三脚V0的电压,调节到一个合适的值才可以显示。

先查硬件,确定没问题再在软件上找原因,只要细心,没有什么解决不了!祝你好运!

您好,您的问题是关于单片机LCD显示屏程序不亮的问题。首先,您需要检查您的硬件连接是否正确,以确保所有连接都得到正确的电源和信号。其次,您需要检查您的程序代码,确保它们正确地控制LCD显示屏,并且您的程序没有任何错误。最后,您可以尝试重新编程,以确保您的程序正确地写入到LCD显示屏中。如果以上措施都没有解决您的问题,您可以尝试更换LCD显示屏,以确保它仍然有效。

/

程序名称:带汉字库的12864液晶显示模块驱动

程序功能:显示字符 、汉字和

开发工具:Kile

MCU型号:AT89S52-24PU

时钟频率:110592MHZ

程序作者:yuan

版权说明:yuan

/

#include<reg52h>

#include "lcdh"

#include "utilh"

sbit E=P1^5;//脉冲使能

sbit RW=P1^6;//读写选择

sbit RS=P1^7;//数据命令选择

sbit rst=P3^6;//12864复位

// 延时ms函数:

// 12864检查状态函数:

void Check12864State(void)

{

P0=0xff;

E=0;//读状态前三控制线的状态

RS=0;

RW=1;

E=1;//拉高,读状态

while((P0&0x80)==0x80);//等待空闲

E=0;//写命令后三控制线的状态

RS=1;

RW=0;

}

// 12864写命令函数:

void Write12864Command( unsigned char com)

{

Check12864State();//检查状态

P0=com;//赋值

E=0;//写命令前三控制线的状态

RS=0;

RW=0;

E=1;//拉高,写命令

E=0;//写命令后三控制线的状态

RS=1;

RW=1;

}

//12864写数据函数:

void Write12864Data( unsigned char dat)

{

Check12864State();//检查状态

P0=dat;//赋值

E=0;//写数据前三控制线的状态

RS=1;

RW=0;

E=1;//拉高,写数据

E=0;//写数据后三控制线的状态

RS=0;

RW=1;

}

//在指定的位置显示字符串(汉字和ASCII码字符)函数:

void LCD12864DisplayString( unsigned char y,unsigned char x, unsigned char pstr)

//y-行数值0-3,x-列数值0-7,pstr-字符串指针

//12864可以显示32个汉字(四行每行8个),一个地址对应一个汉字

//可以显示64个ASCII码字符(四行每行16个),一个地址对应两个字符

//为了实现自动换行功能,这个函数比较繁琐

{

unsigned char row,n=0;

Write12864Command(0x30);//基本指令

Write12864Command(0x06);//地址计数器自动加以,光标右移

switch(y)//根据行号选择行地址

{

case 0:row=0x80;break;//第一行首地址

case 1:row=0x90;break;//第二行首地址

case 2:row=0x88;break;//第三行首地址

case 3:row=0x98;break;//第四行首地址

default:;

}

Write12864Command(row+x);//写地址

while(pstr!='\0')

{

Write12864Data(pstr);//写字符

pstr++;

n++;//计数

if((n+x2)==16)//如果一行写完 ,继续写第二行

{

if(y==0) Write12864Command(0x90);//写下一行地址

else if(y==1) Write12864Command(0x88);//写下一行地址

else if(y==2) Write12864Command(0x98);//写下一行地址

else ;

}

else if((n+x2)==32)//如果第二行写完 ,继续写第三行

{

if(y==0) Write12864Command(0x88);//写下一行地址

else if(y==1) Write12864Command(0x98);//写下一行地址

else ;

}

else if((n+x2)==48)//如果第三行写完 ,继续写第四行

{

if(y==0) Write12864Command(0x98);//写下一行地址

else ;

}

else ;

}

}

//模式清屏函数:

void Clear12864Screen()

{

unsigned char i,j;

Write12864Command(0x34);//功能设定:8位控制方式,使用扩充指令

Write12864Command(0x36);//使用扩充指令,绘图显示控制

for(i=0;i<32;i++)

//ST7920可控制25632点阵(32行256列),而12864液晶实际的行地址只有0-31行,

//12864液晶的32-63行的行是0-31行地址从第128列划分一半出来的,所以分为上下两半屏,

//也就是说第0行和第32行同属一行,行地址相同;第1行和第33行同属一行,以此类推

{

Write12864Command(0x80|i);//写行地址(垂直地址)

Write12864Command(0x80);//写列地址(水平地址)

for(j=0;j<32;j++)

Write12864Data(0x00);//清屏

}

}

//在任意位置显示任意大小的函数:

void LCD12864DisplayPictrue(unsigned char y,unsigned char x,

unsigned char px,unsigned char py, unsigned char pp)

//y-起始行(数值0-63),x-起始列(16位宽,数值0-7),

//px-宽度,py-高度,pp-指针指向数组

//因为上下屏的地址不连续,要在任意位置显示完整的图像,处理起来比较繁琐

{

unsigned char i,j,k;

Clear12864Screen();//清屏

if(y<32)//如果起始行在上半屏

{

k=32-y;//算出上半屏的行数

for(i=0;i<k;i++,y++)//上半屏行数

{

Write12864Command(0x80|y);//写行地址(垂直地址)

Write12864Command(0x80|x);//写列地址(水平地址)

for(j=0;j<px/8;j++)

Write12864Data(pp[ipx/8+j]);//写数据

}

y=0;//下半屏起始行,接上半屏继续写数据

for(;i<py;i++,y++)//下半屏剩下的行数

{

Write12864Command(0x80|y);//写行地址(垂直地址)

Write12864Command(0x80|(8+x));//写列地址(水平地址)

for(j=0;j<px/8;j++)

Write12864Data(pp[ipx/8+j]);//写数据

}

}

else //如果起始行在下半屏

{

for(i=0;i<py;i++,y++)//行数

{

Write12864Command(0x80|(y-32));//写行地址(垂直地址)

Write12864Command(0x80|(8+x));//写列地址(水平地址)

for(j=0;j<px/8;j++)

Write12864Data(pp[ipx/8+j]);//写数据

}

}

}

void Clear12864Text()

{

Write12864Command(0x34);//清屏

DelayMs(5);

Write12864Command(0x30);//清屏

DelayMs(5);

Write12864Command(0x01);//清屏

DelayMs(5);

}

//12864初始化函数:

void Initialize12864()

{

rst=0;//复位12864

DelayMs(30);

rst=1;

DelayMs(20);

Write12864Command(0x30);//功能设定:8位控制方式,使用基本指令

Write12864Command(0x08);//显示关

Write12864Command(0x01);//清屏

Write12864Command(0x06);//地址计数器加一、光标右移

Write12864Command(0x0c);//显示开

}

带字库的驱动

以上就是关于我需要有一个1602的程序,PIC单片机的,最好有解释全部的内容,包括:我需要有一个1602的程序,PIC单片机的,最好有解释、谁有单片机控制1602的显示程序要proteus能仿真成功的、lcd1602有时候单片机下程序能显示有时不能显示是什么原因求助!谢谢!等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/10131716.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-05
下一篇 2023-05-05

发表评论

登录后才能评论

评论列表(0条)

保存