51单片机学习
1闪烁LED
1.1 需求描述
这个案例,我们要让P00引脚对应的LED按照1秒闪烁1次。
1.2 硬件设计
1.1 软件设计
1)LED闪烁的代码
想让LED闪烁,就需要P00的值不断在0和1之间循环变化。实现这一功能的代码也很简单:
#include <STC89C5xRC.H> //包含STC89C52的头文件
#include <INTRINS.H>
sbit g_led = P0 ^ 0;
void Delay_1MS(unsigned int count);
void main()
{
// 让led变为低电位
g_led = 0;
// 死循环卡住单片机,让它不要继续往下执行
while (1)
{
// 对led不断取反,取反就是亮灭转换
g_led = ~g_led;
// 延时500ms
Delay_1MS(500);
}
}
void Delay_1MS(unsigned int count) //@11.0592MHz
{
unsigned char data i, j;
while (count > 0)
{
_nop_();
i = 2;
j = 199;
do
{
while (--j)
;
} while (--i);
count--;
}
}
2)代码解读
(1)延时函数说明
这段代码中,LED闪烁的部分其实相当简单,就是对LED变量不断取反。亮灭的节奏主要取决于延时函数的实现。那我们如何实现一个1ms的延时函数呢?这里,我们可以使用STC-ISP自带的软件延时计算器。打开STC-ISP,选择软件延时计算器标签,指定时长1ms,指令集选择STC-Y1(说明:STC89/STC90单片机都是Y1指令集),即可得到1ms的延时代码。
(2)延时的原理
由于执行每条指令都需要时间,那么可以通过不断的执行指令以达到延迟的效果。具体执行一条指令需要多长时间,我们来计算一下。
时钟周期=1/晶振频率=1/11.0592MHz≈0.09us
机器周期=12时钟周期(约等于1.08us)。
指令周期=1条指令完成所需要的时钟周期(一般12/24/48)。
2 流水灯
2.1 需求描述
本案例我们会让P00到P07的LED依次亮起,间隔100ms,不断循环。
2.2 硬件设计
2.2.1 硬件原理图
2.3 软件设计
#include <STC89C5xRC.H> //包含STC89C52的头文件
#include <INTRINS.H>
// 增加自定义类型,简化代码编写
typedef unsigned char u8;
typedef unsigned int u16;
// 声名延时函数
void Delay_1MS(u16 count);
void main()
{
// 声名临时变量
u8 temp = 1;
// temp是8个bit,对应8个led,1代表亮,正好和P0相反
// 之后我们只要对temp做左位移,即可实现流水灯
while (1)
{
// P0 是temp取反;0000 0001 取反 1111 1110
P0 = ~temp;
// 左移依次为:0000 0001,0000 0010,0000 0100,0000 1000,… 1000 0000
temp <<= 1;
// temp是char类型8位,如果等于1000 0000,再左移一位就变成0000 0000,所以如果temp等于0时,需要将temp再设置为1
if (temp == 0)
{
temp = 1;
}
// 延时100ms