我有 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语言程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)