本人初學stm32,作為一個大一新生,由于學校未開設C語言課程,因此對于編程知識一知半解,所以我一般通過根據復刻實驗例程這種方式來培養自己撰寫程式的熟練度,但是就是在我試著復刻stm32單片機的獨立按鍵程式的時侯我遇到了困難。
在我用我對程式和C語言的理解對試驗例程復刻了之后,我發現我撰寫出來的程式并不能達到標注例程所能達到的效果,不僅如此,還出現了不知原因的故障,希望各位好心的編程大佬幫我看看我的程式哪里出錯了。
由于之前已經復刻過蜂鳴器和跑馬燈的程式,所以在獨立按鍵工程里面我將試驗例程里的led.h/c和beep.h/c檔案拿來直接運用到我自己撰寫的工程里面,所以問題應該出在我自己撰寫的key.c/h里面。
下面是標準例程里面的程式:
key.h:
#ifndef __KEY_H
#define __KEY_H
#include "sys.h"
//////////////////////////////////////////////////////////////////////////////////
//本程式只供學習使用,未經作者許可,不得用于其它任何用途
//ALIENTEK STM32F407開發板
//按鍵輸入驅動代碼
//正點原子@ALIENTEK
//技術論壇:www.openedv.com
//創建日期:2014/5/3
//版本:V1.0
//著作權所有,盜版必究。
//Copyright(C) 廣州市星翼電子科技有限公司 2014-2024
//All rights reserved
//////////////////////////////////////////////////////////////////////////////////
#define KEY0 PEin(4) //PE4
#define KEY1 PEin(3) //PE3
#define KEY2 PEin(2) //P32
#define WK_UP PAin(0) //PA0
#define KEY0_PRES 1 //KEY0按下
#define KEY1_PRES 2 //KEY1按下
#define KEY2_PRES 3 //KEY2按下
#define WKUP_PRES 4 //KEY_UP按下(即WK_UP)
void KEY_Init(void); //IO初始化
u8 KEY_Scan(u8); //按鍵掃描函式
#endif
key.c:
#include "key.h"
#include "delay.h"
//////////////////////////////////////////////////////////////////////////////////
//本程式只供學習使用,未經作者許可,不得用于其它任何用途
//ALIENTEK STM32F407開發板
//按鍵輸入驅動代碼
//正點原子@ALIENTEK
//技術論壇:www.openedv.com
//創建日期:2014/5/3
//版本:V1.0
//著作權所有,盜版必究。
//Copyright(C) 廣州市星翼電子科技有限公司 2014-2024
//All rights reserved
//////////////////////////////////////////////////////////////////////////////////
//按鍵初始化函式
void KEY_Init(void)
{
RCC->AHB1ENR|=1<<0; //使能PORTA時鐘
RCC->AHB1ENR|=1<<4; //使能PORTE時鐘
GPIO_Set(GPIOE,PIN2|PIN3|PIN4,GPIO_MODE_IN,0,0,GPIO_PUPD_PU); //PE2~4設定上拉輸入
GPIO_Set(GPIOA,PIN0,GPIO_MODE_IN,0,0,GPIO_PUPD_PD); //PA0設定為下拉輸入
}
//按鍵處理函式
//回傳按鍵值
//mode:0,不支持連續按;1,支持連續按;
//0,沒有任何按鍵按下
//1,KEY0按下
//2,KEY1按下
//3,KEY2按下
//4,KEY_UP按下 即WK_UP
//注意此函式有回應優先級,KEY0>KEY1>KEY2>KEY_UP!!
u8 KEY_Scan(u8 mode)
{
static u8 key_up=1;//按鍵按松開標志
if(mode)key_up=1; //支持連按
if(key_up&&(KEY0==0||KEY1==0||KEY2==0||WK_UP==1))
{
delay_ms(10);//去抖動
key_up=0;
if(KEY0==0)return 1;
else if(KEY1==0)return 2;
else if(KEY2==0)return 3;
else if(WK_UP==1)return 4;
}else if(KEY0==1&&KEY1==1&&KEY2==1&&WK_UP==0)key_up=1;
return 0;// 無按鍵按下
}
主程式:#include "sys.h"
#include "delay.h"
#include "led.h"
#include "beep.h"
#include "key.h"
//ALIENTEK 探索者STM32F407開發板 實驗3
//按鍵輸入實驗
//技術支持:www.openedv.com
//廣州市星翼電子科技有限公司
int main(void)
{
u8 key;
Stm32_Clock_Init(336,8,2,7);//設定時鐘,168Mhz
delay_init(168); //延時初始化
LED_Init(); //初始化與LED連接的硬體介面
BEEP_Init(); //初始化蜂鳴器IO
KEY_Init(); //初始化與按鍵連接的硬體介面
LED0=0; //先點亮紅燈
while(1)
{
key=KEY_Scan(1); //得到鍵值
if(key)
{
switch(key)
{
case WKUP_PRES: //控制蜂鳴器
BEEP=!BEEP;
break;
case KEY2_PRES: //控制LED0翻轉
LED0=!LED0;
break;
case KEY1_PRES: //控制LED1翻轉
LED1=!LED1;
break;
case KEY0_PRES: //同時控制LED0,LED1翻轉
LED0=!LED0;
LED1=!LED1;
break;
}
}else delay_ms(10);
}
}
然后這些就是我自己撰寫的出問題的工程程式了:
key.h:
#ifndef __KEY_H
#define __KEY_H
#include<sys.h>
#define KEY0 PEin(4)
#define KEY1 PEin(3)
#define KEY2 PEin(2)
#define WK_UP PEin(4)
#define KEY0PRES 1
#define KEY1PRES 2
#define KEY2PRES 3
#define WK_UPPRES 4
void KEY_Init(void);
u8 KEY_Scan(u8);
#endif
key.c
:
#include<key.h>
#include<delay.h>
void KEY_Init(void)
{
RCC->AHB1ENR=1<<0;
RCC->AHB1ENR=1<<4;
GPIO_Set(GPIOE,PIN2|PIN3|PIN4,GPIO_MODE_IN,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU);
GPIO_Set(GPIOA,PIN0,GPIO_MODE_IN,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PD);
}
u8 KEY_Scan(u8 mode)
{
static u8 key_up=1;
if(mode)
{
key_up=1;
}
if(key_up&&(KEY0==0||KEY1==0||KEY2==0||WK_UP==1))
{
delay_ms(50);
key_up=0;
if(KEY0==0)
{
return 1;
}
if(KEY1==0)
{
return 2;
}
if(KEY2==0)
{
return 3;
}
if(WK_UP==1)
{
return 4;
}
}
else if(KEY0==1&&KEY1==1&&KEY2==1&&WK_UP==0)
{
key_up=1;
}
return 0;
}
主程式:
#include<sys.h>
#include<beep.h>
#include<led.h>
#include<key.h>
#include<delay.h>
int main(void)
{
u8 key;
delay_init(168);
LED_Init();
BEEP_Init();
KEY_Init();
LED0=0;
while(1)
{
key=KEY_Scan(0);
if(key)
{
switch(key)
{
case WK_UPPRES:BEEP=!BEEP;break;
case KEY2PRES:LED0=!LED0;break;
case KEY1PRES:LED1=!LED1;break;
case KEY0PRES:LED0=!LED0;LED1=!LED1;break;
}
}
else
{
delay_ms(50);
}
}
}
這套程式不知道什么原因,打開電源之后無論是支持連按還是不支持連按沒有一個燈亮起來,按下按鍵也沒有反應,無論是燈還是蜂鳴器都沒有變化。在這里我注意到一個小細節,就是在電源鍵打開和復位鍵一松手的一瞬間燈閃了一下,我屬實很感到莫名其妙不知道為什么啊,希望各位大佬給我解答解答。
在撰寫這個工程之前我按照自己的印象自己撰寫出來了一個有反應,但是反應并不是我想要的,程式如下;
key.h:
#ifndef __KEY_H
#define __KEY_H
#include<sys.h>
#define KEY0 PEin(4)
#define KEY1 PEin(3)
#define KEY2 PEin(2)
#define WK_UP PAin(0)
void KEY_Init(void); //
u8 KEY_Scan(u8); //
#endif
key.c:
#include<key.h>
#include<delay.h>
void KEY_Init(void) //
{
RCC->AHB1ENR|=1<<0; //
RCC->AHB1ENR|=1<<4;
GPIO_Set(GPIOE,PIN2|PIN3|PIN4,GPIO_MODE_IN,GPIO_SPEED_100M,GPIO_OTYPE_PP,GPIO_PUPD_PU);//
GPIO_Set(GPIOA,PIN0,GPIO_MODE_IN,GPIO_SPEED_100M,GPIO_OTYPE_PP,GPIO_PUPD_PU);//
}
//
//mode
//
u8 KEY_Scan(u8 mode)
{
static u8 key=1; //
if(mode) //
{
key=1;
}
if(key&&(KEY0==0||KEY1==0||KEY2==0||WK_UP==1))
{
delay_ms(10);
key=0;
if(KEY0==0) return 1;
else if(KEY1==0) return 2;
else if(KEY2==0) return 3;
else if(WK_UP==1) return 4;
}
else if(KEY0==1&&KEY1==1&&KEY2==1&&WK_UP==0)
{
key=1;
}
return 0;
}
主程式:
#include<sys.h>
#include<led.h>
#include<beep.h>
#include<delay.h>
#include<key.h>
int main(void)
{
u8 u;
delay_init(168);//
LED_Init();//
KEY_Init();//
BEEP_Init();//
LED1=0;
while(1)
{
u=KEY_Scan(0);
if(u)
{
switch(u)
{
case 4:BEEP=!BEEP;break;
case 3:LED1=!LED1;break;
case 2:LED0=!LED0;break;
case 1:LED0=!LED0;LED1=!LED1;break;
}
}
else delay_ms(50);
}
}
這個更加離譜,在連按的條件下,我不動,蜂鳴器會響一下停一下重復回圈,按鍵能正常使用。但是在非連按的情況下,蜂鳴器會一直響。按什么按鍵都不會有反應,懵了二連。
各位大佬有看出我的程式問題出在哪里的嘛,有的話幫忙指出錯誤好嗎,在下謝謝各位了。
新人第一次發帖有點不好看請多多包含
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/271726.html
標籤:單片機/工控
上一篇:自己弄了一個計算機簡單的程式,初學,動態數碼管只有最后一位顯示,能有大佬告訴我出了什么問題嗎
下一篇:ARM和X86能否嵌套?
