其实这节内容没什么好说的。
技术点就是用到了定时器。
其实相比较于一的,一第一次搞这种环境要花写时间。
这里不仔细写了,很多代码也是抄的别人的,哈哈哈、
还是直接代码托管平台看最新的吧。
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;
}
}
}
/***************************程序完成*****************************************/