🎊专栏【51单片机】
🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。
🎆音乐分享【如愿】
大一同学小吉,欢迎并且感谢大家指出我的问题🥰
目录
⭐注意
🍔同一个灯
🏳️🌈效果
🏳️🌈代码
🏳️🌈问题分析
⭐注意
⭐P3_1=0,表示按下按键
⭐为什么while(P3_1==0);后面要加上分号呢?
⭐两个Delay(20)的作用
⭐P2_0=~P2_0;
🍔不同灯(显示二进制移位)
🏳️🌈效果
🏳️🌈代码
🏳️🌈原因
🍔流水灯(按一下按键,灯亮的位置才会变化)(移位)
🏳️🌈效果
🏳️🌈代码
🏳️🌈解释
🍔流水灯(按一下,灯亮的位置自动改变)
🏳️🌈效果
🏳️🌈代码例子&&解释
main.c
Timer0.c
🎆为什么主函数没有调用中断函数,但是中断函数为什么会执行呢
Timer0.h
Key.c
Key.h
Delay.c
Delay.h
文章来源地址https://www.toymoban.com/news/detail-429705.html
⭐注意
由图片可知,要使用P3口
🍔同一个灯
🏳️🌈效果
led灯闪烁
🏳️🌈代码
#include <REGX52.H>
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms){
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
void main()
{
while(1)
{
if(P3_1==0)//按下
{
Delay(20);
while(P3_1==0);//仍然按下
Delay(20);
P2_0=~P2_0;
}
}
}
着重分析下面的代码
while(1)
{
if(P3_1==0)
{
Delay(20);
while(P3_1==0) ;
Delay(20);
P2_0=~P2_0;
}
}
🏳️🌈问题分析
⭐注意
1.在这个程序里面,最好用类似于P3_1=0的代码,不要用类似于P2=0xFE的代码,因为后者很容易迷糊
(如果是流水灯,可以用P2=0xFE)
2.Delay()函数里面用的是自动延时代码,可以由软件自动生成,如果不明白是怎么肥四,可以参考下面这篇文章
【51单片机】使用STC烧录软件自动生成延时代码_在下 小吉的博客-CSDN博客
⭐P3_1=0,表示按下按键
⭐为什么while(P3_1==0);后面要加上分号呢?
在观察现象的时候发现,按一次松手,灯亮了,再按一次松手,灯灭了
所以,这样子主要是为了一直按着按键的时候,防止灯亮
(而且不能改为P3_1=0,因为这里必须是循环语句或者判断语句)
⭐两个Delay(20)的作用
如图
第一个Delay(20)是作用于前面抖动的部分
第二个Delay(20)是作用于后面抖动的部分(防止松手时影响灯的亮度)
⭐P2_0=~P2_0;
就是控制LED的开关状态,使其可以闪烁
🍔不同灯(显示二进制移位)
🏳️🌈效果
多个led灯亮
🏳️🌈代码
#include <REGX52.H>
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms){
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
void main()
{
unsigned char LEDNum=0;
while(1)
{
if(P3_1==0)
{
Delay(20);
while(P3_1==0);
Delay(20);
LEDNum++;
P2=~LEDNum;
}
}
}
🏳️🌈原因
请看下图
P2=~LEDNum;由于二进制数字的变化,所以会引起灯的变化
🍔流水灯(按一下按键,灯亮的位置才会变化)(移位)
🏳️🌈效果
WeChat_20230425133443
🏳️🌈代码
#include <REGX52.H>
unsigned char LEDNum;
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms){
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
void main()
{
while(1)
{
if(P3_1==0)
{
Delay(20);
while(P3_1==0);
Delay(20);
if(LEDNum>=8)
LEDNum=0;
P2=~(0x01<<LEDNum);
LEDNum++;
}
if(P3_0==0)//多个按键操作
{
Delay(20);
while(P3_0==0);
Delay(20);
if(LEDNum==0)//反方向的流水灯
LEDNum=7;
else
LEDNum--;
P2=~(0x01<<LEDNum);
}
}
}
🏳️🌈解释
🍔流水灯(按一下,灯亮的位置自动改变)
🏳️🌈效果
按键流水灯
🏳️🌈代码例子&&解释
main.c
#include <REGX52.H>
#include "Timer0.h"
#include "Key.h"
#include <INTRINS.H>
unsigned char KeyNum,LEDMode;
void main()
{
P2=0xFE;
Timer0Init();
while(1)
{
KeyNum=Key(); //获取独立按键键码
if(KeyNum!=0) //如果按键按下
{
//if(KeyNum==1) //如果K1按键按下
//{
LEDMode++; //模式切换
if(LEDMode>=2)LEDMode=0;
//}
}
}
}
void Timer0_Routine() interrupt 1
{
static unsigned int T0Count;
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
T0Count++; //T0Count计次,对中断频率进行分频
if(T0Count>=500)//分频500次,500ms
{
T0Count=0;
if(LEDMode==0) //模式判断
P2=_crol_(P2,1); //LED输出
//_crol_循环左移
if(LEDMode==1)
P2=_cror_(P2,1);
//_cror_循环右移
}
}
⭐_crol_循环左移
⭐_cror_循环右移
⭐使用定时器中断的原因(请看图片)
Timer0.c
#include <REGX52.H>
/**
* @brief 定时器0初始化,1毫秒@12.000MHz
* @param 无
* @retval 无
*/
void Timer0Init(void)
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;
EA=1;
PT0=0;
}
/*定时器中断函数模板
void Timer0_Routine() interrupt 1
{
static unsigned int T0Count;
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
T0Count++;
if(T0Count>=1000)
{
T0Count=0;
}
}
*/
🎆为什么主函数没有调用中断函数,但是中断函数为什么会执行呢
当调用Timer0Init()
函数时,就会开启定时器0中断,并将中断服务函数的入口地址设置为Timer0_Routine()
函数的地址(这个过程涉及到中断向量表的设置,一般由编译器完成)。而每当定时器0中断被触发时,就会跳转到Timer0_Routine()
函数执行其中的代码。因此,即使主函数没有显式调用中断函数,中断函数也会被执行。
上面一段代码不明白的同学可以参考一下这一篇博客
【51单片机】使用STC烧录软件生成定时器的代码以及注意事项_在下小吉.的博客-CSDN博客
Timer0.h
#ifndef __TIMER0_H__
#define __TIMER0_H__
void Timer0Init(void);
#endif
Key.c
#include <REGX52.H>
#include "Delay.h"
/**
* @brief 获取独立按键键码
* @param 无
* @retval 按下按键的键码,范围:0~4,无按键按下时返回值为0
*/
unsigned char Key()
{
unsigned char KeyNumber=0;
if(P3_1==0){Delay(20);while(P3_1==0);Delay(20);KeyNumber=1;}
if(P3_0==0){Delay(20);while(P3_0==0);Delay(20);KeyNumber=2;}
if(P3_2==0){Delay(20);while(P3_2==0);Delay(20);KeyNumber=3;}
if(P3_3==0){Delay(20);while(P3_3==0);Delay(20);KeyNumber=4;}
return KeyNumber;
}
因为图片中的就是P3口
所以最好使用P3口的4个引脚(P3_0~P3_3)
Key.h
#ifndef __KEY_H__
#define __KEY_H__
unsigned char Key();
#endif
Delay.c
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
上面一段代码不明白的同学可以参考一下这篇博客
【51单片机】使用STC烧录软件自动生成延时代码_在下小吉.的博客-CSDN博客
Delay.h
#ifndef __DELAY_H__
#define __DELAY_H__
void Delay(unsigned int xms);
#endif
🥰如果大家有不明白的地方,或者文章有问题,欢迎大家在评论区讨论,指正🥰 文章来源:https://www.toymoban.com/news/detail-429705.html
到了这里,关于【51单片机】按键操作(单个灯闪烁&&流水灯)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!