从头学玩单片机STC15F104W《二》点按长按控制灯
编辑时间:2022-05-24 作者:金满斗 浏览量:2674 来源:原创

其实这节内容没什么好说的。

技术点就是用到了定时器。

其实相比较于一的,一第一次搞这种环境要花写时间。

这里不仔细写了,很多代码也是抄的别人的,哈哈哈、

还是直接代码托管平台看最新的吧。

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;
		}
		
	}
}	
/***************************程序完成*****************************************/


来说两句吧