天天看點

學習STM32程式設計——按鍵掃描鍵控流水燈

作者:華26104121

關鍵代碼

uint8_t Key_Scan(uint8_t mode)

{

static uint8_t key_up=1;

if(mode) key_up=1;

if(key_up && (KEY_L==0||KEY_D==0||KEY_R==0||KEY_U==1))

{

delay_ms(20);

key_up=0;

if(KEY_L==0) return KEY_L_PRESS;

else if(KEY_D==0) return KEY_D_PRESS;

else if(KEY_R==0) return KEY_R_PRESS;

else if(KEY_U==1) return KEY_U_PRESS;

}

else if(KEY_L==1&&KEY_D==1&&KEY_R==1&&KEY_U==0)

{

key_up=1;

}

return 0;

}

uint8_t keyValue=0;

LED_WorkModeTypeDef myLEDWorkMode=LED_MODE1;

int main(void)

{

delay_init(168);

LED_Init();

Key_Init();

while(1)

{

keyValue=Key_Scan(0);

switch(keyValue)

{

case KEY_L_PRESS:

myLEDWorkMode=LED_MODE1;

break;

case KEY_D_PRESS:

myLEDWorkMode=LED_MODE2;

break;

case KEY_R_PRESS:

myLEDWorkMode=LED_MODE3;

break;

default:

break;

}

if(myLEDWorkMode==LED_MODE1)

{

LED_Mode1(1000);

}

else if(myLEDWorkMode==LED_MODE2)

{

LED_Mode2();

}

else if(myLEDWorkMode==LED_MODE3)

{

LED_Mode3();

}

}

}

遇到坑,添加如下代碼解決

#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) //将位帶區位址轉換為位帶别名區位址

#define MEM_ADDR(addr) *((volatile unsigned long *)(addr)) //表示該十六進制數為位址,并允許直接對其内容進行操作進行操作(其中的volatile關鍵字常用于寄存器定義,表示從記憶體重新裝載内容,而不是從寄存器拷貝内容)

#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))

//IO口位址映射

#define GPIOA_ODR_Addr (GPIOA_BASE+20) //0x40020014

#define GPIOB_ODR_Addr (GPIOB_BASE+20) //0x40020414

#define GPIOC_ODR_Addr (GPIOC_BASE+20) //0x40020814

#define GPIOD_ODR_Addr (GPIOD_BASE+20) //0x40020C14

#define GPIOE_ODR_Addr (GPIOE_BASE+20) //0x40021014

#define GPIOF_ODR_Addr (GPIOF_BASE+20) //0x40021414

#define GPIOG_ODR_Addr (GPIOG_BASE+20) //0x40021814

#define GPIOH_ODR_Addr (GPIOH_BASE+20) //0x40021C14

#define GPIOI_ODR_Addr (GPIOI_BASE+20) //0x40022014

#define GPIOA_IDR_Addr (GPIOA_BASE+16) //0x40020010

#define GPIOB_IDR_Addr (GPIOB_BASE+16) //0x40020410

#define GPIOC_IDR_Addr (GPIOC_BASE+16) //0x40020810

#define GPIOD_IDR_Addr (GPIOD_BASE+16) //0x40020C10

#define GPIOE_IDR_Addr (GPIOE_BASE+16) //0x40021010

#define GPIOF_IDR_Addr (GPIOF_BASE+16) //0x40021410

#define GPIOG_IDR_Addr (GPIOG_BASE+16) //0x40021810

#define GPIOH_IDR_Addr (GPIOH_BASE+16) //0x40021C10

#define GPIOI_IDR_Addr (GPIOI_BASE+16) //0x40022010

//IO口操作,隻對單一的IO口!

//確定n的值小于16!

#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //輸出

#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //輸入

#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //輸出

#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //輸入

#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //輸出

#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //輸入

#define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //輸出

#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //輸入

#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //輸出

#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //輸入

#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //輸出

#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //輸入

#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //輸出

#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //輸入

#define PHout(n) BIT_ADDR(GPIOH_ODR_Addr,n) //輸出

#define PHin(n) BIT_ADDR(GPIOH_IDR_Addr,n) //輸入

#define PIout(n) BIT_ADDR(GPIOI_ODR_Addr,n) //輸出

#define PIin(n) BIT_ADDR(GPIOI_IDR_Addr,n) //輸入