注意:本实验采用清翔电子51单片机开发板(同样的51单片机开发板,不同型号,内部设计会有一定差异,程序不一定适用)
1、点亮一个灯
#include <reg52.h> //引用51头文件
sbit LED1 = P1^0; //位地址声明,注意:sbit 必须小写,P 大写!
void main() //头文件
{
LED1 = 0; //点亮P1.0上的小灯
}
效果图:
点亮多个灯的方法:简单来说,多sbit定义几个就行,在此不再展开。
2、闪烁一个灯
#include <reg52.h>
sbit LED1 = P1^0;
unsigned int i = 0;//定义一个无符号整数(声明部分)
void main() //void即函数类型,无返回值
{
while (1)
{
LED1 = 0; //点亮小灯
for (i=0; i<30000; i++); //延时
LED1 = 1; //熄灭小灯
for (i=0; i<30000; i++); //延时
}
}
现象:点亮的第一个灯闪烁
闪烁全部灯
#include<reg52.h>
unsigned int i; //无符号整型,范围0~65535
void main()
{
while(1) //大循环
{
P1 = 0x00; //全亮
i = 65535;
while(i--); //延时
P1 = 0xff; //全灭
i = 65535;
while(i--); //延时
}
}
因为是所有灯,所以直接用取反指令也可 P1=~ P1;
现象:
3、流水灯
方法一
#include<reg52.h>
unsigned int i=0; //无符号整型 范围0-65535
unsigned char cnt=0; //无符号字符型 范围0-255,省字节,所以用这个,无符号整型也可以的
void main()
{
while(1) //大循环
{
for(cnt=0;cnt<8;cnt++) //最多移动7位,加上不移动,总共八次
{
P1 = ~(0x01<<cnt); //左移cnt位,然后取反,刚好达到效果
for(i=0;i<30000;i++); //延时
}
}
}
现象:左移依次循环点亮
在这里补充一下左移的知识,
若P1=0xfe,即二进制为1111 1110
P1<<1;P1左移一位后
为1111 1100,移动时自动填零,所以上述程序采用了取反,来达到效果
方法二
使用这个字符循环左移库函数_cror_
#include <reg52.h> //包含51头文件
#include <intrins.h> //包含移位标准库函数头文件,这里用到了这个_crol_
#define uint unsigned int
#define uchar unsigned char
uchar temp;
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毫秒
}
}
现象:左移依次循环点亮
补充下这个_cror_:
如果
a=0xfe;//1111 1110
b=_crol_(a,1) ;//左移1位后将高位补低位,1111 1101
4、蜂鸣器
#include<reg52.h>
unsigned int i = 0; //无符号整型 范围0-65535
unsigned char cnt = 0; //无符号字符型 范围0-255,省字节,所以用这个,无符号整型也可以的
sbit beep = P2^3; //蜂鸣器
void main()
{
while(1) //大循环
{
for(cnt=0;cnt<8;cnt++) //最多移动7位,加上不移动,总共八次
{
P1 = ~(0x01<<cnt); //左移cnt位,然后取反,刚好达到效果
beep = ~beep; //蜂鸣器发滴滴声
for(i=0;i<30000;i++); //延时
}
}
}
现象:流水灯左移,亮灭一次蜂鸣器发一声,跑一趟总共发四声。
beep = 0;是蜂鸣器响,这里的取反是为了让它发滴滴声,而不是一直响。值得注意的是蜂鸣器发声的延时时间不能太短,不然它就一直叫。
总结一下:方法千万条,多练第一条