Section 13: Press and hold an independent button to trigger the acceleration at a constant speed

Publisher:创意火舞Latest update time:2016-03-14 Source: eefocus Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
Opening remarks:

The previous section talked about the continuous stepping trigger function of holding down an independent button. This section will teach you how to achieve accelerated uniform speed triggering of the button with slight modifications based on the previous section.

 

For details, please see the source code.

 

(1) Hardware platform: Based on Zhu Zhaoqi 51 single-chip computer learning board. Use the S1 and S5 keys in the matrix keyboard as independent keys. Remember to keep the output line P0.4 output low level to simulate the trigger ground GND of the independent keys.

 

(2) Function implementation: Two independent buttons S1 and S5, S1 is used as the plus button. S5 is used as the minus button. Each time the S1 button is pressed, the set parameter uiSetNumber will increase by 1. If the S1 button is held down for more than 1 second, the set parameter uiSetNumber will increase by 1 at increasingly faster time intervals. This is called the acceleration trigger function. Until the limit value is reached, it will increase by 1 at a fixed speed. This process is called uniform speed. S5 is used as a subtraction button. Each time it is triggered, uiSetNumber will decrease by 1. Its acceleration and uniform speed trigger functions are the same as those of the S1 button. When the set parameter uiSetNumber is less than 500, the LED light goes out; when it is greater than or equal to 500, the LED light comes on. It should be noted that:

Step 1: Each time you press the button, it triggers a single click. If the time from pressing to releasing the button does not exceed 1 second, it will not enter the continuous acceleration trigger mode.

Step 2: If you hold the button pressed for more than 1 second, the button will enter the continuous acceleration trigger mode. The button trigger rhythm keeps getting faster and faster, and the buzzer beep rhythm keeps getting faster and faster. Until they both reach a limit value, and then they are triggered at a uniform speed at this limit value interval. At the beginning of acceleration, the steps of button triggering and buzzer triggering are consistent. When either of them reaches the limit value, the rapid sound is inconsistent with the button triggering. The button is not triggered every time the buzzer sounds. In fact, at the end of acceleration, the button triggering speed is much faster than the buzzer triggering speed.

 

(3) The source code is explained as follows:

#include "REG52.H"

 

#define const_voice_short 40 //Duration of the buzzer short call

 

#define const_key_time1 20 //Key debounce delay time

#define const_key_time2 20 //Key debounce delay time

 

#define const_time_1s 444 //Number of timer interrupts required for 1 second

 

#define const_initial_set 160 //In continuous trigger mode, the interval trigger time when the button is just pressed

#define const_min_level 30 //In continuous trigger mode, after the key is accelerated, if it is found to be less than this value, it will directly change to the last interval trigger time

#define const_sub_dt 10 //The "acceleration" of the key, which is equivalent to the change in the key interval time each time

 

#define const_last_min_set 5 //In continuous trigger mode, the last interval trigger time after the key is accelerated

 

#define const_syn_min_level 45 //The minimum threshold for generating synchronous sound. This time must be slightly longer than the buzzer time.

 

 

void initial_myself();    

void initial_peripheral();

void delay_long(unsigned int uiDelaylong);

void T0_time(); //Timer interrupt function

void key_service(); //Key service application

void key_scan(); //The key scan function is placed in the timer interrupt

void led_run(); //LED light application

 

sbit key_sr1=P0^0; //Corresponding to the S1 key of Zhu Zhaoqi learning board

sbit key_sr2=P0^1; //Corresponding to the S5 key of Zhu Zhaoqi learning board

sbit key_gnd_dr=P0^4; //Simulate the ground GND of the independent key, so it must always output a low level

 

sbit beep_dr=P2^7; //Buzzer driver IO port

 

sbit led_dr=P3^5; //LED driver IO port

 

 

unsigned char ucKeySec=0; //The key number that is triggered

 

unsigned int uiKeyTimeCnt1=0; //Key debounce delay counter

unsigned int uiKeyCtntyCnt1=0; //Interval delay counter for continuous key triggering

unsigned char ucKeyLock1=0; // variable flag for self-locking after key triggering

 

unsigned int uiSynCtntyCnt1=0; //Counter for generating key synchronization sound

