1.流水灯
方法一:
#include <REGX52.H>
//也可以使用<REG52.H> 缺点是只能对P2整体操作,不能操作单独操作一位,如P2_0
#include <INTRINS.H>
//这个库里面有_nop_()
void Delay1ms(unsigned int time) //@11.0592MHz
{
unsigned char i, j;
while(time--){
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
}
int main(){
while(1)
{
/*51单片机是大段存储,
因此1111 1110是点亮P27~P20中的P20*/
P2=0xFE;//1111 1110 P20对应原理图的D1(第一个灯)
Delay1ms(100);
P2=0xFD;//1111 1101
Delay1ms(100);
P2=0xFB;//1111 1011
Delay1ms(100);
P2=0xF7;//1111 0111
Delay1ms(100);
P2=0xEF;//1110 1111
Delay1ms(100);
P2=0xDF;//1101 1111
Delay1ms(100);
P2=0xBF;//1011 1111
Delay1ms(100);
P2=0x7F;//0111 1111
Delay1ms(100);
}
}
方法二:
使用位运算的方法(非逻辑运算)
增:| a=xxxx xxxx,把D0位变成1 a |= 1<<0
删:&~ a=xxxx xx1x,把D1位变成0 a &=~(1<<1)
查:& a=xxxx x1xx,查D2位是否为1 a &=(1<<2) 如果a不为零,说明D2位是1
#include <REGX52.H>
#include <INTRINS.H>
void Delay1ms(unsigned int time) //@11.0592MHz
{
unsigned char i, j;
while(time--){
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
}
int main(){
unsigned char LedFlg=0;
while(1)
{
char count=0;
for(count=0;count<8;count++){
P2=~(LedFlg|(1<<count));
Delay1ms(100);
}
}
}
2.按键控制led灯
1.K1长按亮灯,松手不亮:
#include <REGX52.H>
//不可以使用<REG52.H> 只能对P2整体操作,不能操作单独操作一位,如P2_0
void main(){
while(1)
{
if(P3_1==0) //如果K1按键
P2_0=0;
else
P2_0=1;
}
}
2.K1按下切换亮灭
#include <REGX52.H>
#include <INTRINS.H>
void Delay1ms(unsigned int time) //@11.0592MHz
{
unsigned char i, j;
while(time--){
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
}
void main(){
while(1)
{
if(P3_1==0){ //如果K1按键
Delay1ms(10);//按下消抖
while(P3_1==0);
Delay1ms(10);//抬起消抖
P2_0=~P2_0;
}
}
}
3.K1按下led灯右移,
3.控制八个LED灯实现二进制加法
#include <REGX52.H>
#include <INTRINS.H>
void Delay1ms(unsigned int time) //@11.0592MHz
{
unsigned char i, j;
while(time--){
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
}
void main(){
unsigned char num=0;
while(1)
{
if(P3_1==0){ //如果K1按键
Delay1ms(10);//按下消抖
while(P3_1==0);
Delay1ms(10);//抬起消抖
num++;
P2=~num;
}
}
}
要按 (256)次才能实验按完,太累了,如果按着不动就可以自动加,只需要去掉抬手的代码(24和25行)。
4.思考
1.
#include <REGX52.H>
#include <INTRINS.H>
void Delay1ms(unsigned int time) //@11.0592MHz
{
unsigned char i, j;
while(time--){
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
}
void main(){
unsigned char num=0;
while(1)
{
if(P3_1==0){ //如果K1按键
Delay1ms(10);//按下消抖
num++;
}else if(P3_0==0){
num--;
Delay1ms(10);
}
P2=~num;
}
}
上述代码按键同时按下的话是只能加,不能减。如何实现同时按下不加也不减。(判断的先后顺序很重要)
驱动库分享整理(1)——用于单片机中的小巧多功能按键支持库_单片机 state machine 库-CSDN博客
2.如果led灯不进行加法,而是进行移位,需要改哪些。
#include <REGX52.H>
#include <INTRINS.H>
void Delay1ms(unsigned int time) //@11.0592MHz
{
unsigned char i, j;
while(time--){
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
}
void main(){
unsigned char count=0;
P2=0xFE;
while(1)
{
if(P3_1==0){ //如果K1按键
Delay1ms(20);//按下消抖
while(P3_1==0);
Delay1ms(20);
if(count==7)
count=0;//加之前一定要先检查count的值快超了吗
else
count++;
P2=~(0x01<<count);
}else if(P3_0==0){
Delay1ms(20);
while(P3_0==0);
Delay1ms(20);
if(count==0)
count=7;
else
count--;
P2=~(0x01<<count);
}
}
}