单片机+1602+按键 c语言编程

单片机+1602+按键 c语言编程,第1张

最简单的是

把这8行内容放到一个二维数组里,unsigned char Word[8][];

定义个变量char DisWordLine = 0;

然后主程序循环显示DisPlay(Word, DisWordLine);//显示函数

扫描按键,按上移时DisWordLine++,按下移时DisWordLine--;

复杂点的可以参考“一个占用内存极少的菜单系统的实现”

#include<reg52h>

#define uint unsigned int

#define uchar unsigned char

sbit ACC_7=ACC^7; //位寻址寄存器定义

sbit rs=P3^5;

sbit en=P3^4;

sbit sclk=P2^0;

sbit io=P2^5;

sbit ce=P2^4;

sbit wd18b20=P2^7;

sbit beep=P1^7;

sbit led=P3^7;

sbit s1=P1^0;

sbit s2=P1^1;

sbit s3=P1^2;

sbit s4=P1^3;

sbit s5=P1^4;

char yue,ri,shi,fen,miao;

uchar s1num=0,a=0; //a是s1num所对应的结果

uchar b=0x80+0x40;

uchar code table1[5]={

0x56,0x34,0x12,0x22,0x02};

void delay(uint x)

{

uint i,j;

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

for(j=114;j>0;j--);

}

void write_com(uchar com) //1602写命令

{

rs=0;

en=0;

P0=com;

delay(5);

en=1;

delay(5);

en=0;

}

void write_data(uchar dat) //1602写数据

{

rs=1;

en=0;

P0=dat;

delay(5);

en=1;

delay(5);

en=0;

}

void w1302(uchar dz,uchar sj) //1302写,先地址,后数据

{

uchar i,j;

ce=0;

sclk=0;

ce=1;

for(i=8;i>0;i--)

{

sclk=0;

j=dz;

io=(bit)(j&0x01);

dz>>=1;

sclk=1;

}

for(i=8;i>0;i--)

{

sclk=0;

j=sj;

io=(bit)(j&0x01);

dz>>=1;

sclk=1;

}

ce=0;

}

uchar r1302(uchar dz) //读取数据函数

{

uchar i,j,sj1,sj2;

ce=0;

sclk=0;

ce=1;

for(i=8;i>0;i--)

{

sclk=0;

j=dz;

io=(bit)(j&0x01);

dz>>=1;

sclk=1;

}

for(i=8;i>0;i--)

{

ACC_7=io;

sclk=1;

ACC>>=1;

sclk=0;

}

ce=0;

sj1=ACC;

sj2=sj1/16;

sj1=sj1%16;

sj1=sj1+sj210;

return(sj1);

}

void init() //初始化函数

{

uchar a,b=0x80;

write_com(0x38);

write_com(0x0c);

write_com(0x06);

write_com(0x01); //1602初始化

write_com(0x80+0x40+2);

write_data('/');

write_com(0x80+0x40+5);

write_data('-');

write_com(0x80+0x40+8);

write_data(':');

write_com(0x80+0x40+11);

write_data(':');

w1302(0x8e,0x00); //1302初始化

for(a=0;a<5;a++)

{

w1302(b,table1[a]);

b+=2;

}

w1302(0x8e,0x80);

}

void shuax(uchar dz1602,uchar dz1302) //刷新时间函数

{

uchar sj,shi,ge;

sj=dz1302;

shi=sj/10;

ge=sj%10;

write_com(dz1602);

write_data(0x30+shi);

write_data(0x30+ge);

}

void keyscan()

