概要
如何通过51单片机点亮灯笔记
具体原理与思路
从I/O口设置输出高低电平,通过杜邦线连接对应的灯光串口。灯光串口根据接收到的高电平或低电平来选择亮或者不亮。
点亮灯光的几种方式
-
端口直接赋值
-
多位次赋值
端口值赋值
通过sbit关键字将某一串口命名变量,并且通过这个变量设值来实现设置串口输出的高低电平。(也有另一个关键字srf,此关键字多用于单片机内部预先定义的串口地址)
例如:
- sbit LED = P2^2; /*直接将LED变量指向P2^2口,通过改变LED的值,可以改变P2^2口的电压变化*/
- srf P0 = 0x80; /*单片机内部地址0x80处的寄存器重新起名为P0,在程序中对P0的操作,就是对该地址的操作*/
多位次赋值
如果打算同时控制多个灯光的话,一位一位的给串口赋值很麻烦,通过多位次赋值实现多个灯光控制。八个灯光用八个二进制位表示,每四个二进制位为一个十六进制位。通常使用两位十六进制位来设置灯光。
例如
- P2 = 0x7E /*连接P2组与LED组杜邦线后,通过直接设置P2组值,实现对应串口灯光亮灭 相当于 0111 1110 设置D1和D8灯光*/
基础练习
-
依次点亮D1,D2,D3,D4,D5,D6,D7,D8
实现代码:
#include "reg52.h"
typedef unsigned int u16;
typedef unsigned char u8;
void Delay_10us(u16 ten_us)
{
while(ten_us--);
}
void main()
{
while(1)
{
/* 依次点亮D1,D2,D3,D4,D5,D6,D7,D8灯光*/
P2 = 0xfe;
Delay_10us(10000);
P2 = 0xfd;
Delay_10us(10000);
P2 = 0xfb;
Delay_10us(10000);
P2 = 0xf7;
Delay_10us(10000);
P2 = 0xef;
Delay_10us(10000);
P2 = 0xdf;
Delay_10us(10000);
P2 = 0x7f;
Delay_10us(10000);
}
}
-
使用端口赋值,同时点亮D1和D8;同时点亮D2和D7;同时点亮D3和D6 ;同时点亮D4和D5 .
实现代码:
#include "reg52.h"
typedef unsigned int u16;
typedef unsigned char u8;
void Delay_10us(u16 ten_us)
{
while(ten_us--);
}
void main()
{
while(1)
{
P2 = 0x7e;
Delay_10us(100000);
P2 = 0xbd;
Delay_10us(100000);
P2 = 0xdb;
Delay_10us(100000);
P2 = 0xe7;
Delay_10us(100000);
}
}
进阶练习
流水灯练习: 流水灯实现的四种方式
- 端口赋值+延时点亮
- 数组赋值+延时点亮
实现原理:
通过在数组中设置对应八个灯的十六进制位,再遍历该数组即可。
- 移位符号+延时点亮------此种方法是累加点亮
实现原理:
- 左循环 /右循环函数+延时点亮(需引入intrins.h头部文件)
字符循环左移 _crol_
字符循环右移 _cror_
实现原理:
循环左移 : 将最低位向左移动一位,最高位循环至最低位。通过此原理实现D1-D8点亮
循环右移 : 将最高位向右移动一位,最低位循环至最高位。通过此原理实现D8-D1点亮
实现代码:
#include "reg52.h"
#include "intrins.h"
#define led P2 //将P2组地址赋值给led变量
typedef unsigned int u16;
void Delay_10us(u16 ten_us)
{
while(ten_us--);
}
/* 灯光右循环*/
void left_light()
{
led = _crol_(led,1);
Delay_10us(100000);
}
/* 灯光左循环*/
void right_light()
{
led = _cror_(led,1);
Delay_10us(100000);
}
void main()
{
u16 i;
led = 0xfe; //点亮D1灯,用来开始循环
while(1)
{
for(i=0;i<7;i++)
{
left_light();
}
for(i=0;i<7;i++)
{
right_light();
}
}
}