
刚敲完,测试过,没有任何问题,放心使用
#include <reg51h>
#include <intrinsh>
#define uchar unsigned char
#define uint unsigned int
sbit K1=P2^4;
sbit K2=P2^3;
sbit K3=P2^2;
sbit K4=P2^1;
sbit K5=P2^0;
sbit BE=P2^7;
uchar code NUM[]=
{0x00,0x3e,0x41,0x41,0x41,0x3e,0x00,0x00,
0x00,0x00,0x00,0x21,0x7f,0x01,0x00,0x00,
0x00,0x27,0x45,0x45,0x45,0x39,0x00,0x00,
0x00,0x22,0x49,0x49,0x49,0x26,0x00,0x00,
0x00,0x0c,0x14,0x24,0x7f,0x04,0x00,0x00,
0x00,0x72,0x51,0x51,0x51,0x4e,0x00,0x00,
0x00,0x36,0x49,0x49,0x49,0x36,0x00,0x00,
0x00,0x32,0x49,0x49,0x49,0x3e,0x00,0x00};
uint r;
char offset=0;
uchar Current_Level=1,Dest_Level=1,x=0,t=0;
void delay(uint x)
{
uchar i;
while(x--)
for(i=0;i<120;i++);
}
void main()
{
P3=0x80;
Current_Level=1;
Dest_Level=1;
TMOD=0x01;
TH0=-4000/256;
TL0=-4000%256;
TR0=1;
IE=0x82;
while(1);
}
void LED_Screen_Display() interrupt 1
{
uchar i;
if(P1!=0xff&&Current_Level==Dest_Level)
{
if(P1==0xfe) {Dest_Level=5;K5=0;}
if(P1==0xfd) {Dest_Level=4;K4=0;}
if(P1==0xfb) {Dest_Level=3;K3=0;}
if(P1==0xf7) {Dest_Level=2;K2=0;}
if(P1==0xef) {Dest_Level=1;K1=0;}
}
TH0=-4000/256;
TL0=-4000%256;
P3=_crol_(P3,1);
i=Current_Level8+r+offset;
P0=~NUM[i];
if(Current_Level<Dest_Level)
{
if(++r==8)
{
r=0;
if(++x==4)
{
x=0;
if(++offset==8)
{
offset=0;
Current_Level++;
}
}
}
}
else
if(Current_Level>Dest_Level)
{
if(++r==8)
{
r=0;
if(++x==4)
{
x=0;
if(--offset==-8)
{
offset=0;
Current_Level--;
}
}
}
}
else
{
if(++r==8) {r=0;}
}
}
按照你题目,用了2个2位显示,实际有4位合一起的。
k3:切换计数模式/预置模式。
计数模式:LED显示计时数字,从0开始计时,直到预置最大值。
预置模式:LED显示当前预置最大值,按k1,k2可对预置值+- *** 作,长按k1,k2大约2秒,会进入自动加减预置值。直到再次点击k1,k2,k3任意一键停止自动。
k4:在计数模式下使用,每按下一次显示的数字加一(会在正常计时同时额外+1)。
当计数达到预置最大值,会停止计数,LEN闪烁(实际就是交替显示间隔边长),蜂鸣器响。
按键时长、LED动态显示间隔、闪烁间隔、计数速度,均可直接修改常量,需要自己改,我备注写的很详细。
电路基本按照你上图,略有修改。
#include <reg52h>
#define uint unsigned int
#define uchar unsigned char
#define duan P0
#define on 0
#define off 1
#define SSSPEED 35 //LED交替闪烁间隔时间
#define JSPEED 5000//计数模式,速度默认数值(5000200us=1S) 值越小计数越快
#define PREESTIME 500//按钮长按时间判定,预设500(大约2秒),需要自改,值越大,长按时间越长
sbit fm=P3^3;
sbit wei1=P3^4;
sbit wei2=P3^5;
sbit wei3=P3^6;
sbit wei4=P3^7;
sbit k1=P1^4;
sbit k2=P1^5;
sbit k3=P1^6;
sbit k4=P1^7;
uint jsSpd=JSPEED;//计时速度,默认1s一次(5000200us)
uint ssSpd=SSSPEED;//LED交替闪烁速度
//共阳极
int delay(uint xms);
void init();
void jspause();//计数器开启/停止
void setnumYS();//设置预设数值
void numJsChange();//计数模式数字改变
void showLED();
int pressWait(uint btn);
uint g=0;
uint s=0;
uint b=0;
uint q=0;
uint count=0;
uint ispause=1;
uint numYS=0;//预设数值
uint numJS=0;//实际计时的数字
uint isMaxJs=0;//标识:计时达最大。 达最大1,否0
uint isk3press=0;//标识:k3按钮是否被点击。 点击1,否0
uint ispress1=0;//标识:k1被长按
uint ispress2=0;//标识:k2被长按
uint isbtn4=0;//标识:k4被按下
uint btnName=0;//按钮长按计时
void main()
{
init();
while(1)
{
if(ispause==1 && ispress1==1 && numYS<9999) //预置模式下,k1已长按,自动增
{
numYS++;
setnumYS();
}
if(ispause==1 && ispress2==1 && numYS>0) //预置模式下,k2已长按,自动减
{
numYS--;
setnumYS();
}
if(isMaxJs==0 && numJS>=numYS && ispause==0) //计时模式下达最大值
{
fm=on;
ssSpd=1000;//增加LED交替间隔,实现数字闪烁
isMaxJs=1;
EA=0;
setnumYS();
numJS=0;
}
if(k1==0 ||k2==0|| k3==0) //k1\k2\k3任意一个按钮被按下,停止预置数自动增长
{
ispress1=0;
ispress2=0;
}
if(k1==0 && ispause==1)//预置模式下+
{
delay(10);
if(k1==0)
{
btnName=1;
if(pressWait(btnName))//判断连按
{
while(k1==0);
ispress1=1;
}
else if(numYS<9999)
{
numYS++;
setnumYS();
}
}
}
if(k2==0 && ispause==1)//预置模式下-
{
delay(10);
if(k2==0)
{
btnName=2;
if(pressWait(btnName))//判断连按
{
while(k2==0);
ispress2=1;
}
else if(numYS>0)
{
numYS--;
setnumYS();
}
}
}
if(k3==0)
{
delay(10);
if(k3==0)
{
while(k3==0);
fm=off;
jspause();
}
}
if(k4==0 && ispause==0)//计数模式下按下k4,k4的防抖写在中断中
{
delay(10);
if(k4==0)
{
while(k4==0);
isbtn4=1;
}
}
showLED();
}
}
void showLED()
{
uchar nums[10]={0xc0,0xf9,0xa4,0xB0,0x99,0x92,0x82,0xf8,0x80,0x98};
if(g>=0)
{
duan=nums[g];
wei4=on;
delay(ssSpd);
wei4=off;
}
if(s>0 || (s==0 && b>0))
{
duan=nums[s];
wei3=on;
delay(ssSpd);
wei3=off;
}
if(b>0 || (b==0 && q>0))
{
duan=nums[b];
wei2=on;
delay(ssSpd);
wei2=off;
}
if(q>0)
{
duan=nums[q];
wei1=on;
delay(ssSpd);
wei1=off;
}
}
void setnumYS()//设置预设数值
{
q=numYS/1000;
b=(numYS%1000)/100;
s=(numYS%100)/10;
g=numYS%10;
}
void jspause()
{
if(ispause==0 || isMaxJs==1)//关闭计时模式 / 启动预置模式
{
EA=0;
isMaxJs=0;
ispause=1;
ssSpd=SSSPEED;
ispress1=0;
ispress2=0;
setnumYS();
}
else if(ispause==1) //启动计时模式 / 关闭预置模式
{
ispause=0;
q=b=s=g=0;
numJS=0;
ssSpd=SSSPEED;
EA=1;
}
}
void init()
{
TMOD=0x02; //T0 工作模式2 自动装填8位 200us
TH0=0x38;
TL0=0x38;
EA=0;
ET0=1;
TR0=1;
wei1=off;
wei2=off;
wei3=off;
wei4=off;
}
void numJsChange()//计数模式数字改变
{
if(g==9)
{
g=0;
if(s==9)
{
s=0;
if(b==9)
{
b=0;
if(q==9)
{
q=0;
}
else
q++;
}
else
b++;
}
else
s++;
}
else
g++;
}
void ct() interrupt 1 //一次中断200us
{
if(count<jsSpd)
count++;
else
{
count=0;
numJsChange();
numJS++;
}
if(isbtn4==1)
{
isbtn4=0;
numJsChange();
numJS++;
}
}
int pressWait(uint btn)
{
uint i,j;
for(i=PREESTIME;i>0;i--)
for(j=110;j>0;j--)
{
if((k1==1 && btn==1)||(k2==1 && btn==2))
return 0;
}
return 1;
}
int delay(uint xms)
{
uint i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--)
{
if(k1==0 || k2==0 ||k3==0)
return 1;
}
return 0;
}
51单片机4×4矩阵键盘仿真哪里找
44 矩阵键盘布局如下,检测按键,然后通过 LCD1602 显示出来
第一行:The key value is
第二行:每按一次键,键值依次显示出来,整行显示完后,清屏,键值
从左开始显示
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
0png
单片机源程序如下:
/
LCD1602液晶显示实验
实现现象:下载程序后插上LCD1602液晶在开发板上,即可显示
注意事项:如果不想让点阵模块显示,可以将74HC595模块上的JP595短接片拔掉。
/
#include "reg52h" //此文件中定义了单片机的一些特殊功能寄存器
#include "lcdh"
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
#define LCD1602_DATAPINS P0
#define GPIO_KEY P1
u8 KeyValue,k=0,n=0,miss=1;
u8 Disp[]="The key value is";
u8 cmy[17]={'1','2','3','/','4','5','6','%','7','8','9','@','','0','#','='};
u8 dp[17]={' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
/
函 数 名 : main
函数功能 : 主函数
输 入 : 无
输 出 : 无
/
void KeyDown(void)
{
char a=0;
GPIO_KEY=0x0f;
if(GPIO_KEY!=0x0f)//读取按键是否按下
{
Lcd1602_Delay1ms(10);//延时10ms进行消抖
if(GPIO_KEY!=0x0f)//再次检测键盘是否按下
{ n=1;
//测试列
GPIO_KEY=0X0F;
switch(GPIO_KEY)
{
case(0X07): KeyValue=0;break;
case(0X0b): KeyValue=1;break;
case(0X0d): KeyValue=2;break;
case(0X0e): KeyValue=3;break;
}
//测试行
GPIO_KEY=0XF0;
switch(GPIO_KEY)
{
case(0X70): KeyValue=KeyValue;break;
case(0Xb0): KeyValue=KeyValue+4;break;
case(0Xd0): KeyValue=KeyValue+8;break;
case(0Xe0): KeyValue=KeyValue+12;break;
}
while((a<50)&&(GPIO_KEY!=0xf0)) //检测按键松手检测
{
Lcd1602_Delay1ms(1);
a++;
}
}
}
}
void main(void)
{
u8 i,m;
LcdInit();
for(i=0;i<16;i++)
{
LcdWriteData(Disp[i]);
}
while(miss)
{
LcdWriteCom(0x80+0x40);
KeyDown();
if(n==1)
{dp[k]=cmy[KeyValue];
n=0;
k++;
}
for(m=0;m<16;m++)
{LcdWriteData(dp[m]);}
if(k==16)
{ for(m=0;m<16;m++)
{dp[m]=' ';}
Lcd1602_Delay1ms(1000);
LcdWriteCom(0x01);
Lcd1602_Delay1ms(1000);
k=0;
for(i=0;i<16;i++)
{
LcdWriteData(Disp[i]);
}
}
}
}
以上就是关于求一个c语言程序,用单片机,8*8点阵屏,和按键做一个电梯仿真系统……要求;按第一个键点阵屏显示1全部的内容,包括:求一个c语言程序,用单片机,8*8点阵屏,和按键做一个电梯仿真系统……要求;按第一个键点阵屏显示1、proteus仿真电路图,51单片机按键计数、51单片机4×4矩阵键盘仿真哪里找等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)