#include "reg52.h"
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
sbit LSA = P2^2;
sbit LSB = P2^3;
sbit LSC = P2^4;
sbit beef = P1^5;
u8 initial_value, reversal_value, P1_value; //矩阵按键赋位
u8 wei[8]={10,10,10,10,10,10,10,10}; //数码管状态位 10-不显示
u8 a,i,floor=1;keyflag=0,state=1,extre=6,voted=1; //a赋给wei voted为候选位
u8 smgduan[11]={0x3f,0x06,0x5b,0x4f, //0 1 2 3
0x66,0x6d,0x7d,0x07, //4 5 6 7
0x7f,0x6f,0x00};
/*******************************************************************************
* 函 数 名 : delay_ms
* 函数功能 : 延时1ms
* 输 入 : i
* 输 出 : 无
*******************************************************************************/
void delay_ms(u16 i)
{
u8 j;
while(i--)
{
for(j = 0;j < 125;j++);
}
}
/*******************************************************************************
* 函 数 名 : delay_us
* 函数功能 : 延时10us
* 输 入 : i
* 输 出 : 无
*******************************************************************************/
void delay_us(u16 i)
{
while(i--);
}
/*******************************************************************************
* 函 数 名 : weixuan
* 函数功能 : 数码管位选
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void weixuan()
{
LSA=1;LSB=1;LSC=1;P0=smgduan[wei[7]];delay_ms(1); P0 = 0X00;delay_us(10);
LSA=0;LSB=1;LSC=1;P0=smgduan[wei[6]];delay_ms(1); P0 = 0X00;delay_us(10);
LSA=1;LSB=0;LSC=1;P0=smgduan[wei[5]];delay_ms(1); P0 = 0X00;delay_us(10);
LSA=0;LSB=0;LSC=1;P0=smgduan[wei[4]];delay_ms(1); P0 = 0X00;delay_us(10);
LSA=1;LSB=1;LSC=0;P0=smgduan[wei[3]];delay_ms(1); P0 = 0X00;delay_us(10);
LSA=0;LSB=1;LSC=0;P0=smgduan[wei[2]];delay_ms(1); P0 = 0X00;delay_us(10);
LSA=1;LSB=0;LSC=0;P0=smgduan[wei[1]];delay_ms(1); P0 = 0X00;delay_us(10);
LSA=0;LSB=0;LSC=0;P0=smgduan[wei[0]];delay_ms(1); P0 = 0X00;delay_us(10);
}
/*******************************************************************************
* 函 数 名 : KeyDown
* 函数功能 : 检测有按键按下并读取键值
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void KeyDown(void)
{
P1=0x0f;
if(P1!=0x0f)//读取按键是否按下
{
delay_ms(10);//延时10ms进行消抖
if(P1!=0x0f)//再次检测键盘是否按下
{
initial_value = P1;
P1 = 0xf0;
reversal_value = P1;
P1_value = initial_value | reversal_value;
}
switch(P1_value)
{
case(0X77): a=1;keyflag=1;break;
case(0X7b): a=2;keyflag=1;break;
case(0X7d): a=3;keyflag=1;break;
case(0X7e): a=4;keyflag=1;break;
case(0Xb7): a=5;keyflag=1;break;
case(0Xbb): a=6;keyflag=1;break;
case(0Xbd): a=8;break;
case(0Xbe): a=8;break;
case(0Xd7): a=8;break;
case(0Xdb): a=8;break;
case(0Xdd): a=8;break;
case(0Xde): a=8;break;
case(0Xe7): a=8;break;
case(0Xeb): a=8;break;
case(0Xed): a=8;break;
case(0Xee): a=8;break;
default:break;
}
}
P1 = 0x0f;
while(P1!=0x0f); //检测按键松手检测
}
/*******************************************************************************
* 函 数 名 : Time0_Init
* 函数功能 : 定时器0初始化
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Time0_Init()
{
TMOD |= 0x01; // 使用工作方式 1
TH0 = (65536 - 10000) / 256; // 装载定时器定时周期
TL0 = (65536 - 10000) % 256;
/*
TH0 = 0xFC;
TLO = 0x18;
*/
ET0 = 1;// 打开Timer0的中断允许
EA = 1; // 打开总中断
TR0 = 0; // 启动定时器
}
/*******************************************************************************
* 函 数 名 : Time1_Init
* 函数功能 : 定时器1初始化
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Time1_Init()
{
TMOD |= 0x10; // 使用工作方式 1
TH1 = (65536 - 10000) / 256; // 装载定时器定时周期
TL1 = (65536 - 10000) % 256;
ET1 = 1;// 打开Timer0的中断允许
EA = 1; // 打开总中断
TR1 = 0; // 启动定时器功能
}
/*******************************************************************************
* 函 数 名 : Time_0() interrupt 1
* 函数功能 : 定时器0的中断函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Time_0() interrupt 1 //上升定时
{
static int j=0;
j++;
TH0 = (65536 - 10000) / 256; //给定时器重新赋值10ms
TL0 = (65536 - 10000) % 256;
if(floor!=voted) //没到候选层
{
wei[6]=1; //上升
if(j==100)
{
j=0;
wei[floor-1]=10;
floor++;
}
}
if(floor==voted) //到达候选层
{
wei[6]=0; //下降
wei[floor-1]=10; //到达的层清屏
if(floor==extre)
{
TR0 = 0;
state=0;
voted=floor;
}
if(j==300)
{
j=0;
while(1)
{
if(wei[voted]==10) //寻找下一个等候区
{
voted++;
}
else
{
voted++;
break;
}
}
if(floor!=extre)
{
floor++;
}
}
}
wei[7]=floor; //显示楼层
/*定时器定时完1ms后,THO,TL0将会自动清0,这是需要重新赋值,然后开始计数*/
}
/*******************************************************************************
* 函 数 名 : Time_1() interrupt 3
* 函数功能 : 定时器0的中断函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Time_1() interrupt 3 //下降定时
{
static int j=0;
j++;
TH1 = (65536 - 10000) / 256; //给定时器重新赋值10ms
TL1 = (65536 - 10000) % 256;
/*定时器定时完10ms后,TH1,TL1将会自动清0,这是需要重新赋值,然后开始计数*/
if(floor!=voted)
{
wei[6]=7;
if(j==100)
{
j=0;
wei[floor-1]=10;
floor--;
}
}
if(floor==voted)
{
wei[6]=0;
wei[floor-1]=10;
if(floor==extre)
{
TR1 = 0;
state=0;
voted=floor;
}
if(j==300)
{
j=0;
while(1)
{
if(wei[voted-2]==10)
{
voted--;
}
else
{
voted--;
break;
}
}
if(floor!=extre)
{
floor--;
}
}
}
wei[7]=floor;
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
wei[0]=1; //初始化楼层
Time0_Init();
Time1_Init();
while(1)
{
weixuan();
KeyDown();
if(state==0) //停止状态
{
wei[6]=0;
if(extre<a) //a为被选的楼层
{
state=1;
}
if(extre>a)
{
state=7;
}
if(extre==a)
{
state=0;
}
}
if(keyflag==1) //有楼层被选
{
keyflag=0; //清除标志位
if(wei[a-1]!=a) //取消选择
{
wei[a-1]=a;
}
else
{
wei[a-1]=10;
}
}
if(state==1) //上升状态
{
extre=6;
for(i=5;i>0;i--) //寻找最高楼层
{
if(wei[i]==10&&floor<extre)
{
extre--;
}
if(wei[i]!=10)
{
break;
}
}
if(voted<extre)
{
TR0 = 1;
}
}
if(state==7) //下降状态
{
extre=1;
for(i=0;i<5;i++) //输入一位,数字向左移动一位
{
if(wei[i]==10&&floor>extre)
{
extre++;
}
if(wei[i]!=10)
{
break;
}
}
if(voted>extre)
{
TR1 = 1;
}
}
51单片机(STC89C52) 模拟电梯控制 代码
需积分: 0 85 浏览量
更新于2023-10-16
3
收藏 35KB ZIP 举报
1.电梯
用矩阵键盘和数码管,完全模仿电梯,初始状态为1楼,电梯上的时候必须上到选定的最高楼层才能开始下,电梯下的时候必须下到选定的最低楼层才能开始上,所按的楼层要求停3秒,经过没按的楼层时显示1秒,八个数码管,前六个代表1-6楼,按中的楼层要显示,到达按中的楼层后,该楼层不显示,没选中的楼层不显示,最右边的数码管显示目前所在的楼层
电梯拓展:
1.选定的楼层再按一次取消
2.倒数第二个数码管可以显示现在的状态,上升(1)下降(7)还是停止(0)
3.电梯在运行的过程中可以再次选择要停止的楼层(上升状态是选择更高的楼层,下降是选择低的楼层)
机电侠克
- 粉丝: 67
- 资源: 12
最新资源
- 小伊工具箱小程序源码/趣味工具微信小程序源码
- 网络安全领域中关于防范钓鱼邮件导致的病毒入侵与应对措施探讨
- Build a Large Language Model - 2025
- 郑州升达大学2024-2025第一学期计算机视觉课程期末试卷,
- ztsc_109339.apk
- boost电路电压闭环仿真 有pi控制和零极点补偿器两种 仿真误差0.00705,仿真波形如图二所示 所搭建的模型输入电压5V,输出电压24伏
- COMSOL模拟动水条件联系裂隙注浆扩散,考虑粘度时变
- 学生信息管理系统,该程序用于管理学生的基本信息,包括姓名、年龄、性别和成绩 用户可以添加、删除、修改和查询学生信息
- XC7V2000T+TMS320C6678设计文件,包含原理图,PCB等文件,已验证,可直接生产
- 简易图书管理系统,该程序用于管理图书的基本信息,包括书名、作者、出版年份和库存数量 用户可以添加、删除、修改和查询图书信息
- 简易日程提醒系统, 该程序用于管理用户的日程提醒,包括事件名称、日期、时间和描述 用户可以添加、删除、修改和查询日程提醒
- 无线充电仿真 simulink 磁耦合谐振 无线电能传输 MCR WPT lcc ss llc拓扑补偿 基于matlab 一共四套模型: 1.llc谐振器实现12 24V恒压输出 带调频闭环控制 附
- 直流无刷电机,直径38mm,径向长23.8mm,转速25000rpm,功率200W,可用于磨头加工
- 47191 Python语言程序设计(第2版)(含视频教学)-课后习题答案.zip
- 信息系统管理师试题分享
- FreeRTOS学习之系统移植