{

if(s1==0)

{

delay(5);

if(s1==0)

{

s1num++;

while(!s1);

switch(s1num)

{

case 1:a=1;

write_com(0x80);

write_data('y');

break;

case 2:s1num=0;

a=0;

write_com(0x0c);

write_com(0x80);

write_data(' ');

w1302(0x8e,0x00);

w1302(0x80,miao);

w1302(0x82,fen);

w1302(0x84,shi);

w1302(0x86,ri);

w1302(0x88,yue);

w1302(0x8e,0x80);

break;

}

}

}

if(s1num!=0)

{

if(s2==0)

{

delay(5);

if(s2==0)

{

while(!s2);

b=b+3;

write_com(b);

write_com(0x0f);

}

}

if(s3==0)

{

delay(5);

if(s3==0)

{

while(!s3);

b=b-3;

write_com(b);

write_com(0x0f);

}

}

if(s4==0)

{

delay(5);

if(s4==0)

{

while(!s4);

switch(b)

{

case 0x80+0x40:yue++;

if(yue==13)

yue=1;

w1302(0x8e,0x00);

w1302(0x88,yue);

w1302(0x8e,0x80);

shuax(0x80+0x40,yue);

break;

case 0x80+0x40+3:ri++;

if(ri==32)

ri=1;

w1302(0x8e,0x00);

w1302(0x86,ri);

w1302(0x8e,0x80);

shuax(0x80+0x40+3,ri);

break;

case 0x80+0x40+6:shi++;

if(shi==24)

shi=0;

w1302(0x8e,0x00);

w1302(0x84,shi);

w1302(0x8e,0x80);

shuax(0x80+0x40+6,shi);

break;

case 0x80+0x40+9:fen++;

if(fen==60)

fen=0;

w1302(0x8e,0x00);

w1302(0x82,fen);

w1302(0x8e,0x80);

shuax(0x80+0x40+9,fen);

break;

case 0x80+0x40+12:miao++;

if(miao==60)

miao=0;

w1302(0x8e,0x00);

w1302(0x80,miao);

w1302(0x8e,0x80);

shuax(0x80+0x40+12,miao);

break;

}

}

}

if(s5==0)

{

delay(5);

if(s5==0)

{

while(!s5);

switch(b)

{

case 0x80+0x40:yue--;

if(yue==0)

yue=12;

shuax(0x80+0x40,yue);

break;

case 0x80+0x40+3:ri--;

if(ri==0)

ri=31;

shuax(0x80+0x40+3,ri);

break;

case 0x80+0x40+6:shi--;

if(shi==-1)

shi=23;

shuax(0x80+0x40+6,shi);

break;

case 0x80+0x40+9:fen--;

if(fen==-1)

fen=59;

shuax(0x80+0x40+9,fen);

break;

case 0x80+0x40+12:miao--;

if(miao==-1)

miao=59;

shuax(0x80+0x40+12,miao);

break;

}

}

}

}

}

void main()

{

init();

while(1)

{

yue=r1302(0x89);

ri=r1302(0x87);

shi=r1302(0x85);

fen=r1302(0x83);

miao=r1302(0x81);

keyscan();

shuax(0x80+0x40,yue);

shuax(0x80+0x40+3,ri);

shuax(0x80+0x40+6,shi);

shuax(0x80+0x40+9,fen);

shuax(0x80+0x40+12,miao);

}

}

1602液晶的程序我有,要做数字锁的话其实用到液晶也不多。

因为你显示密码是时候不应该都是现实吗?

你只需把键盘写入的数据存在一个数组中,然后跟密码数组对比就好了。

还有就是值得注意的是数据类型问题。

输入的键值看你处理的方式而定,密码存放的格式,还有输出显示的是ascll码。注意转换。

下面附带一段51的1602LCD的C程序,自己仔细琢磨。

#include<reg52h>

#define uchar unsigned char

#define uint unsigned int

uchar table[16]="abcdefghijklmnyz";

uchar table1[16]="0123456789abcdef";

sbit lcden=P2^0;

sbit lcdrs=P2^1;

sbit dula=P2^6;

sbit wela=P2^7;

uchar num;

void delay(uint z)

{

uint x,y;

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

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

}

void write_com(uchar com)

{ wela=0;

lcdrs=0;

P0=com;

delay(5);

lcden=1;

delay(5);

lcden=0;

}

void write_data(uchar date)

{ wela=0;

lcdrs=1;

P0=date;

delay(5);

lcden=1;

delay(5);

lcden=0;

}

void init()

{

lcden=0;

write_com(0x38);

write_com(0x0e);

write_com(0x06);

write_com(0x01);

write_com(0x80);

}

void main()

{

init();

for(num=0;num<16;num++)

{

write_data(table[num]);

delay(20);

}

write_com(1);

write_com(0x80+0x40);

for(num=0;num<16;num++)

{

write_data(table1[num]);

delay(20);

}

while(1);

}

会加的,减的也就不难了

设置计数器工作模式,然后反复读取计数器的值即可

TMOD=0X05;//定时器0为16位计数模式

TH0=0;

TL0=0;

TR0=1;//启动计数器

while(1)

{

delay_ms(10);//如果液晶显示,可加大延时时间,如果数码管显示,可不要此延时

//但数码管显示程序中间要有驻留延时

a=TH0256+TL0;//读取计数器的值

b=10000-a;//假设减1计数的初值为10000

if (key==0) display(1,0,a);//显示从第一行第一列起

else  display(1,0,b);//也可改成display(2,0,b)

}

