单片机键盘及1602显示程序

单片机键盘及1602显示程序,第1张

我有 at89s52 的键盘 和1602初始化程序,你可以组装一下,

STC12C5A08AD单片机和at89s52 差不多。

#include<at89x52h>

#include<intrinsh>

sbit d_i=P1^0;

sbit r_w=P1^1;

sbit e=P1^2;

#define uchar unsigned char

#define nop _nop_()

void delay(unsigned int ttt) // 长延时,ttt为延时的mS数

{

unsigned int aaa;

while(ttt--) // 延时约1mS

{

aaa=89;

while(aaa--);

}

}

void wcom(uchar cmd);

void wddr(uchar dat);

void checkbusy();

void lcd_init();

void display();

void main()

{

delay(40);

lcd_init();

while(1){

display();}

}

void lcd_init()

{

delay(15);

wcom(0x01);

delay(5);

wcom(0x38);

delay(5);

wcom(0x38);

delay(10);

wcom(0x0c);

delay(5);

wcom(0x06);

delay(5);

wcom(0x01);

delay(5);

}

void wcom(uchar cmd)

{

checkbusy();

d_i=0;

r_w=0;

e=0;

P0=cmd;

nop;

nop;

nop;

nop;

e=1;

nop;

nop;

nop;

nop;e=0;

}

void wddr (uchar dat)

{

checkbusy();

d_i=1;

r_w=0;

e=0;

P0=dat;

nop;nop;

nop;nop;

e=1;

nop;nop;

nop;nop;

e=0;

}

void checkbusy ()

{ bit result;

d_i=0;

r_w=1;

P0=0xff;

e=0;

nop;nop;

e=1;

nop;

nop;nop;

nop;

do {delay(1);

result = (bit)(P0&0x80);}

while(result!=0);

e=0;}

void display()

{// wcom(0x80);

wddr(0x61);

delay(100);

}

/取键值函数/

uchar keyscan()

{

uchar hang=0x00,lie=0x01,i=0x00;

uchar lcode,hcode;

uchar keynumber=0xff;

P2=0xf0;

if((P2&0xf0)!=0xf0)

{

delay(15); //去抖动

if((P2&0xf0)!=0xf0)

{

hcode=0xfe; //从第一行开始查

while((hcode&0x10)!=0)

{ P2=hcode;

if((P2&0xf0)!=0xf0)

{

lcode=(P2&0xf0)|0x0f;

//nop;nop;nop;nop;

//shortdelay(2);

lcode=(~lcode)>>4;

while(lie!=lcode) //判断在第几列(通过移动到某一位,是否匹配)

{ lie=lie<<1; //变量移动后要赋值

i++;

}

lie=i;

keynumber=hang4+lie;// 键值

//shortdelay(5); //开始程序不健壮,加上延时就可以稳定显示了,现在去掉也没问题

// nop;nop;nop;nop;

return (keynumber);

//break; //当初以为返回值后,不能跳出故加上;现在也可去掉

}

else

{

hcode=(hcode<<1)|0x01;

hang++;//下一次扫描第hang行,行值

}

}

}

}

else return (keynumber);

}

代码贴出,供大家参考

需要设定开始地址和移动方式,而后写入数据地址自动加1,给你一段驱动程序,看你会用么

首先是库文件,自己建立一个LCD1602h文件,用记事本或编译器打开,将代码粘贴进去,该文件放在项目文件夹下

#ifndef __LCD1602_H__

#define __LCD1602_H__

#include<reg52h>

#include"timerh"

/以下为函数开关/

//#define LCD1602_CKECKBUSY

//#define LCD1602_CLEANSCREEN

#define LCD1602_DISPLAYSTR

#define LCD1602_DSIPLAYINT

//

#define lcd_port P0  //LCD1602总线接口

sbit lcdrs = P2^3; //寄存器选择,高电平1选择数据寄存器、低电平0选择指令寄存器。

sbit lcden = P2^5; //使能端,写 *** 作时,下降沿使能,读 *** 作时,E高电平有效

sbit lcdrw = P2^4; //读写选通,高电平读,低电平写。

//注意改驱动不支持从LCD读取数据

void LCD1602_initialise(); //初始化函数,开机后,显示内容之前,请初始化

#ifdef LCD1602_CLEANSCREEN

