基于51单片机流水灯仿真与程序设计
基于51单片机流水灯设计
摘要 本次程序设计和仿真是基于Proteus和keil的环境对STC89C51进行流水灯设计,根据左移方式实现基本的流水灯,根据外部中断的方式实现不同类型的流水灯操作。
关键字Proteus、keil、流水灯、外部中断
一、工程介绍
1.1、实现要求
二、仿真电路设计 2.1、环境介绍
- 利用单片机一个端口接8个LED发光二极管,另一个端口接两个开关。设计硬件电路图,并编写程序,实现从上到下轮流点亮8个发光二极管(流水灯,即每次只点亮一个灯)。
- 扩展任务一:
设计一个开关 K 1 K_1 K1?,按下时,先奇数再偶数亮,不断循环。- 扩展任务二:
在完成基础任务的基础上,设计开关 K 2 K_2 K2?,按下时,分别从两边向中间流动三次,再从中间向两边流动三次。
2.2、电路设计
- 仿真设计使用Proteus 8.0; Proteus安装参考链接
2.2.1、最小系统的实现 第一步:在Proteus中的[P]中选择所需要的零件有电阻RES、电容CAP、电解电容CAP-ELEC、复位开关BUTTON、晶振CRYSTAL、排阻RESPACK-8、LED灯LED-YELLOW、最后是单片机AT89C5C。
第二步:设计晶振电路、复位电路,如图所示:
文章图片
注意事项:复位系统中R9不能设置太大,否则导致复位系统不能正常工作,这里选择 R 9 = 1 K R9=1K R9=1K
2.2.2、实现任务中三个要求 第一步:将P0端口全部上拉
- EA:内外部存储器选择
- ALE:地址所存允许信号输出引脚
- PSEN:外部程序存储器选通信号输出引脚
P0口作为总线扩展用时,不用加上拉电阻;作为I/O口使用时,需要加10K-4.7K上拉电阻,上电复位后是开漏输出。
第二步:接上八个LED,且限流电阻为1K
LED驱动电流大概再0~20MA,随便在看一个LED的datassheet如下:
文章图片
可以知道LED驱动电流的极限值为20MA和25MA,具体的LAD驱动电流要根据datasheet设计,仿真中驱动电流为: I = 5 V ? 0.7 V 1 K = 4.3 M A I=\frac{5V-0.7V}{1K}=4.3MA I=1K5V?0.7V?=4.3MA
第三步:设计两个外部中断的开关
在STC89C52的数据手册中,可以知道外部中断分别P32、P33分别对应外部中断0和外部中断1。而且P3的复位值为1111 1111B,也就是上电P32、P33口都是高电平,如果用外部中断触发的话,可以设计低电平触发,也就是按钮直接接地即可。
文章图片
第四步:总体电路设计如下
文章图片
三、程序设计 3.1、环境介绍
3.2、实现流水灯操作
- 程序设计采用Keil 5.22;MDK5安装以及C51支持包
可以通过自带的函数**_ crol _**:循环左移函数实现
假设Var = 0xFE 即二进制(1111 1110B)程序如下:
_ crol _(Var,1)= 0xFD (1111 1101B)
#include
#include"intrins.h"
unsigned char status = 0xFe;
//初始化P0为1111 1110 P00处的LED
unsigned int time = 0xFFFF;
//LED点亮时间
void main(void){
while(1){
time = 0xFFFF;
P0 = status;
status = _crol_(status,1);
while(time--);
}
}
效果如下:
文章图片
3.3、通过中断实现扩展操作
按键用到了51单片机的两个外部中断,使用低电平的方式触发中断,具体配置可以根据数据手册来操作,如下:
文章图片
可以知道这两个外部中断位于寄存器TCON中,标志位分别为IE.0和IE.1,触发方式分别为IT0和IT1
中断查询表可以知道外部中断0对应0,外部中断1对应2
文章图片
程序如下:
#include
#include"intrins.h"
unsigned char Function = 0x00;
//对应相应功能
/******************************************************************************
* @briefEX0_ISR:外部中断一,实现扩展任务1
******************************************************************************/
void EX0_ISR(void) interrupt 0
{
Function = 0x01;
//对应扩展任务1
P0 = 0xFF;
//LED全部复位
}
/******************************************************************************
* @briefEX0_ISR:外部中断二,实现扩展任务2
******************************************************************************/
void EX1_ISR(void) interrupt 2
{
Function = 0x02;
//对应扩展任务1
P0 = 0xFF;
//LED全部复位
}
/******************************************************************************
* @briefLedMove:实现扩展任务2
******************************************************************************/
void LedMove(void)
{
unsigned char count = 0x03;
while(count--)
{
time = 0xFFFF;
P0 = 0x7E;
while(time--);
P0 = 0xFF;
time = 0xFFFF;
P0 = 0xBD;
while(time--);
P0 = 0xFF;
time = 0xFFFF;
P0 = 0xDB;
while(time--);
P0 = 0xFF;
time = 0xFFFF;
P0 = 0xE7;
while(time--);
P0 = 0xFF;
}
count = 0x03;
while(count--)
{
time = 0xFFFF;
P0 = 0xE7;
while(time--);
P0 = 0xFF;
time = 0xFFFF;
P0 = 0xDB;
while(time--);
P0 = 0xFF;
time = 0xFFFF;
P0 = 0xBD;
while(time--);
P0 = 0xFF;
time = 0xFFFF;
P0 = 0x7E;
while(time--);
P0 = 0xFF;
}
}
void main(void)
{
IT0 = 1;
//外部中断0低电平触发
EX0 = 1;
//使能中断
IT1 = 1;
//外部中断1低电平触发
EX1 = 1;
//使能中断
EA = 1;
//打开总中断
while(1)
{
switch(Function)
{
case 0x01:
time = 0xFFFF;
P0 = 0xAA;
while(time--);
time = 0xFFFF;
P0 = 0x55;
while(time--);
break;
case 0x02:
LedMove();
break;
}
}
}
效果如下:
【基于51单片机流水灯仿真与程序设计】
文章图片
四、结果分析与改进
- 按键程序中并没有加消抖方式,硬件结构也没加消抖方式,这样实际中是要采取一种软件或者硬件消抖方式
- 用proteus绘画51单片机最小系统
- crol循环左移函数
推荐阅读
- 基于微信小程序带后端ssm接口小区物业管理平台设计
- live|live to inspire 一个普通上班族的流水账0723
- 基于|基于 antd 风格的 element-table + pagination 的二次封装
- 基于爱,才会有“愿望”当“要求”。2017.8.12
- (小说)月流水几亿的火爆游戏养成记
- javaweb|基于Servlet+jsp+mysql开发javaWeb学生成绩管理系统
- JavaScript|vue 基于axios封装request接口请求——request.js文件
- 韵达基于云原生的业务中台建设 | 实战派
- EasyOA|EasyOA 基于SSM的实现 未完成总结与自我批判
- 记录元宵节一天的流水账