液晶显示函数附件里有,可干脆将else去掉,第一行递增显示,第二行递减显示

//液晶显示温度

#include "AT89X52H"

#define Ddata P0

sbit RS=P3^5; //命令数据控制端

sbit RW=P3^6; //读写选择端

sbit LCDE=P3^7; //液晶使能端

sbit DQ=P1^0; //ds18b20与单片机连接口

#define uchar unsigned char

#define uint unsigned int

unsigned char hour=0,min=0,sec=0; //定义初值

unsigned int count=0;

unsigned char line1[16]={"

temp: "}; //16个字符

unsigned char line2[16]={" time: 00:00:00"}; //16个字符

unsigned char tab[]={'0','1','2','3','4','5','6','7','8','9'}; //数组

uchar

data disdata[5];

uint tvalue; //温度值

uchar tflag; //温度正负标志

void time();

/lcd1602程序/

void delay1ms(unsigned int ms)//延时1毫秒(不够精确的)

{

unsigned

int i,j;

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

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

}

void delay­5ms()//延时5毫秒(不够精确的)

{

unsigned

int i;

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

}

void delay50us()

{

register

int i;

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

}

void delay()

{unsigned char m,n;

for(m=255;m>0;m--)

for(n=255;n>0;n--);

}

void wr_com(unsigned char comm)

//写控制字符程序 E=1 RS=0

RW=0//

{

LCDE=0; //使能端

RS=0;

//RS寄存器选择输入端,当RS=0;当进行写模块 *** 作,指向指令寄存器。

RW=0;

//当RS=1,无论是读 *** 作还是写 *** 作,都是指向数据寄存器。

LCDE=1;

Ddata=comm;

RS=0;

RW=0;

LCDE=0;

}

void wr_data(unsigned char dat)//当前位置写字符子程序:E=1 RS=1 RW=0

{

LCDE=0;

RS=0;

//RS寄存器选择输入端,当RS=0;当进行写模块 *** 作,指向指令寄存器。

RW=0;

//当RS=1,无论是读 *** 作还是写 *** 作,都是指向数据寄存器。

RS=1;

RW=0;

LCDE=1;

Ddata=dat; //将dat赋给P0口

LCDE=0;

RS=0;

RW=0;

}

unsigned char busycheck()//忙状态检查//

{

unsigned char i;

LCDE=0;

RS=0;

RW=0;

RS=0;

RW=1;

LCDE=1;

i=Ddata;

LCDE=0;

return(i);

}

void init()//初始化程序,必须按照产品的资料介绍的过程进行//

{

wr_com(0x38); //显示模式设置必须三次,不用检测忙信号

delay5ms();

wr_com(0x38);

delay5ms();

wr_com(0x38);

delay5ms();

wr_com(0x01); ///清屏

delay5ms();

busycheck();

wr_com(0x08);

delay5ms();

busycheck();

delay5ms();

wr_com(0x06); ///光标移动设置,写一个字符后地址指针加1

delay5ms();

busycheck();

delay50us();

wr_com(0x38); ////显示模式设置

delay50us();

busycheck();

delay50us();

wr_com(0x0c); /////显示开,不显示光标

delay50us();

busycheck();

delay50us();

wr_com(0x40); //set cgram address

delay50us();

delay50us(); //这些延时可用可不用//

}

void display()

{ unsigned char i;

wr_com(0x80); //set ram address

delay50us();

busycheck();

delay50us();

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

{wr_data(line1[i]); //display(6个字符)

delay50us();

busycheck();}

busycheck();

delay50us();

wr_com(0xc0); // 0xc0=0x80+0x40

delay50us();

busycheck();

delay50us();

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

{

wr_data(line2[i]); //display

delay50us();

busycheck();

}

}

/温度传感器ds1820程序/

void delay_18B20(unsigned int i)//延时1微秒

{

while(i--);

}

void ds1820rst()/ds1820复位/

{ unsigned char x=0;

DQ = 1; //DQ复位

delay_18B20(4); //延时

DQ = 0; //DQ拉低

delay_18B20(100); //精确延时大于480us

DQ = 1; //拉高

delay_18B20(40);

}

uchar ds1820rd()/读数据/

{ unsigned char i=0;

unsigned char dat = 0;

for (i=8;i>0;i--) //读一个字节的数据函数

{ DQ = 0; //给脉冲信号

dat>>=1;

DQ = 1; //给脉冲信号

if(DQ)

dat|=0x80; //等价于 dat =

dat | 0x80,dat和0x80做“或”的运算, 结果是最高位置1,其它位保持不变。

delay_18B20(10);

}

return(dat);

}

void ds1820wr(uchar wdata)/写数据/

{unsigned char i=0;

for (i=8; i>0; i--)

{ DQ = 0;

DQ = wdata&0x01;

delay_18B20(10);

DQ = 1;

wdata>>=1;

//右移一位

}

}read_temp()/读取温度值并转换/

{uchar a,b;

ds1820rst(); //ds1802/初始化程序

ds1820wr(0xcc);//跳过读序列号/

ds1820wr(0x44);//启动温度转换/

ds1820rst();

ds1820wr(0xcc);//跳过读序列号/

ds1820wr(0xbe);//读取温度/

a=ds1820rd(); //读低八位

b=ds1820rd(); //读高八位

tvalue=b;

tvalue<<=8;

tvalue=tvalue|a;

if(tvalue<0x0fff)

tflag=0;

else //“&” 是逻辑与“|” 是逻辑或if(dat & 0x01):不管dat是什么数和0x01(00000001)做了“与”的运算后,最低位保持不变,其它位均为0如果dat的最低位为1,则表达式为真,就会执行if语句中的内容。如果dat最低位为0,则表达式为假,不执行if语句,执行if语句后的下一条语句。dat |= 0x80:等价于 dat = dat | 0x80,dat和0x80做“或”的运算,意思是最高位置1,其它位保持不变。

具体的可以去参考一下C语言的相关语法。

{tvalue=~tvalue+1;

tflag=1;

}

tvalue=tvalue(0625);//温度值扩大10倍,精确到1位小数

return(tvalue);

}

//

void ds1820disp()//温度值显示

{ uchar flagdat;

disdata[0]=tvalue/1000+0x30;//百位数

disdata[1]=tvalue%1000/100+0x30;//十位数

disdata[2]=tvalue%100/10+0x30;//个位数

disdata[3]=tvalue%10+0x30;//小数位

if(tflag==0)

flagdat=0x20;//正温度不显示符号

else

flagdat=0x2d;//负温度显示负号:-

if(disdata[0]==0x30)

{disdata[0]=0x20;//如果百位为0,不显示

if(disdata[1]==0x30)

{disdata[1]=0x20;//如果百位为0,十位为0也不显示

}

}

wr_com(0x88);

wr_data(flagdat);//显示符号位

wr_com(0x89);

wr_data(disdata[0]);//显示百位

wr_com(0x8a);

wr_data(disdata[1]);//显示十位

wr_com(0x8b);

wr_data(disdata[2]);//显示个位

wr_com(0x8c);

wr_data(0x2e);//显示小数点

wr_com(0x8d);

wr_data(disdata[3]);//显示小数位

}

void main()

{

TMOD=0X01;

EA=1;

ET0=1;

TR0=1;

TH0=(65536-4995)/256;

TL0=(65536-4995)%256;

init();

while(1)

{

read_temp();//读取温度

ds1820disp();//显示

time(); //时间程序

display();//时间显示程序

}

}

void t0(void)interrupt 1 using 0

{

TH0=(65536-4995)/256;

TL0=(65536-4995)%256;

count++;

if(count==200){count=0;sec++;}

if(sec==60){sec=0;min++;}

if(min==60){min=0;hour++;}

if(hour==24){hour=0;}

}

void time()

{

line2[15]=tab[sec%10];line2[14]=tab[sec/10];

line2[12]=tab[min%10];line2[11]=tab[min/10];

line2[9]=tab[hour%10];line2[8]=tab[hour/10];

if(!P1_2){delay();if(!P1_2){delay();sec++;if(sec==60){sec=0;}}}

if(!P1_1){delay();if(!P1_1){delay();min++;if(min==60){min=0;}}}

if(!P1_0){delay();if(!P1_0){delay();hour++;if(hour==24){hour=0;}}}

}

给你参考一下,这样才能提高哦

以上就是关于单片机+1602+按键 c语言编程全部的内容,包括:单片机+1602+按键 c语言编程、求一份用1602,AT89C52,DS1302做的时钟的C语言代码,或者求哪位大侠帮我看看这个程序有什么问题吧。。。、1602液晶显示屏显示程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址: https://outofmemory.cn/zz/10169003.html

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

发表评论

登录后才能评论

评论列表(0条)

保存