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;// 延时500msDelay_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 1110P0 = ~temp;// 左移依次为:0000 0001,0000 0010,0000 0100,0000 1000,… 1000 0000temp <<= 1;// temp是char类型8位,如果等于1000 0000,再左移一位就变成0000 0000,所以如果temp等于0时,需要将temp再设置为1if (temp == 0){temp = 1;}// 延时100ms