【BY2HIT--C51系列】001-LED
哈尔滨工业大学业余无线电俱乐部51单片机系列
001 LED
第一个程序,寄存器直接控制IO口
#include <REG52.h>
void main(){
/*P3寄存器是一个八位寄存器,每一位对应着一个IO口,通过每一位的1 0 来控制IO口电平的高低。类似开关*/
P3=0x3F; //0011111 即P3.6 P3.7为低电平
while(1); //卡死程序!
}
注意,此处P3寄存器是7~0,左为高位
第二个程序,sbit位操作
#include <reg52.h>
sbit led0=P3^6;
sbit led1=P3^7;
void main()[
led0=0; //像单独控制一个开关,而不是像之前控制一组八个开关
led1=0;
while(1);
}
第三个程序,延时+闪烁
#include <reg52.h>
sbit led0=P3^6;
sbit led1=P3^7;
void delay_ms(unsigned int x);
void main(){
while(1){
led0=0;
led1=0;
delay_ms(1000);
led0=1;
led1=1;
delay_ms(1000);
}
}
/*软件延时,就是让CPU执行无用的指令,占用时间,下面程序是24M12分频,大概计算的一个程序,时间不一定准*/
void delay_ms(unsigned int x){
int y,z;
for(y=x;y>0;y--)
for(z=960;z>0;z--);
}
上述的程序有一点小缺陷,就是对led1与led0 进行了赋值操作,很容易输错。
看看下面的解决方案。
#include <reg52.h>
sbit led0=P3^6;
sbit led1=P3^7;
void delay_ms(unsigned int x);
void main(){
led0=1; //这次我们来实现一个交替闪烁的效果
led1=0;
while(1){
led0=~led0; //这个操作是取反,0变1 1变0
led1=~led1; /*这样就真正的像一个开关一样,没操作一次就相当于按下一次开关,改变了一次状态*/
delay_ms(1000);
}
}
/*软件延时,就是让CPU执行无用的指令,占用时间,下面程序是24M12分频,大概计算的一个程序,时间不一定准*/
void delay_ms(unsigned int x){
int y,z;
for(y=x;y>0;y--)
for(z=960;z>0;z--);
}
如果我们有一排LED呢(八个)
上面的方法好像都不太适用了!
这次我们用到的是位移操作符
看看我的解决办法:
#include <reg52.h>
#define uchar unsigned char
sbit LED1=P3^6;
sbit LED2=P3^7;
void delay_ms(unsigned int x);
void main(){
char temp;
temp=0x80; //1000 0000
do{
delay_ms(1000);
P3=~temp; //取反!
temp>>=1; //右移一次,高位用0补位
if(temp==0x00){
temp=0x80;
}
} while(1);
}
void delay_ms(unsigned int x)
{
int y,z;
for(y=x;y>0;y--)
for(z=960;z>0;z--);
}
第一次执行 :
temp 1000 0000
P3 0111 1111
右移
temp 0100 0000
总结
别看一个简单的LED程序,但是包含了后期好多种算法,大家好好理解!