🏆文章目录
❤️第一话——单片机延时和秒数单位换算
我们知道程序是一步步执行下去的,遇到循环做循环、遇到跳转做跳转,我们单片机程序也一样,想要用到单片机延时其实就是让程序执行循环,让程序走迷宫,至于花多少时间走出这个迷宫,就看我们的循环判定条件规定多大了。
😃 1.1 单片机的四种延时方法
1. 用for延时: 这个比较容易理解,让for里面的变量递增,一直递增到你规定的的判定条件的大小(图中为i<100),这个期间,单片机会一直判断,所以就起到延时效果,不过一般要规定很大的数才有效果。
2.用while延时: 这个的做法和for类似,while的判断条件为0或1,非0的都为真;我们规定的i,让它递减,一直递减到0,跳出循环,在此期间也会一直判断,让程序在循环里走迷宫。
3.用定时器延时: 这个延时主要与单片机的频率和机器周期有关,作为延时用更精确一些,通常会和中断配合使用,后面讲中断会细讲。
4.用库函数延时: 利用_nop_()库函数延时首先需要调用"#include <intrins.h>头文件,然后再来使用,下面列子会讲解。
😂 1.2 毫秒、微秒、纳秒单位换算
有时我们需要延时几秒,有时需要延时几毫秒,所以一定要会相互的单位转换!
1s=1000ms;1ms=1/1000s;
1s=1000000us;1us=1/1000000s;
1s=1000000000ns
(s——秒;ms——毫秒;ns——纳秒)
❤️第二话——单片机的点灯操作
🌿2.1让一个LED端口亮灭
#include <reg51.h> //51单片机的头文件
void delay25ms() /*---------------------------------------------------*/
{
unsigned char i,j; /*--------------------------------------------------*/
i=45;
j=208;
do /*延时25ms;太快的话肉眼观察不出来,这个延时尽量长一些*/
{
while(--j);
} while(--i); /*-----------------------------------------------*/
} /*-----------------------------------------------*/
sbit LED=P2^0; //让定义P2.0这个端口叫LED
void main()
{
while(1)
{
LED=0; //让P2.0输出低电平,点亮LED
delay25ms(); //延时25毫秒
LED=1; //让P2.0输出高电平,熄灭LED
delay25ms(); //再延时25毫秒,在while循环里一直做这些事情,LED就一直亮灭亮灭了
}
}
延时多久,可以用STC的软件,其中可以生成延时函数:
STC89系列注意选择指令集STC-Y1系列
🍀2.2让一个LED端口亮几次灭掉
#include <reg51.h>
void delay25ms() /*---------------------------------------------------*/
{
unsigned char i,j; /*--------------------------------------------------*/
i=45;
j=208;
do /*写一个25ms的延时函数,后面直接调用这个函数 */
{
while(--j);
} while(--i); /*-----------------------------------------------*/
}
sbit LED=P2^0; //这里随便定义,根据自己开发板的LED引脚来定义即可
void main()
{
unsigned char i; //先定义一个变量i,让程序明白有这么个东西需要用
for(i=0;i<6;i++) //用for循环判断,判断一次执行大括号里面的东西,也就是LED亮灭一次,这里执行6次,第7次跳出循环
{
LED=0;
delay25ms();
LED=1;
delay25ms();
}
while(1) //跳出循环后,进入这个死循环,让这个口一直处于高电平,LED就一直灭着了
{
LED=1;
}
}
🌸2.3 让LED端口流水灯形式动作
/*****************最简单写法*******************/
#include <reg51.h>
void delay25ms() /*---------------------------------------------------*/
{
unsigned char i,j; /*--------------------------------------------------*/
i=45;
j=208;
do /*写一个25ms的延时函数,后面直接调用这个函数 */
{
while(--j);
} while(--i); /*-----------------------------------------------*/
}
sbit LED1=P2^0; /*-------------------------*/
sbit LED2=P2^1;
sbit LED3=P2^2;
sbit LED4=P2^3;
/* 这里是对应8个LED一一对应P2.0到P2.7的8个引脚*/
sbit LED5=P2^4;
sbit LED6=P2^5;
sbit LED7=P2^6;
sbit LED8=P2^7; /*-------------------------*/
void main()
{
while(1)
{
LED1=0; //第一个LED灯亮灭完。第二个亮灭,依次执行下去就形成了流水灯的效果
delay25ms() ;
LED1=1;
delay25ms() ;
LED2=0;
delay25ms() ;
LED2=1;
delay25ms() ;
LED3=0;
delay25ms() ;
LED3=1;
delay25ms() ;
LED4=0;
delay25ms() ;
LED4=1;
delay25ms() ;
LED5=0;
delay25ms() ;
LED5=1;
delay25ms() ;
LED6=0;
delay25ms() ;
LED6=1;
delay25ms() ;
LED7=0;
delay25ms() ;
LED7=1;
delay25ms() ;
LED8=0;
delay25ms() ;
LED8=1;
delay25ms() ;
}
}
/********************用移位的方法写流水灯程序*********************/
#include <regx51.h>
void delay25ms() /*---------------------------------------------------*/
{
unsigned char i,j; /*--------------------------------------------------*/
i=45;
j=208;
do /*写一个25ms的延时函数,后面直接调用这个函数 */
{
while(--j);
} while(--i); /*-----------------------------------------------*/
}
void main()
{
unsigned char cnt=0; //定义了一个计数器,并赋初值为0
while(1)
{
P2=0XFE<<cnt; //0XFE代表P2.0这个端口输出为0,也就是LED1亮,其他都灭(转化成二进制就清楚了 1111 1110);
//左移0位相当于没有移
delay25ms(); //延时25毫秒
cnt++; //让计数器累加,就可以依次移动一位,从一个端口变成相邻的端口
if(cnt>=8) //移的位数超过8位,从0位在开始移动8位
{
cnt=0;
}
}
}
🏆2.4 扩充知识——逻辑运算、位运算
(1)逻辑与(&&): 假设A=1,B=1→A&&B就为真;逻辑与要两个条件都为真,均要满足才为真。
(2)逻辑或(||): A和B其中满足一个为真,A||B就为真
(3)逻辑非(!): 逻辑非有两种结果,要么是0要么是1;指本来值的反值。
(4)按位左移(<<): 假设有数据0111 0001按位左移即向左移一位,没有的位补0,最左边移出的去掉,按位左移后为1110 0010。
(5)按位右移(>>): 按位右移就是按位左移反过来,还是上面的数据0111 0001,按位右移后为0011 1000。
(6)按位与(&): 1111 1100 & 1111 1001的结果为1111 1000;一位和一位的与,都为1才为真也就是1。
(7)按位或(|): 1111 1100 | 1111 1001的结果为1111 1101;每一位对照,有1则1。
(8)按位异或(^): 1111 1100 ^ 1111 1001的结果为0000 0101;每一位对照,一样位的为0,不一样的位为1。
9)按位取反(~): ~1010 0011的结果为0101 1100;每一位取反。