久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4528|回復: 7
打印 上一主題 下一主題
收起左側

STM8(STM32)單片機如何實現按鍵鎖定程序

[復制鏈接]
跳轉到指定樓層
樓主
各位大佬好,在使用STM8的時候遇到一個問題,想用比較簡便的方法解決:
/*  目標:想使用一個撥碼開關來控制所有的按鍵鎖定:
                                               1.在任何時候,只要【撥碼開關】置“0”,按鍵輸入就無效;
                                               2.在任何時候,只有【撥碼開關】置“1”,按鍵輸入才有效。
(個人想法:能不能在 #define 一個名詞(Ka)的時候,讓它先判斷【撥碼開關 BM1 】的狀態,符合條件再對【按鍵 K1 】讀取。)
然后再使用這個名詞,在函數里完成【按鍵 K1 】的狀態讀取,按照這種思路,我目前的寫法,編譯時報錯。
請教各位大佬,有沒有比較簡便的方法來實現這種功能,不局限于STM8,STM32也可以。謝謝!*/

//以下基于STM8。使用的軟件是 IAR
#include <stm8s.h>
#include <stm8s_gpio.h>

//【按鍵】說明K1為:讀取PC1口 輸入數據(為0或者不為0)
#define K1 (GPIO_ReadInputData(GPIOC)&GPIO_PIN_1)

//【燈】燈L1亮_滅,PB3口高電平時控制三極管導通燈亮,低電平時三極管關斷燈滅
#define ON  1
#define OFF 0
#define L1(ON_OFF)  if(ON_OFF==ON)GPIO_WriteHigh(GPIOB, GPIO_PIN_3);\
                       else GPIO_WriteLow(GPIOB, GPIO_PIN_3)

//【撥碼開關】 說明BM1為:讀取PB6口 輸入數據(為0或者不為0)
#define BM1 (GPIO_ReadInputData(GPIOB)&GPIO_PIN_6)


//用【撥碼開關】作為按鍵鎖定:當BM1不為0(撥碼開關置“1”)時,讀取【按鍵 K1 】輸入。
#define Ka if(BM1!=0)GPIO_ReadInputData(GPIOC)&GPIO_PIN_1

//IO口初始化
void GPIO_Config()
  {

  /燈L1初始化:PB3低電平輸出
  GPIO_Init(GPIOB, GPIO_PIN_3, GPIO_MODE_OUT_PP_LOW_FAST);  

  //按鍵初始化:PC1無中斷無浮點上拉輸入
  GPIO_Init(GPIOC, GPIO_PIN_1, GPIO_MODE_IN_PU_NO_IT);

   //撥碼開關初始化:PB6無中斷無浮點上拉輸入
  GPIO_Init(GPIOB, GPIO_PIN_6, GPIO_MODE_IN_PU_NO_IT);
  }

//主函數
int main(void)
{  
  GPIO_Config();   //IO口初始化
  while(1)
  {
   if(K1==0)   //檢測【按鍵 K1 】狀態,按下時為“0”,松開時不為“0”
   {
     L1(OFF);   //【燈 L1】滅
   }

   if(Ka!=0)     
   {
     L1(ON);
   }
  }
}


//STM8解決u8/u32定義報錯問題
#ifdef USE_FULL_ASSERT

