1. 程式人生 > >STM32學習---GPIO和按鍵(流水燈學習)

STM32學習---GPIO和按鍵(流水燈學習)

//main的完整過程:
int main(void){
	 
	LED_GPIO_CONFIG();	//定義LED燈;
	
	
	KEY_GPIO_CONFIG();	//定義按鍵;
	 
	 //迴圈判斷按鍵的過程:
	 while(1){
			if((KEY_SCANF(GPIOC,GPIO_Pin_5)==0)){				//確定按鍵完全按下
				if(GPIO_ReadOutputDataBit(GPIOD,GPIO_Pin_2)==0)	//當燈都亮起時,GPIO_ReadOutputDataBit(GPIOD,GPIO_Pin_2)讀到輸出資料;
				      GPIO_SetBits(GPIOD,GPIO_Pin_2);			//置位,燈滅;
				else
					GPIO_ResetBits(GPIOD,GPIO_Pin_2);			//復位,燈亮
			}
	}
}
 
//關於KEY的操作;
 //實現操作:(初始時燈亮)按一下按鍵後燈滅,再按一下燈亮;
 
 先按之前的程式碼點亮一個LED燈;
 GPIO_InitTypeDef GPIO_D;
	 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);

	 GPIO_D.GPIO_Pin=GPIO_Pin_2;
	 GPIO_D.GPIO_Mode=GPIO_Mode_Out_PP;
	 GPIO_D.GPIO_Speed=3;
	 GPIO_Init(GPIOD,&GPIO_D);

//然後定義按鍵;
void KEY_GPIO_CONFIG(void)
{
	GPIO_InitTypeDef GPIO_C;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
	
    GPIO_C.GPIO_Pin=GPIO_Pin_5;
	GPIO_C.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_C.GPIO_Speed=1;
	GPIO_Init(GPIOC,&GPIO_C);
}
//定義按鍵和定義LED燈的過程差不多,主要區別在於Mode的配置上;
/*
4種輸入模式 :
GPIO_Mode_IPD(下拉輸入模式):在預設情況下(GPIO引腳無輸入的情況下),讀取得GPIO的引腳資料為1;
GPIO_Mode_IPU(上拉輸入模式):在預設情況下(GPIO引腳無輸入的情況下),讀取得GPIO的引腳資料為0;
GPIO_Mode_IN_FLOATING(浮空輸入模式):在晶片內部既沒有上拉也沒有下拉,經由觸發器輸入。由於其阻抗較大,所以一般把這種模式用於標準的通訊協議如I2C,USART的接收端。
GPIO_Mode_AIN(模擬輸入模式):關閉施密特觸發器,不接入上、下拉電阻,經由另一線路把電壓訊號傳送到片上外設模組。如傳送到ADC模組,由ADC模組採集電壓訊號。所以使用ADC外設的時候,必須設定為模擬輸入模式。

4種輸出模式:
GPIO_Mode_Out_PP(普通推輓輸出):一般用於輸出電平為0和3.3V的場合。
GPIO_Mode_Out_OD(普通開漏輸出):一般應用在電平不匹配的場合,如需要輸出5V的高電平,就需要在外部接一個上拉電阻,電源為5V,把GPIO設定為開漏模式,當輸出高阻態時,由上拉電阻和電源向外輸出5V的電平。
GPIO_Mode_AF_PP(複用推輓輸出):
GPIO_Mode_AF_OD(複用開漏輸出):
*/
//根據原理圖:當KEY沒有按下時為高電平,按下時為低電平,根據上述模式的介紹,可以選擇上拉輸入模式(GPIO_Mode_IPU)

//定義一個掃描KEY輸入的函式:
u8 KEY_SCANF(GPIO_TypeDef* a,u16 PIN)
{
	if(GPIO_ReadInputDataBit(a,PIN)==0){
		Delay(10000);	//按鍵消抖
		if(GPIO_ReadInputDataBit(a,PIN)==0){
			while(GPIO_ReadInputDataBit(a,PIN)==0);//
						return 0;
		}
		else{
			return 1;
		}
	}
	else
		return 1;
}
//逐句分析:
if(GPIO_ReadInputDataBit(a,PIN)==0):
//新的庫函式:GPIO_ReadInputDataBit(a,PIN),讀取輸入的資料,可用輸入電平高低判斷。
//根據呼叫函式:KEY_SCANF(GPIOC,GPIO_Pin_5) 可知,判斷的是KEY是否有輸入;
//當沒有按下KEY時,應輸入模式確定為上拉輸入模式,所以預設為高電平。然後,若有按下KEY,則輸入變為低電平。
//第二個
if(GPIO_ReadInputDataBit(a,PIN)==0) //是確認確實有按鍵按下,而不是按下一半返回。
while(GPIO_ReadInputDataBit(a,PIN)==0);//不停的檢測按鍵的電平,直至按鍵被釋放,被釋放後,按鍵的電平又恢復到預設的高電平。
//實際上這一整個過程都是按鍵掃描、消抖。