void LCD1602_cleanScreen(bit rewind); //清屏函数(rewind为0),或使光标归位(rewind为1时)

#endif

#ifdef LCD1602_DISPLAYSTR //显示字符(串)

void LCD1602_displayStr(unsigned char row,unsigned char position,unsigned char dat);

#endif

#ifdef LCD1602_DSIPLAYINT     //显示整型数据(-32767~32767)

void LCD1602_displayInt(unsigned char row,unsigned char position,int dat); //一次写入整型数(-32767~32767),position为开始位置

#endif

void LCD1602_setCmd(unsigned char command); //设定子函数  写指令或设定地址

void LCD1602_writeData(unsigned char dat); //向LCD1602写入数据,记得先用写指令函数设定地址

#ifdef LCD1602_CKECKBUSY

 bit LCD1602_checkBusy(); //判忙函数,忙返回值为1

#endif

//

/ row显示位置行选择,0为第一行,1为第二行            /

/ position显示位置的其实位置,为该行所在位置,值:0~15          /

/ dat为显示内容                                                 /

//

#endif

以下是驱动源代码,自己建立一个LCD1602c文件,用记事本或编译器打开,复制粘贴进去:

该文件放在项目文件夹下

#include"LCD1602h"

void delay(unsigned int ms)//延时大约1ms

{

unsigned int i;

for(;ms>0;ms--)

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

}

void delayMicroseconds(unsigned int us)

{

for(;us>4;us-=4);

}

void LCD1602_setCmd(unsigned char command)         //设定子函数  写指令

{  

lcdrs=0;  //当lcdrs=0 时,允许写入指令  

lcd_port=command;  

delayMicroseconds(5);  

lcden=1; 

delayMicroseconds(5);  

lcden=0; 

}

void LCD1602_writeData(unsigned char dat)            //写数据

