灯光定时亮/灭
软件延时/定时器延时
在学会流水灯之前,需要先掌握软件延时,因为,当单片机在处理某些事件的时候我们希望它处理完后间隔一段时间再去处理下一个事件,这时就需要用到延时。常用的延时方法:软件延时、定时器延时。
软件延时例如:
unsigned int i;
i=65535;
while(i);
定时器延时由于我们暂时用不到,所以暂时不做介绍。
IO口与字节位的关系
如果把一个字节的数据赋值给一组IO口,其中数据的最低位对应此组IO口的最低位,数据的最高位对应此组IO口最高位。
IO口:Input和Output接口的含义
例如把十六进制数0xfe赋值给P1口它们的对应关系如下图所示:
编写程序
编译程序和烧录程序的方法在上一个文章中已经写出,相当详细,大家可以去看看上一篇文章
软件延时主要用的是C语言循环结构,十分简单,就不多解释,大家看看就行。
#include <reg52.h>//包含51头文件
unsigned int i;//0~65535
void main()//main函数自身会循环
{
while(1)//大循环
{
P1 = 0; //点亮P1口8个LED
i = 65535;
while(i--);//软件延时
P1 = 0xff;//1111 1111 熄灭P1口8个LED
i = 65535;
while(i--);//软件延时
}
}
上个代码块使用的是反复给P1赋值的方法,在下面我会展示使用按位取反的方法
#include <reg52.h>
unsigned int i;//0~65535
void main()//main函数自身会循环
{
P1 = 0xff;//熄灭8位LED
while(1) //大循环
{
P1 = ~P1; //使用按位取反运算符使LED闪烁
i = 65535;
while(i--);//软件延时
}
}
烧录完成后,单片机会进入循环,灯光就表现为全亮/全灭。由于视频不好弄,就不展示了。
灯光按位亮/灭(流水灯)
循环位移函数
上面我们讲了通过给一组端口赋值来达到控制一组灯光的目的,既然这样,我们就可以对P1端口的值进行操作来达到目的。
这时我们就需要引入循环位移函数,标准库函数:intrins.h,字符型循环左移:_crol_,字符型循环右移:_cror_,
通过这个函数,我们可以调整P1口的顺序,例如以下自定义函数:
#include <intrins.h>
void test_crol (void) {
unsigned char a;
unsigned char b;
a = 0xFE; //1111 1110
b = _crol_(a,1); // b now is 0xFD 二进制为1111 1101
该自定义函数调用按位循环左移函数,将a的值转换为八位二进制的数,首尾相连,向左平移。
循环移位函数与左移和右移运算符的区别
使用字符型循环左移:
void test_crol (void) {
unsigned char a;
unsigned char b;
a = 0xFE; //1111 1110
b = _crol_(a,1); // b now is 0xFD 二进制为1111 1101
}
使用左移运算符
a = 0xFE; //1111 1110
b = a<<1; // b now is 0xFC 二进制为1111 1100
区别:循环左移是把最高位移到最低位上,左移运算符是把最高位移除最低位补0
编写流水灯程序
程序如下
#include <reg52.h> //包含51头文件
#include <intrins.h> //包含移位标准库函数头文件
#define uint unsigned int
#define uchar unsigned char
uchar temp;//LED灯相关变量
/*
函数 : delay(uint z)
参数 :z 延时毫秒设定,取值范围0-65535
返回值 :无
描述 :12T/Fosc11.0592M毫秒级延时
*/
void delay(uint z)
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
void main()//main函数自身会循环
{
temp = 0xfe;
P1 = temp; //1111 1110 初值LED1亮
delay(100);//毫秒级延时 100毫秒
while(1)
{
temp = _crol_(temp, 1);//循环左移
P1 = temp;//移位完成后赋值给P1 每个一个灯点亮
delay(100);//毫秒级延时 100毫秒
}
}
若要达到另一种灯效,可以考虑使用以下主函数进行替代
void main()//main函数自身会循环
{
temp = 0xf0;
P1 = temp; //1111 0000 一次点亮4个灯
delay(100);//毫秒级延时 100毫秒
while(1)//大循环
{
temp = _crol_(temp, 1);//循环左移
P1 = temp;
delay(100);//毫秒级延时 100毫秒
}
}
总结
流水灯程序主要用到了循环位移函数,另外的,还需要掌握宏定义,自定义函数等C语言语法知识。本次学习暂时截止,下一篇文章就看看在线仿真器怎么用吧。