学习要以解决实际问题出发。
这里模拟下风扇的3个档位吧,按一下一档,按一下二灯亮,别的灯熄灭,按一下3档位。
这是我画的图。
直接上代码吧,代码写的很啰嗦,肯定有更精简的方法的,这里先上啰嗦代码吧,如果以后又优化,gitee那边是最终代码。
/********************************************************************
日 期:2022/05/24
功 能: 简单按键识别,按键控制灯亮或者灭 芯片型号STC15F104W
编 写:劲松电脑通讯 www.jvbaopeng.com
*********************************************************************/
#include <stc15.h> //引入库文件,这个直接下载器里复制保存为stc15.h
#define CPU_Fosc 12000000uL //定义主时钟
#define uint unsigned int //宏定义无符号整型
/********************************************************************
I/O定义
*********************************************************************/
sbit LED1=P3^0; //定义单片机P3口的第0位 (即P3.0)//定义5脚接灯
sbit LED2=P3^1; //定义单片机P3口的第2位 (即P3.1)//6脚
sbit LED3=P3^4; //这里接1脚,因为7脚按键占位置了
sbit key1=P3^2; //定义单片机P3口的第2位 (即P3.2)//为按键输入 这里是7脚
uint status =0 ; //这里用标志位区分是按了几次键
//========================================================================
// 函数: void delayms(unsigned int ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~65535ms. 自动适应主时钟.
// 返回: none.
//========================================================================
void delayms(unsigned int ms)
{
unsigned int i;
do{
i = CPU_Fosc/13000;
while(--i);
}
while(--ms);
}
/***************************主函数*****************************************/
void main()
{
LED1 = 0;
LED2 = 0;
LED3 = 0; //11111110定义每次一个灯亮,芯片默认都有电平输出,先把所有脚电压置低,不然加电就灯半闪烁
while(1)
{
if(key1==0)
{
delayms(30); //这里判断按键时长,用于防抖
if(key1==0)
{
while(!key1); //这个必须加,不然按键时灯闪烁
status++;
switch(status)
{
case 1:
LED1 = 1 ;
LED2 = 0;
LED3 = 0;
break; // 跳出循环
case 2:
LED1 = 0 ;
LED2 = 1;
LED3 = 0;
break; // 跳出循环
case 3:
LED1 = 0 ;
LED2 = 0;
LED3 = 1;
status=0; //按键归零,从头计数
break; // 跳出循环
default:
break;
}
}
}
}
}
/***************************程序完成*****************************************/
第2个方法,直接操作二进制位,学习下二进制位的操作。
/***************************第二精操作方式,直接操作P3试试 主函数*****************************************/
void main()
{
//按3个灯的位置,0,1,4位 都不亮的话二进制位置应该这样 11101100 转换为十六进制为 0xEC
P3 = 0xEC ;
while(1)
{
if(key1==0)
{
delayms(30); //这里判断按键时长,用于防抖
if(key1==0)
{
while(!key1); //这个必须加,相当于判断按键是否松开,不然按键时灯闪烁
status++;
//不是顺着来的,还是搞1,2,3档位的判断吧
if(status==1){
P3 = P3|(1<< 0); //0位置1,亮
P3 = P3&~(1 << 4); //4为置1,取反则为0,和P3且也就P3的4位为0了
}else if(status==2){
P3 = P3|(1<< 1);
P3 = P3&~(1 << 0);
}else if(status==3){ //位置不是顺着来的,第3个灯就要搞到第5位了
P3 = P3|(1 << 4); //把二进制第4为设置为1
P3 = P3&~(1 << 1); //把二进制第1为设置为0,相当于这个是3档灯让一档熄灭
status = 0; //计数归0
}
}
}
}
}
/***************************程序完成*****************************************/
还有第3总操作方式,这个代码看起来就简单一些
void main()
{
//按3个灯的位置,0,1,4位 都不亮的话二进制位置应该这样 11101100 转换为十六进制为 0xEC
P3 = 0xEC ;
while(1){
if(key1==0){
delayms(30); //这里判断按键时长,用于防抖
if(key1==0)
{
while(!key1); //这个必须加,相当于判断按键是否松开,不然按键时灯闪烁
P3 = 0xEC ; //也可以这样操作,每次灯全熄灭后单独再点亮
if(status<=1){
P3 = P3|(1<< status);
status++;
}else{
P3 = P3|(1<< 4);
status = 0;
}
}
}
}
}