江西农业大学,农机2101,版本为本人所有
以stm32为基础,设计了秒表计时器系统,采取两片74hc595进行级联输入,6位数码管显示操作。
程序设计思路:
①该系统需要具备正向计时系统,并且为了做到功能不单一,增添设置了倒计时模式。
②该系统同时具备在正向计时模式以及倒计时计时模式下都可以进入对时间随心所欲的调节模式。
③该系统模式之间应该要做到任意的切换,并且保证任务不错乱。
④对此我们设置了四个按钮,即start(开始计时),stop(停止计时),clear(清空计时),mode(模式切换),用这四个按钮对秒表计时系统进行整体操作。
具体讲解:以下为系统讲解:
①Foword Timing Mode1 :正向计时系统,从零开始计时,此时前三位按键单击时可控制,双击长击无效- - -Start(单击)clear(单 击),stop(单击)
②Backfoword Timing Mode3(单击mode进入):反向计时系统,如若此时单击start,则默认一小时倒计时-- Start(单击),clear(单击), stop(单击)
③ Adjutsting Timing and Return to initial Mode2(长击mode进入):调节时间系统及其返回安排,此模式下,显示器上时,分,秒皆为零,双击系统可以运行
④若此时为正向计时系统:双击star(s+=1) or stop(min+=1) or clear(hour+=1),对s,min,hour进行调节,双击mode,返回当前正向计时模式,系统按调定时间running。
⑤若此时为反向计时系统:双击start(s-=1) or stop(min-=1) or clear(hour-=1),对s,min,hour进行调节,双击mode,返回当前反向计时模式,系统按调定时间running。
Tim_key.c的设置
#include "Tim_Key.h"
#include "stm32f10x.h" // Device header
#include "status_machine_key.h" //调用单按键的TIM计时器功能,每2ms扫描按键一次;
//四个按键(开始(+),停止(-),清零,模式)引脚初始化函数。
tim_Multi_key tim_keystruct;//定义结构体的变量uint16_t tim_Multi_count;//按键时间总体计时位
uint16_t tim_Multi_dual_count;//双击计数位
uint16_t tim_Multi_short_stickflag;//短击标志位
uint16_t tim_Multi_long_stickflag;//长击标志位
uint16_t tim_Multi_dual_stickflag;//双击标志位
uint16_t tim_position;//区别按键按下的标志位void Timming_key_init(void)//四个按键的初始化
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef Start;
Start.GPIO_Mode=GPIO_Mode_IPU;//外部接地。故为上拉输入,此时引脚默认为高电平,按下为低电平
Start.GPIO_Pin=START;
Start.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIO__Start,&Start);
Start.GPIO_Mode=GPIO_Mode_IPU;//外部接地。故为上拉输入
Start.GPIO_Pin=STOP;
Start.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIO__Stop,&Start);
Start.GPIO_Mode=GPIO_Mode_IPU;//外部接地。故为上拉输入
Start.GPIO_Pin=CLEAR;
Start.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIO__Clear,&Start);
Start.GPIO_Mode=GPIO_Mode_IPU;//外部接地。故为上拉输入
Start.GPIO_Pin=MODE;
Start.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIO__Mode,&Start);
}void CLEAR_Count(void)//清零函数
{
tim_Multi_count=0;
tim_Multi_short_stickflag=0;
tim_Multi_dual_stickflag=0;
tim_Multi_long_stickflag=0;
tim_position=0;
}void tim_Multi_key_Scan(void)//start/stop/clear三个按键的单机双击长击短击
{if(!KEY_START&&KEY_STOP&&KEY_CLEAR&&KEY_MODE)//如果start按下且其余为高电平
{
tim_position=1;
if(tim_Multi_count<10000)//小于20s主要是为了预防长按导致的长时间停留,导致count被清零长按失去意义
{
tim_Multi_count++;
}
if(tim_Multi_count>Shaking_tim)//不管想要按下什么状态,短击标志位始终需要置为1;
{
tim_Multi_short_stickflag=1;
}
if(tim_Multi_dual_stickflag==0&&tim_Multi_dual_count>0)//双击位置为1,该行代码为第二次按下按键启动,第一次松开时tim_Multi_dual_count开始自增;
{
tim_Multi_dual_stickflag=1;
}
if(tim_Multi_count>Longtstick_tim)//长击位置为1;
{
tim_Multi_short_stickflag=0;tim_Multi_long_stickflag=1;
}
}
if(KEY_START&&!KEY_STOP&&KEY_CLEAR&&KEY_MODE)//如果stop按下且其余为高电平
{
tim_position=2;
if(tim_Multi_count<10000)//小于20s主要是为了预防长按导致的长时间停留,导致count被清零长按失去意义
{
tim_Multi_count++;
}
if(tim_Multi_count>Shaking_tim)//不管想要按下什么状态,短击标志位始终需要置为1;
{
tim_Multi_short_stickflag=1;
}
if(tim_Multi_dual_stickflag==0&&tim_Multi_dual_count>0)//双击位置为1,该行代码为第二次按下按键启动,第一次松开时tim_Multi_dual_count开始自增;
{
tim_Multi_dual_stickflag=1;
}
if(tim_Multi_count>Longtstick_tim)//长击位置为1;
{
tim_Multi_short_stickflag=0;tim_Multi_long_stickflag=1;
}
}
if(KEY_START&&KEY_STOP&&!KEY_CLEAR&&KEY_MODE)//如果clear按下且其余为高电平
{
tim_position=3;
if(tim_Multi_count<10000)//小于20s主要是为了预防长按导致的长时间停留,导致count被清零长按失去意义
{
tim_Multi_count++;
}
if(tim_Multi_count>Shaking_tim)//不管想要按下什么状态,短击标志位始终需要置为1;
{
tim_Multi_short_stickflag=1;
}
if(tim_Multi_dual_stickflag==0&&tim_Multi_dual_count>0)//双击位置为1,该行代码为第二次按下按键启动,第一次松开时tim_Multi_dual_count开始自增;
{
tim_Multi_dual_stickflag=1;
}
if(tim_Multi_count>Longtstick_tim)//长击位置为1;
{
tim_Multi_short_stickflag=0;tim_Multi_long_stickflag=1;
}
}
if(KEY_START&&KEY_STOP&&KEY_CLEAR&&!KEY_MODE)//如果mode按下且其余为高电平
{
tim_position=4;
if(tim_Multi_count<10000)//小于20s主要是为了预防长按导致的长时间停留,导致count被清零长按失去意义
{
tim_Multi_count++;
}
if(tim_Multi_count>Shaking_tim)//不管想要按下什么状态,短击标志位始终需要置为1;
{
tim_Multi_short_stickflag=1;
}
if(tim_Multi_dual_stickflag==0&&tim_Multi_dual_count>0)//双击位置为1,该行代码为第二次按下按键启动,第一次松开时tim_Multi_dual_count开始自增;
{
tim_Multi_dual_stickflag=1;
}
if(tim_Multi_count>Longtstick_tim)//长击位置为1;
{
tim_Multi_short_stickflag=0;tim_Multi_long_stickflag=1;
}
}
else
if(KEY_START&&KEY_STOP&&KEY_CLEAR&&KEY_MODE)//如果松开且全部为松手
{
if(tim_Multi_count<Shaking_tim)//松下时未达到消抖时间
{
tim_Multi_count=0;
tim_Multi_short_stickflag=0;
tim_Multi_dual_stickflag=0;
tim_Multi_long_stickflag=0;
tim_Multi_dual_count=0;
}
if(tim_Multi_short_stickflag==1)//也就是没有长击情况
{
if(tim_Multi_dual_count>0||tim_Multi_dual_count==0)//在前一次为短击的情况下,松开就自动计时
{
tim_Multi_dual_count++;
}
if(tim_Multi_dual_count<=Doublestick_tim&&tim_Multi_dual_stickflag==1)//双击按键成功,为两次
{
tim_Multi_dual_stickflag=2;tim_Multi_dual_count=0;//判为双击
}
if(tim_Multi_dual_stickflag==0&&tim_Multi_dual_count>Doublestick_tim)
{
tim_Multi_short_stickflag=2;//判为短击
}
//如果第一次按下松开后,双机计数位递增但是超过时间间隔范围内且没有再次按键按下,即本次事件为单击
}
if(tim_Multi_long_stickflag==1)
{
tim_Multi_long_stickflag=2;//判为长击
}
}
//*******以下是按键的判断************//
//短击为1,长击为2,双击为3
if(tim_Multi_count>Shaking_tim&&tim_Multi_count<10000)
{
//按键start
if(tim_Multi_short_stickflag==2&&tim_position==1)//start短击键位设计
{
tim_keystruct.tim_shortstick1=1;
tim_keystruct.tim_shortstick2=0;
tim_keystruct.tim_shortstick3=0;
tim_keystruct.tim_shortstick4=0;
tim_keystruct.tim_dualstick1=0;
tim_keystruct.tim_dualstick2=0;
tim_keystruct.tim_dualstick3=0;
tim_keystruct.tim_longstick4=0;
CLEAR_Count();}