郭天祥十天学完单片机学习笔记第二弹

本文介绍了使用单片机控制流水灯的方法,包括利用宏定义简化代码、自定义延时函数实现不同间隔时间的灯光效果,以及通过循环左移指令控制流水灯的连续变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第二课

这一节主要讲通过各种函数来实现对流水灯的控制,比如延时,流水亮灭等,还有学习如何在软件上调试(有学C语言的话应该都已经学过了)

直接上例子,让第一个灯一间隔500ms闪烁

#include<reg52.h>
#define uint unsigned int
sbit D1=P1^0;
void delay();
void main()
{
	while(1)
	{
		D1=0;
		delay();
		D1=1;
		delay();
	};
}
void delay()
{
	uint a,b;
	for(a=100;a>0;a--)
		for(b=600;b>0;b--);
}

几点注意,define宏定义,使代码更加简洁;自己定义的函数使用前要声明原函数;delay中for语句的嵌套不是必要的。如果要使亮和灭持续时间不同,可以用如下带参数的delay函数,更加灵活。

void delay(uint x)
{
	uint a;
	for(a=x;a>0;a--);
}

例二,流水灯控制

#include<reg52.h>
#include<intrins.h>
unsigned int x,y;
unsigned char tempt;
void delay(unsigned int y);
void main()
{
	tempt=0xfe;
	while(1)
	{
		P1=tempt;
		delay();
		tempt=_crol_(tempt,1)
	}
}
void delay(unsigned int y)
{
	for(x=y;x>0;x--);
}

这个例子可以看出上一个例子中宏定义的方便性,因为多次使用到unsigned int,故可将它定义为更加简单的形式。
_crol_是unsigned char型数据的循环左移,如一开始tempt=0xfe(即1111 1110),左移一次后为(1111 1101)即第二个灯亮,以此类推。
下面用定义位的方式来实现,要麻烦很多

#include<reg52.h>
sbit D1=P1^0;
sbit D2=P1^1;
sbit D3=P1^2;
sbit D4=P1^3;
sbit D5=P1^4;
sbit D6=P1^5;
sbit D7=P1^6;
sbit D8=P1^7;
unsigned int x,y;
void delay(unsigned int);
void main()
{
	while(1)
{
	D1=0;
	delay(50);
	D1=1;
	D2=0;
	delay(50);
	D2=1;
	D3=0;
	delay(50);
	D3=1;
	D4=0;
	delay(50);
	D4=1;
	D5=0;
	delay(50);
	D5=1;
	D6=0;
	delay(50);
	D6=1;
	D7=0;
	delay(50);
	D7=1;
	D8=0;
	delay(50);
	D8=1;
}	
}
void delay(unsigned int y)
{
	x=y;
 while(x>0)
 {x--;}
}

作业:
在这里插入图片描述2.这里需要了解单片机如何控制蜂鸣器工作。

#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit FM=P2^3;
void delay(uint);
uchar tempt;
uint x,y,z;
void main()
{
	tempt=0xfe;
	while(1)
	{
	P1=tempt;
	FM=0;
	delay(20);
	P1=0xff;
	FM=1;
	delay(20);
	tempt=_crol_(tempt,1);
	}
}	
void delay(uint z)
{
	x=z;
 while(x>0)
 {
	 y=2500;
	 while(y>0)
	 {y--;}
		x--;
	}
}

提醒一下自己用到函数的时候不要老是忘了include函数库啊
4.用减法实现加法,tempt=0xfe时第一个灯亮代表一,tempt=tempt-1,第二个灯亮代表二,以此类推。

5.这个需要比较细心,有点麻烦,不过调试出来成功了还是挺开心的,耶~

#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
uint x,y,z,t;
uchar tempt;
void delay(uint);
void main()
{ 
while(1)
{
	t=1;
	while(t<=2)
	{
		t++;
		tempt=0xfe;
		P1=tempt;
		delay(200);
		while(tempt>0x7f)
		{
			tempt=_crol_(tempt,1);
			P1=tempt;
			delay(200);
		};
		while(tempt<0xfe)
		{
			tempt=_cror_(tempt,1);
			P1=tempt;
			delay(200);
		};
		
		while(t<=7)
		{
			t++;
			tempt=0xff;
			P1=tempt;
			delay(300);
		
			tempt=0x00;
			P1=tempt;
			delay(300);	
		}
		}
}
}
void delay(uint z)
{
	for(x=z;x>0;x--)
		for(y=150;y>0;y--);
}

这里函数声明时原本用了delay(uint),这样没有确定返回类型,则使用默认定义,后面对函数进行定义时有void返回类型,编译器会以为你对同个函数进行不同定义,会出现函数redefinition报错;

#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
uint x,y,z,t;
uchar tempt;
void delay(uint);
void main()
{
	tempt=0xfe;
	while(1)
	{
		t=0;
		while(t<8)
		{
			t++;
			P1=tempt;
			delay(300);
			tempt=_crol_(tempt,1);
		};
		tempt=0xfc;
		while(t<16)
		{
			t++;
			P1=tempt;
			delay(300);
			tempt=_crol_(tempt,1);

		};
		tempt=0xf8;
		while(t<24)
		{
			t++;
			P1=tempt;
			delay(300);
			tempt=_crol_(tempt,1);	
		};
		tempt=0xf0;
		while(t<32)
		{
			t++;
			P1=tempt;
			delay(300);
			tempt=_crol_(tempt,1);	
		};
		tempt=0xe0;
		while(t<40)
		{
			t++;
			P1=tempt;
			delay(300);
			tempt=_crol_(tempt,1);	
		};
		tempt=0xc0;
		while(t<48)
		{
			t++;
			P1=tempt;
			delay(300);
			tempt=_crol_(tempt,1);	
		};
		tempt=0x80;
		while(t<56)
		{
			t++;
			P1=tempt;
			delay(300);
			tempt=_crol_(tempt,1);	
		};
		tempt=0x00;
		P1=tempt;
	}
}
void delay(uint z)
{
	for(x=z;x>0;x--)
		for(y=150;y>0;y--);
}

7,这里只实现两个灯从两端往中间流动部分

#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
sbit D1=P1^0;
sbit D2=P1^1;
sbit D3=P1^2;
sbit D4=P1^3;
sbit D5=P1^4;
sbit D6=P1^5;
sbit D7=P1^6;
sbit D8=P1^7;
uint x,y,z,t;
void delay(uint);
void main()
{
	D1=D8;
	D2=D7;
	D3=D6;
	D4=D5;
	t=0;
	while(t<3)
	{
		t++;
		D1=0;
		delay(300);
		D1=1;
		D2=0;
		delay(300);
		D2=1;
		D3=0;
		delay(300);
		D3=1;
		D4=0;
		delay(300);
	};
}
void delay(uint z)
{
	for(x=z;x>0;x--)
		for(y=150;y>0;y--);
}

okay,今天先学到这里啦~

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值