欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

51单片机Proteus仿真+Keil工程-实验1-LED

程序员文章站 2022-03-11 20:44:59
通过控制8个流水灯,完成从左到右的循环控制;从两边到中间的反复循环控制;流水灯的间隔控制。一共三个小任务。流水灯控制,我编写了三种控制方法,分别是数组传值、调用函数和使用移位运算符。...

实验1-单片机流水灯控制实验

  之前做的一次实验,51单片机控制Led灯,如有问题欢迎指正。

实验目标:

  通过控制8个流水灯,完成从左到右的循环控制;从两边到中间的反复循环控制;流水灯的间隔控制。一共三个小任务。

Proteus原理图

51单片机Proteus仿真+Keil工程-实验1-LED

选择元器件:

DEVICES 说明
AT89C51 MCU
BUTTON 按键
CAP 普通电容
CAP-ELEC 电解电容
CRYSTAL 晶振
LED-BLUE 蓝色LED灯
RES 电阻
RESPACK-8 排阻

  51单片机的P0口做IO口使用时是漏极开路输出,其引脚一般需要在片外接一定阻值的上拉电阻,此时端口不存在高阻抗的悬浮状态,因此它是一个准双向口。同时,P0口每一位的驱动能力是P1~P3口的两倍,每位可以驱动8个LSTTL(Low-power Schottky TTL,即低功耗肖特基TTL)输入,89C51等单片机任何一个端口想要获得较大的驱动能力,必须采用低电平输出。上图的LED灯就是采用低电平驱动(图片上的“红色LED”应该是“蓝色LED”)。

  时钟晶体振荡频率为fosc=12MHZf_{osc}=12MHZ
  时钟周期相当于Tosc=1fosc83.33nsT_{osc}=\frac{1}{f_{osc}} \approx 83.33ns
  复位电路的话通过给89C51等单片机的复位引脚RST加上大于2个机器周期的高电平(即24个时钟振荡周期)就可以使单片机复位。

KEIL工程:

主函数:

#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define LedPort P0
#define TIME 500  	/*流水灯间隔时间*/
uchar code table[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
uchar code table1[]={0x7e,0xbd,0xdb,0xe7};
void delay(uint i);
void display_led();
void main(void)
{
	LedPort=0xff;
	while(1)
	{
		display_led();
	}
}
void delay(uint i)
{
	uchar t;
	while(i--)
	{
		for(t=0;t<120;t++);
	}
}

  我在display_led()函数中编写了三种控制方法,分别是数组传值、调用函数和使用移位运算符:
  1.数组传值就是直接对LED灯端口给电平,为了保护电路使用低电平驱动,比如使第一个LED灯亮对端口赋值0xfe;
  2.用头文件intrins.h,里面各种移位函数都有,还有NOP()指令。控制LED调用函数_crol_直接移位,后面自动置零。
  3.使用移位运算符时要自己置零。

void display_led()
{
	uint i;
	/**从左到右从右到左*/
		/*控制方式1:数组传值*/
//		for(i=0;i<8;i++)/*防止越界*/
//		{
//			LedPort=table[i];
//			delay(TIME);
//		}
//		for(i=7;i>0;i--)/*防止越界*/
//		{
//			LedPort=table[i-1];
//			delay(TIME);
//		}
		
//		/*控制方式2:调用函数*/
//		LedPort=0xfe;
//		for(i=0;i<7;i++)
//		{
//			delay(TIME);
//			LedPort=_crol_(LedPort,1);
//		}
//		for(i=0;i<7;i++)
//		{
//			delay(TIME);
//			LedPort=_cror_(LedPort,1);
//		}
//		delay(TIME);
		
		/*控制方式3:移位运算符*/
		uchar temp;
		temp=0x01;
		for(i=0;i<8;i++)
		{
			LedPort=~temp;
			delay(TIME);
			temp=temp<<1;
		}
		temp=0x40;
		for(i=0;i<8;i++)
		{
			LedPort=~temp;
			delay(TIME);
			temp=temp>>1;
		}
		
	/**两边到中间中间到两边*/
		for(i=0;i<4;i++)
		{
			LedPort=table1[i];
			delay(TIME);
		}
		for(i=3;i>0;i--)
		{
			LedPort=table1[i-1];
			delay(TIME);
		}
	LedPort=0xff;
	delay(TIME);
}

参考文献
1.《单片机原理与接口技术》张毅刚

返回目录

本文地址:https://blog.csdn.net/qq_43353985/article/details/107937040