其实这节内容没什么好说的。
技术点就是用到了定时器。
其实相比较于一的,一第一次搞这种环境要花写时间。
这里不仔细写了,很多代码也是抄的别人的,哈哈哈、
还是直接代码托管平台看最新的吧。
https://gitee.com/jvbaopen/stc_demo
考虑到有些人懒得去看,这里也贴下代码吧,不过不一定是最终代码。
/******************************************************************** 日 期:2022/05/23 功 能: 简单按键识别,在第一个的基础上加个按键时长判断,点按按键直接呼吸灯,长按按键灯开关 芯片型号STC15F104W 编 写:劲松电脑通讯 *********************************************************************/ #include <stc15.h> //引入库文件,这个直接下载器里复制保存为stc15.h #define CPU_Fosc 12000000uL //定义主时钟 #define uchar unsigned char //宏定义无符号字符型 #define uint unsigned int //宏定义无符号整型 /******************************************************************** I/O定义 *********************************************************************/ sbit LED1=P3^3; //定义单片机P3口的第3位 (即P3.3)//为输出 这是8脚,配合开发板图玩玩,接的灯电路 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 TimeStart() // 描述: 定时器初始化函数 这个调用了,按5豪秒循环 // 参数: 无. // 返回: none. //======================================================================== void TimeStart() // 定时器初始化 { EA = 1; // 打开总中断 ET0 = 1; // 打开定时器 0 中断 TR0 = 1; // 打开定时器 0 TMOD = 0X01; // 设置定时器 0 为工作模式 1 16 位定时器模式,工作模式工作在1 TH0 = 0XED; TL0 = 0XFF; // 定时 5 毫秒 } //======================================================================== // 函数: void KEYS1() // 描述: 按键扫码函数,定时器启动后每隔5毫秒扫描 // 参数: 无. // 返回: none. //======================================================================== void KEYS1() // 按键 1 扫描函数 { static uchar num = 0; // 局部静态变量 static uint key_time_s1 = 0; //局部计时 switch(num) { case 0x00: if(key1 == 0) // 判断按键已按下 { num = 0x01; // 跳转到第二条语句 消抖 } break; // 跳出循环 case 0x01: if(key1 == 0) // 再次判断按键是否被按下 { key_time_s1 = 0; // 开始计数 num = 0x02; // 跳转到第三条语句 判断单击或者长按 }else { num = 0x00; // // 否则判断为毛刺,跳转到第一条语句 等待下次触发 } break; // 跳出循环 case 0x02: if(key1 == 1) // 判断是否松手 { LED1=~LED1; // 灯反转一下,达到呼吸灯效果 status = 1 ; //标志位,呼吸灯 num = 0x00; // 跳转到第一条语句 判断为单击按键 } else if(++key_time_s1 >= 50) // 如果计时的时间超过 250 毫秒则判断为长按 { LED1=~LED1; // 执行 LED3 状态反转一次 status = 0; num = 0x03; // 跳转到第 4 条语句 松手检测 } break; // 跳出循环 case 0x03: if(key1 == 1) // 如果按键松开 { num = 0x00; // 跳转到第一条语句 等待下次按键被按下 } break; // 跳出循环 default: break; } } //======================================================================== // 函数: void Timer0() // 描述: 定时器中断,后面表示的是中断位 interrupt后面0 1 2 3 4分别对应外部中断0,定时器/计数器0中断,外部中断1,定时器/计数器1中断,串口中断 // 参数: 无. // 返回: none. //======================================================================== void Timer0()interrupt 1 { static uchar i; // 时间标志位 用来计算定时时间 TH0 = 0XED; TL0 = 0XFF; // 定时 5 毫秒时间到后重新给寄存器赋初始值 i++; // 时间标志位加 1 加 1 表示 5 毫秒 1 次 两次表示十毫秒到 if(i == 2) // 判断 10 毫秒是否到了 { i = 0; //10 毫秒时间到,时间标志位清零 KEYS1(); // 扫描按键 1 } } /***************************主函数*****************************************/ void main() { LED1 = 0x00; //芯片默认都有电平输出,先把这个脚电压置低,不然加电就灯半闪烁 TimeStart(); //定时器初始化。定时器跑起来 while(1) { if(status==1){ //如果是点按,就让他闪烁呼吸灯 delayms(200); LED1=~LED1; } } } /***************************程序完成*****************************************/