学习要以解决实际问题出发。
这里模拟下风扇的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; } } } } }