unsigned int uiCtntyTimeSet1=const_initial_set; //The time interval between each button trigger. This value keeps getting smaller, resulting in a faster speed.

unsigned int uiCtntySynSet1 = const_initial_set; //Time interval for synchronizing sound, this value keeps getting smaller, resulting in faster speed

unsigned char ucCtntyFlag1=0; //Whether it is in the continuous acceleration trigger mode flag

 

 

unsigned int uiKeyTimeCnt2=0; //Key debounce delay counter

unsigned int uiKeyCtntyCnt2=0; //Interval delay counter for continuous key triggering

unsigned char ucKeyLock2=0; //Variable flag for self-locking after key triggering

 

unsigned int uiSynCtntyCnt2=0; //Counter for generating key synchronization sound

unsigned int uiCtntyTimeSet2 = const_initial_set; //The time interval between each button trigger. This value keeps getting smaller, resulting in a faster speed.

unsigned int uiCtntySynSet2 = const_initial_set; //Time interval for synchronizing sound. This value keeps getting smaller, causing the speed to keep getting faster.

unsigned char ucCtntyFlag2=0; //Whether it is in the continuous acceleration trigger mode flag

 

unsigned int uiVoiceCnt=0; //Buzzer beeping duration counter

 

unsigned int uiSetNumber=0; //Set data

 

void main() 

  {

   initial_myself();  

   delay_long(100);   

   initial_peripheral(); 

   while(1)  

   { 

       key_service(); //Key service application

       led_run(); //LED lamp application

   }

 

}

 

void led_run() //LED light application

{

   if(uiSetNumber<500) //If the set parameter uiSetNumber is less than 500, the LED light will be off. Otherwise, it will be on.

   {

      led_dr=0; // off

   }

   else

   {

      led_dr=1; //light up

   }

}

 

 

void key_scan()//The key scan function is placed in the timer interrupt