{  

lcdrs=1;               //当lcdrs=1 时,允许写入显示  

lcd_port=dat;  

delay(1);

lcden=1;               //lcden高脉冲将P0口数据读走  

delayMicroseconds(5);  

lcden=0; 

#ifdef LCD1602_CLEANSCREEN

void LCD1602_cleanScreen(bit rewind) //清屏或光标归位函数

{

if(rewind)

LCD1602_setCmd(0x02); //光标归位指令

else

LCD1602_setCmd(0x01); //清屏指令

delay(5);

}

#endif

#ifdef LCD1602_CKECKBUSY

bit LCD1602_checkBusy(void) //判忙函数

{

lcd_port=0xFF;

lcdrs=0;

lcdrw=1;

lcden=0;

delayMicroseconds(1);

lcden=1;

return !(bit)(lcd_port&0x80);

}

#endif

void LCD1602_initialise()                     //初始化函数

{

lcden=0;

lcdrw=0;

LCD1602_setCmd(0x38);               //指令码:设置16X2显示,5X7点阵,8位数据接口  

LCD1602_setCmd(0x0C);               //指令码:开显示,不显示光标  

LCD1602_setCmd(0x06);               //指令码:指针加一,整屏不移动  

LCD1602_setCmd(0x01);               //显示清屏 

delay(10); //稍停顿下,让LCD正确配置好

} ///

#ifdef LCD1602_DISPLAYSTR

void LCD1602_displayStr(unsigned char row,unsigned char position,unsigned char dat)//一次写入字符串(超出不显示),position为开始位置

{

LCD1602_setCmd(0x80+0x40row+position);

while(dat)

{

LCD1602_writeData(dat++);

}

}

#endif

#ifdef LCD1602_DSIPLAYINT

void LCD1602_displayInt(unsigned char row,unsigned char position,int dat) //一次写入整型数(-32767~32767),position为开始位置

{

unsigned char str[7];

unsigned char i=0;

bit flag=0;

if(dat==0)

{

str[i++]=0x30;

}

else 

{

if(dat<0)

{

str[i++]=0x2D;

dat=-dat;

}

if(dat/10000  ||flag){str[i++]=dat/10000+0x30;  flag=1;}

if(dat/1000%10||flag){str[i++]=dat/1000%10+0x30;flag=1;}

if(dat/100%10 ||flag){str[i++]=dat/100%10+0x30; flag=1;}

if(dat/10%10  ||flag){str[i++]=dat/10%10+0x30;  flag=1;}

if(dat%10     ||flag){str[i++]=dat%10+0x30;    }

}

str[i]=0;

flag=0;

i=0;

LCD1602_setCmd(0x80+0x40row+position);

while(str[i])

{

LCD1602_writeData(str[i++]);

}

}

#endif

1、需要修改引脚设置,就到LCD1602h中修改

2、主函数头写上#include“LCD1602h”,将“LCD1602c”添加到项目中

3、使用的时候先调用LCD1602_initialise();对1602初始化;其中光标移动方式已经设定好了

4、根据需要开关函数开关(注释掉定义就是关闭相应函数,取消注释则是打开),调用相关函数。关于函数功能,库文件注释得很详细,请自行查看;

提供一段main()函数代码,供参考:

#include<REG52h>

#include"LCD1602h"

void main(void)

{

    LCD1602_initialise();

    LCD1602_displayStr(0,0,"Hello World!");

    LCD1602_displayInt(1,0,2015);

    while(1);

}

手打不易,望采纳!

这是为你量身制作的,希望你能喜欢,光标根据按键在数字下面闪烁,一定符合你的要求,给你截了一张效果图

#include<reg52h>

#include<intrinsh>

#define uchar unsigned char

#define uint unsigned int

#define ulong unsigned long

uchar code table[]="1602";

sbit key1=P1^0;

sbit key2=P1^1;

sbit key3=P1^2;

sbit key4=P1^3;

sbit rs=P2^0;

sbit rw=P2^1;

sbit en=P2^2;

void delay(uint z)

{

uint x,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

void write_com(uchar com)

{

rs=0;

rw=0;

en=0;

P0=com;

delay(5);

en=1;

delay(5);

en=0;

}

void write_dat(uchar dat)

{

rs=1;

rw=0;

en=0;

P0=dat;

delay(5);

en=1;

delay(5);

en=0;

}

void init()

{

uchar i;

write_com(0x38);

write_com(0x0c);

write_com(0x06);

write_com(0x01);

write_com(0x86);

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

{

write_dat(table[i]);

delay(5);

}

}

void main()

{

init();

while(1)

{

if(key1==0)

{

delay(10);

if(key1==0)

{

while(key1==0);

write_com(0x86);

write_com(0x0f);

}

}

if(key2==0)

{

delay(10);

if(key2==0)

{

while(key2==0);

write_com(0x87);

write_com(0x0f);

}

}

if(key3==0)

{

delay(10);

if(key3==0)

{

while(key3==0);

write_com(0x88);

write_com(0x0f);

}

}

if(key4==0)

{

delay(10);

if(key4==0)

{

while(key4==0);

write_com(0x89);

write_com(0x0f);

}

}

}

}

1602不能显示汉字 。。这是我以前写的MEGA128的哦#include<iom128vh>

#define uchar unsigned char

#define uint unsigned int

#define RS 0

#define RW 1

#define EN 2

uchar wz[]={"ssssssssss"};

uchar gd[]={"ssssssssss"};

void s_ms(uint ms)

{

for(;ms>1;ms--);

}

void busy(void)

{

uchar temp;

s_ms(500);

PORTC&=~(1<<RS); //RS=0

s_ms(500);

PORTC|=(1<<RW); //RW=1

s_ms(500);

while(temp)

{

PORTC|=(1<<EN); //EN=1

s_ms(500);

DDRA=0x00; //A口变输入

PORTA=0xff; //上拉使能

s_ms(500);

temp = PINA&0x80; //读取A口

s_ms(500);

DDRA=0xff;

PORTA=0xff; //A口变输出

s_ms(500);

PORTC&=~(1<<EN); //EN=0

s_ms(500);

}

}

void writecom(uchar com)

{

busy();

s_ms(500);

PORTC&=~(1<<RS); //RS=0

s_ms(500);

PORTC&=~(1<<RW); //RW=0

s_ms(500);

PORTC|=(1<<EN); //EN=1

s_ms(500);

PORTA = com; //输出指令

s_ms(500);

PORTC&=~(1<<EN); //EN=0

s_ms(500);

}

void WriteChar(uchar row,uchar col,uint num,uchar pBuffer)

{

uchar i,j,t;

if (row == 1) row = 0x80 + col;

else row = 0xC0 + col;

writecom(row);

PORTC|=(1<<RS);

s_ms(500);

PORTC&=~(1<<RW);

s_ms(500);

for(i=num;i!=0;i--)

{

t=pBuffer;

s_ms(500);

writedata(t);

s_ms(500);

pBuffer++;

}

}

void LcdInit(void)

{

writecom(0x38);

s_ms(1000);

writecom(0x01);

s_ms(10000);

writecom(0x02);

s_ms(1000);

writecom(0x06);

s_ms(1000);

writecom(0x0c);

s_ms(1000);

writecom(0x38);

s_ms(1000);

}

void writedata(uchar data)

{

busy();

s_ms(500);

PORTC|=(1<<RS); //RS=1

s_ms(500);

PORTC&=~(1<<RW); //RW=0

s_ms(500);

PORTC|=(1<<EN); //EN=1

s_ms(500);

PORTA = data; //输出数据

s_ms(500);

PORTC&=~(1<<EN); //EN=0

s_ms(500);

}

main()

{

DDRA=0xff;

PORTA=0xff;

DDRC=0xff;

PORTC=0xff;

LcdInit();

WriteChar(1,1,13,wz);

WriteChar(2,3,10,gd);

}

你可以使用电脑的串口,或是并口,来跟1602连接。

当然,中间可能需要一些TTL讯号准位的IC,来做沟通与连接。

并口,可使用IO378H位址。

你可以搜索百度文库。。。

基于PC打印口的IO接口扩展

打印口分析及应用扩展

你这个接线就不合理 引脚4、5、6是控制端竟然没接给你个图参考

再给你一个仿真中的接线图和程序 你自己试试看

程序:

RS EQU P37

RW EQU P36

E EQU P35

mov p3,#0ffh

MOV P1,#01H ;清除屏幕

ACALL ENABLE

MOV P1,#38H ;8位点阵

ACALL ENABLE

MOV P1,#0FH ;开显示

ACALL ENABLE

MOV P1,#06H ;移动光标

ACALL ENABLE

MOV P1,#80H ;显示位置

ACALL ENABLE

l3: mov p1,#01h

acall enable

mov dptr,#table1 ;送第一句话

call write1

call enable

MOV P1,#0C0H ;写入显示起始地址(第二行第一个位置)

ACALL ENABLE ;调用写入命令子程序

call write1

call enable

mov p1,#01h

call delay1

call delay1

call delay1

jmp l3

ENABLE: ;送命令

CLR RS

CLR RW

CLR E

ACALL DELAY

SETB E

RET

write1: ;送字符串

mov r1,#00h

a1:mov a,r1

movc a,@a+dptr

call write2

inc r1

cjne a,#00h,a1 ;以00H做字符串结束标志

ret

write2: ;送单个字符

mov p1,a

setb rs

clr rw

clr e

call delay

setb e

ret

delay: ;延时子程序

mov r7,#255

d1:mov r6,#255

d2:djnz r6,d2

djnz r7,d1

ret

delay1:

mov r7,#255

delay2:mov r6,#255

djnz r6,$

djnz r7,delay2

ret

table1: db 20h,20h,20h,57h,45h,4ch,43h,4fh,4dh,45h,20h,54h,4fh,20h,20h,20h,20h,00h

table2: db 20h,57h,57h,57h,2Eh,4dh,43h,55h,39h,39h,2Eh,43h,4Fh,4Dh,20h,20h,20h,00h

end

所有人回答的都不对,其实是忘了将1602第5脚rw设置为0了,而郭天祥的板子是直接接地,所以不用设置,但是别的板子却不能照搬了。所以程序应改为

sbit lcdrw=P3^6;

void write_com(uchar com)

{

lcdrs=0;

lcdrw=0;//加这一条

P0=com;

delay(5);

lcden=1;

delay(5);

lcden=0;

}

void write_data(uchar date)

{

lcdrs=1;

lcdrw=0;//加这一条

P0=date;

delay(5);

lcden=1;

delay(5);

lcden=0;

}

以上就是关于单片机键盘及1602显示程序全部的内容,包括:单片机键盘及1602显示程序、字符型1602LCD自定义字符地址设置后,字符显示时,地址需要用c语言编程调用吗还是程序默认调、用于1602液晶屏的C语言程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存