void assert_failed(u8* file, u32 line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

/*********************************************************************************************************/
報錯信息如下:


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:824490 發表于 2021-5-15 11:10 | 只看該作者
你的想法沒錯,在按鍵掃描函數的開始加入對這個開關的判斷,為0就跳過按鍵掃描
回復

使用道具 舉報

板凳
ID:919615 發表于 2021-5-15 15:22 | 只看該作者

你的想法沒錯,在按鍵掃描函數的開始加入對這個開關的判斷,為0就跳過按鍵掃描
回復

使用道具 舉報

地板
ID:728915 發表于 2021-5-15 15:50 | 只看該作者
名字不是重點 發表于 2021-5-15 11:10
你的想法沒錯,在按鍵掃描函數的開始加入對這個開關的判斷,為0就跳過按鍵掃描

是的,可以通過函數來先行判斷,但僅通過定義來先一步實現按鍵鎖定判斷好像行不通。
另外,是不是除了主函數里或者極個別情況下,盡量不要使用while、或者for之類的循環語句,會過分占用CPU資源,
比如我下面的按鍵函數:

//按鍵判斷,帶撥碼開關BM3按鍵鎖定
int Anjian(void)   //返回值: K1(設置鍵)短/長按:1/11; K2(+鍵)短/長按:2/22; K3(-鍵)短/長按:3/33
{  
  u16 i=0;
  if(BM3!=0)
  {
    while(1)
    {
      if(BM3==0)
      {
        break;
      }
      if(K1==0)   //K1(設置鍵)按下
      {
        while(1)
        {
          if(K1==0)
          {
            i++;
            delay_cms(1);    //方便 計算 按鍵K1(設置鍵)計數時長
            if(i>=60000)   
            {
              i=55555;      //防止達到 計數上限   
            }
          }
         
          if(K1!=0)
          {
            if(i<=179)
            {            
              return 1;     //判斷K1(設置鍵)為:短按(約3秒以內)
            }
            if(i>=180)
            {        
               return 11;   //判斷K1(設置鍵)為:長按(約4秒以后)                 
            }                 
          }
        }
      }
      
      if(K2==0)   //K2(+鍵)按下
      {
        while(1)
        {
          if(K2==0)
          {
            i++;
            delay_cms(1);    //方便 計算 按鍵K2(+鍵)計數時長
            if(i>=60000)   
            {
              i=55555;      //防止達到 計數上限   
            }
          }
         
          if(K2!=0)
          {
            if(i<=179)
            {            
              return 2;     //判斷K2(+鍵)為:短按(約3秒以內)
            }
            if(i>=180)
            {        
               return 22;   //判斷K2(+鍵)為:長按(約4秒以后)                  
            }                 
          }
        }
      }

      if(K3==0)   //K3(-鍵)按下
      {
        while(1)
        {
          if(K3==0)
          {
            i++;
            delay_cms(1);    //方便 計算 按鍵K3(-鍵)計數時長
            if(i>=60000)   
            {
              i=55555;      //防止達到 計數上限   
            }
          }
         
          if(K3!=0)
          {
            if(i<=179)
            {            
              return 3;     //判斷K3(-鍵)為:短按(約3秒以內)
            }
            if(i>=180)
            {        
               return 33;   //判斷K3(-鍵)為:長按(約4秒以后)                  
            }                 
          }
        }
      }   
    }     
  }  
}
回復

使用道具 舉報

5#
ID:824490 發表于 2021-5-16 15:27 | 只看該作者
本帖最后由 名字不是重點 于 2021-5-16 15:33 編輯
我,菜雞 發表于 2021-5-15 15:50
是的,可以通過函數來先行判斷,但僅通過定義來先一步實現按鍵鎖定判斷好像行不通。
另外,是不是除了主 ...

你這個函數有點繞。。。
一般常來說,超過3個并聯關系,最好是要用Switch。。。case來做分支。
uchar key_value;
key_value=key_scan();
switch (key_value)
{
case: 0x01
.
.
break;
case: 0x11
.
.
break;

case.
.
.
}
回復

使用道具 舉報

6#
ID:824490 發表于 2021-5-16 15:32 | 只看該作者
我,菜雞 發表于 2021-5-15 15:50
是的,可以通過函數來先行判斷,但僅通過定義來先一步實現按鍵鎖定判斷好像行不通。
另外,是不是除了主 ...

定義一個孌量 uchar Key_vaule;
把K1的狀態存為Key_vaule的bit0,按下為0,未按下為1,同理,K2存為bit1...
這樣一來再配合switch。case 很方便做組合鍵,也能做長短按。
回復

使用道具 舉報

7#
ID:824490 發表于 2021-5-16 15:35 | 只看該作者
          key=key_scan();
                        switch (key)
                        {
                                case 0:
                                        break;
                                case 1://ENT
                                        item++;
                                  if (item>3)
                                        {
                                                RTC_Set(tyear,tmonth,tdate,calendar.hour,calendar.min,calendar.sec);//寫入時間;
                                                OLED_Screen_Fill(0x00);
                                                ret=1;
                                        }       
                                        break;
                                case 2: //+
                                        switch (item)
                                        {
                                                case 1:
                                                        if (tyear==2029) tyear=1970;
                                                  else             tyear++;
                                                  break;
                                                case 2:
                                                        if(tmonth==12)   tmonth=1;
                                                  else                                     tmonth++;
                                                  break;
                                                case 3:
                                                        max_date=DFM[tmonth-1];
                                                  if((Is_Leap_Year(tyear)==1)&&(tmonth==2))  max_date=29;
                                                        if(tdate==max_date)    tdate=1;
                                                  else                                     tdate++;
                                                 break;
                                        }
                                        break;
                                case 3://-
                                        switch (item)
                                        {
                                                case 1:
                                                 if (tyear==1970)  tyear=2099;
                                                 else               tyear--;
                                                 break;
                                                case 2:
                                                 if(tmonth==1)    tmonth=12;
                                                 else             tmonth--;
                                                 break;
                                                case 3:
                                                 max_date=DFM[tmonth-1];
                                                 if((Is_Leap_Year(tyear)==1)&&(tmonth==2))  max_date=29;
                                                 if (tdate==1)   tdate=max_date;
                                                 else             tdate--;
                                                 break;
                                        }
                                        break;
                                default:
                                        break;
                        }               
回復

使用道具 舉報

8#
ID:728915 發表于 2021-5-16 20:55 | 只看該作者
名字不是重點 發表于 2021-5-16 15:27
你這個函數有點繞。。。
一般常來說,超過3個并聯關系,最好是要用Switch。。。case來做分支。
uchar k ...

噢噢,受教了,謝謝!
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久人人爽人人爽人人片av免费 | av网址在线| 亚洲不卡在线视频 | 欧美成人一区二区 | 亚洲精品在线免费观看视频 | 国产黄色大片 | 国产精品久久免费观看 | 一级片av | 国产精品一区在线观看 | 欧美精品一区三区 | 中文字幕一区二区三区不卡 | 亚洲成人在线免费 | 亚洲国产欧美在线 | www.国产| 欧美区日韩区 | 亚洲永久在线 | 久久伊人青青草 | 精品国产一区二区国模嫣然 | 亚洲精品一区二三区不卡 | 国产在线精品一区二区三区 | 一级做a爰片性色毛片16 | 久草网址 | 久久精品亚洲欧美日韩精品中文字幕 | 亚洲欧美精品国产一级在线 | 麻豆久久久9性大片 | 久久丝袜 | 亚洲狠狠爱 | 欧美久久一区 | 新疆少妇videos高潮 | 亚洲国产一区二区三区在线观看 | 国产精品99久久久久久久vr | 91夜色在线观看 | 91精品一区二区三区久久久久 | 国产精品一区二区三区四区 | 日韩视频在线免费观看 | 91久久国产综合久久 | 国产精品毛片久久久久久久 | 91伊人| 欧美韩一区二区三区 | 日韩国产欧美一区 | 91欧美精品成人综合在线观看 |