{  

/* Note 1:

* Independent buttons to continuously speed up the scanning process:

* Step 1: Each time you press the button, it triggers a single click. If the time from pressing to releasing the button does not exceed 1 second, it will not enter the continuous acceleration trigger mode.

* Step 2: If you hold down the button for more than 1 second, the button will enter the continuous acceleration trigger mode. The button trigger rhythm will continue to accelerate, and the buzzer will sound faster and faster.

* also speeds up. Until they all reach a limit, and then trigger at a constant speed at this limit interval. At the beginning of acceleration, the key trigger and

* The steps of buzzer triggering are consistent. When any of them reaches the limit value, the rapid sound is inconsistent with the triggering of the button.

* Each time the buzzer sounds, the button is triggered. In fact, at the end of the acceleration, the button triggering speed is much faster than the buzzer triggering speed.

*/

  if(key_sr1==1)//IO is high level, indicating that the key is not pressed, then some flags should be cleared in time

  {

     ucKeyLock1=0; //key self-locking flag cleared

     uiKeyTimeCnt1=0; //The key de-bounce delay counter is cleared. This line is very clever and I figured it out in actual combat.    

     uiKeyCtntyCnt1=0; //The time delay counter of the continuous acceleration of the key is cleared

         uiSynCtntyCnt1=0; //The time delay counter of the buzzer's continuous acceleration is cleared

     uiCtntyTimeSet1=const_initial_set; //The initial time interval between each button trigger. This value keeps getting smaller, resulting in a faster speed.

     uiCtntySynSet1=const_initial_set; //The initial value of the time interval for the synchronized sound. This value keeps getting smaller, causing the chirping rhythm to keep getting faster.

 

  }

  else if(ucKeyLock1==0)//A key is pressed, and it is the first time it is pressed

  {

     uiKeyTimeCnt1++; //Accumulate the number of timer interrupts

     if(uiKeyTimeCnt1>const_key_time1)

     {

        uiKeyTimeCnt1=0; 

        ucKeyLock1=1; //Set the self-locking key to avoid continuous triggering

                ucCtntyFlag1=0; //Continuous acceleration trigger mode flag 0 represents single click 1 represents continuous acceleration trigger

        ucKeySec=1; //Trigger key 1

     }

  }

  else if(uiKeyTimeCnt1

  {

     uiKeyTimeCnt1++;

  }

  else //If you hold the button for 1 second, the rhythmic acceleration will start.

  {

         uiKeyCtntyCnt1++; //Key continuously triggers the delay counter to accumulate

 

//Press and hold, the button will be triggered once every uiCtntyTimeSet1 time, and the speed will get faster and faster as uiCtntyTimeSet1 keeps decreasing

         if(uiKeyCtntyCnt1>uiCtntyTimeSet1) 

         {

                     if(uiCtntyTimeSet1>const_min_level)

                         {

                            uiCtntyTimeSet1=uiCtntyTimeSet1-const_sub_dt; //uiCtntyTimeSet1 keeps decreasing, the speed is getting faster and faster

                         }

                         else

                         {

                             uiCtntyTimeSet1=const_last_min_set; //uiCtntyTimeSet1 keeps decreasing and reaches a limit value

                         }

             uiKeyCtntyCnt1=0; 

                         ucCtntyFlag1=1; //Enter continuous acceleration trigger mode

             ucKeySec=1; //Trigger key 1

         }

 

 

                 uiSynCtntyCnt1++; //Buzzer continuously triggers delay counter accumulation

 

//If you hold down the button and don't release it, the buzzer will be triggered once every uiCtntySynSet1 time. As uiCtntySynSet1 decreases, the buzzing rhythm will become faster and faster.

                 if(uiSynCtntyCnt1>uiCtntySynSet1)

                 {

                uiCtntySynSet1=uiCtntySynSet1-const_sub_dt; //uiCtntySynSet1 keeps decreasing, and the chirping rhythm becomes faster and faster

                        if(uiCtntySynSet1

                        {

                             uiCtntySynSet1=const_syn_min_level; //uiCtntySynSet1 keeps decreasing and reaches a limit value

                        }

 

                        uiVoiceCnt=const_voice_short; //Key press triggers the sound, stops after one beep.

                        uiSynCtntyCnt1=0;

                 

                 }

 

 

   

  }

 

 

  if(key_sr2==1)

  {

     ucKeyLock2=0; 

     uiKeyTimeCnt2=0;

     uiKeyCtntyCnt2=0; 

         uiSynCtntyCnt2=0;

     uiCtntyTimeSet2=const_initial_set;

     uiCtntySynSet2=const_initial_set;

 

  }

  else if(ucKeyLock2==0)

  {

     uiKeyTimeCnt2++; 

     if(uiKeyTimeCnt2>const_key_time2)

     {

        uiKeyTimeCnt2=0; 

        ucKeyLock2=1;  

                ucCtntyFlag2=0;

        ucKeySec=2;  

     }

  }

  else if(uiKeyTimeCnt2

  {

     uiKeyTimeCnt2++;

  }

  else  

  {

         uiKeyCtntyCnt2++; 

         if(uiKeyCtntyCnt2>uiCtntyTimeSet2) 

         {

                     if(uiCtntyTimeSet2>const_min_level)

                         {

                            uiCtntyTimeSet2=uiCtntyTimeSet2-const_sub_dt;

                         }

                         else

                         {

                             uiCtntyTimeSet2=const_last_min_set;

                         }

             uiKeyCtntyCnt2=0; 

                         ucCtntyFlag2=1;

             ucKeySec=2;   

         }

 

                 uiSynCtntyCnt2++;

                 if(uiSynCtntyCnt2>uiCtntySynSet2)

                 {

                uiCtntySynSet2=uiCtntySynSet2-const_sub_dt;

                        if(uiCtntySynSet2

                        {

                             uiCtntySynSet2=const_syn_min_level;

                        }

 

                        uiVoiceCnt=const_voice_short; 

                        uiSynCtntyCnt2=0;

                 

                 }

 

 

   

  }

}

 

 

void key_service() //Application for the third zone key service

{

  switch(ucKeySec) //Key service status switch

  {

    case 1:// Continuous key addition of key 1 corresponds to the S1 key of Zhu Zhaoqi learning board  

              uiSetNumber++; //The set parameters are continuously increased

              if(uiSetNumber>1000) //The maximum is 1000

              {

                   uiSetNumber=1000;

              }

 

                          if(ucCtntyFlag1==0) //If the button is clicked, the buzzer will sound, otherwise the buzzer will sound in the key scan key_scan

                          {

                  uiVoiceCnt=const_voice_short; //Key press triggers the sound, stops after one beep.

                          }

              ucKeySec=0; //After responding to the key service handler, the key number is cleared to avoid consistent triggering

          break;        

    case 2:// The 2nd key is used for continuous reduction, corresponding to the S5 key of the Zhu Zhaoqi learning board

/* Note 2:

* In the C language compiler of the microcontroller, when the unsigned data 0 is subtracted from 1, it will overflow and become the maximum value of this type of data.

* For example, 0 minus 1 of unsigned int equals 65535 (0xffff), and 0 minus 1 of unsigned char equals 255 (0xff)

*/

              uiSetNumber--; //The set parameter is continuously reduced

              if(uiSetNumber>1000) //The minimum is 0. Why is 1000 used here? Because 0 minus 1 overflows and becomes 65535 (0xffff)

              {

                  uiSetNumber=0;

              }

                          if(ucCtntyFlag2==0) //If the button is clicked, the buzzer will sound, otherwise the buzzer will sound in the key scan key_scan

                          {

                  uiVoiceCnt=const_voice_short; //Key press triggers the sound, stops after one beep.

                          }

              ucKeySec=0; //After responding to the key service handler, the key number is cleared to avoid consistent triggering

          break;                    

  }                

}

 

 

 

void T0_time() interrupt 1

{

  TF0=0; //Clear interrupt flag

  TR0=0; //Disable interrupt

 

  key_scan(); //Key scanning function

 

  if(uiVoiceCnt!=0)

  {

     uiVoiceCnt--; //Every time the timer interrupt is entered, it will be decremented by 1 until it is equal to zero. Then the beeping will stop.

         beep_dr=0; //The buzzer is controlled by a PNP transistor and starts beeping when the voltage level is low.

  }

  else

  {

     ; //Add an extra empty instruction here to maintain symmetry with the number of if bracket statements, both are two instructions. It is also OK not to add it.

           beep_dr=1; //The buzzer is controlled by a PNP transistor, and it stops beeping when the level is high.

  }

 

 

  TH0=0xf8; //Reinstall initial value (65535-2000)=63535=0xf82f

  TL0=0x2f;

  TR0=1; //Open interrupt

}

 

 

void delay_long(unsigned int uiDelayLong)

{

   unsigned int i;

   unsigned int j;

   for(i=0;i

   {

      for(j=0;j<500;j++) //Number of empty instructions in the embedded loop

          {

             ; //A semicolon is equivalent to executing an empty statement

          }

   }

}

 

 

void initial_myself() //Initialize the MCU in the first zone

{

/* Comment 3:

* The matrix keyboard can also be used as an independent key, provided that one of the common output lines outputs a low level.

* Simulate the triggering ground of an independent key. In this program, key_gnd_dr is outputted at a low level.

* The S1 and S5 buttons of Zhu Zhaoqi 51 learning board are the two independent buttons used in this program.

*/

  key_gnd_dr=0; //Simulate the ground GND of the independent key, so it must always output a low level

 

 

  beep_dr=1; //Use PNP transistor to control the buzzer, it will not sound when the output is high level.

  led_dr=0; //LED light off

 

  TMOD=0x01; //Set timer 0 to working mode 1

 

 

  TH0=0xf8; //Reinstall initial value (65535-2000)=63535=0xf82f

  TL0=0x2f;

 

}

void initial_peripheral() // Initialize the periphery of the second zone

{

  EA=1; //Open the general interrupt

  ET0=1; //Enable timer interrupt

  TR0=1; //Start timing interrupt

 

}

Closing remarks:

    So far, we have spent 8 sections to explain the scanning procedure of independent keys. If it is a matrix keyboard, how should we write the program? For details, please listen to the next analysis - the single trigger of the matrix keyboard.

Reference address:Section 13: Press and hold an independent button to trigger the acceleration at a constant speed

Previous article:Section 12: Continuous stepping triggering by holding down a single button
Next article:Section 15: Compressed code programming for single trigger of matrix keyboard

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号