一、实验目的和实验要求
实验要求:短按实验板扩展板上的按键SW18,依次点亮核心板上D2-D4指示灯。长按按键2秒,实现四个灯循环点亮(跑马灯)。
二、实验原理
如上图所示,四个 LED 正极通过电阻连接到电源+3.3V,LED 负端连接到 CPU 的 PEx
引脚。由此可知,只需要通过 CPU 控制 PEx 引脚为低电平,对应的指示灯即可点亮,如果
控制 PEx 引脚为高电平,这对应的 LED 熄灭。通过程序循环扫描,即可实现跑马灯控制。
三、实验结果
#include "stm32f10x.h"#define RCC_APB2ENR (*((volatile unsigned int*)0x40021018))
#define GPIOE_CRH (*((volatile unsigned int*)0x40011804))
#define GPIOE_BSRR (*((volatile unsigned int*)0x40011810))
#define GPIOE_IDR (*((volatile unsigned int*)0x40011808)) // ¶Ë¿ÚÊäÈëÊý¾Ý¼Ä´æÆ÷
#define GPIOE_ODR (*((volatile unsigned int*)0x4001180C)) #define GPIOB_CRL (*((volatile unsigned int*)0x40010C00))
#define GPIOB_IDR (*((volatile unsigned int*)0x40010C08)) void LED_Init(void)
{RCC_APB2ENR |= 1<<6; GPIOE_CRH &=0XFFFF0000; GPIOE_CRH |=0x3333; GPIOE_BSRR |= 1<<8; GPIOE_BSRR |= 1<<9; GPIOE_BSRR |= 1<<10; GPIOE_BSRR |= 1<<11;
}void Delay(unsigned int nCount)
{ while(nCount > 0){ nCount --; }
}
int count=0;
void LED_Turn(void)
{//通过count判断现在四个灯的状态,并完成切换if(count==1){GPIOE_BSRR |= 1<<8; GPIOE_BSRR |= 1<<25; count++;Delay(0xfffff);Delay(0xfffff);}else if(count==2){GPIOE_BSRR |= 1<<9;GPIOE_BSRR |= 1<<26;count++;Delay(0xfffff);Delay(0xfffff);}else if(count==3){GPIOE_BSRR |= 1<<10; GPIOE_BSRR |= 1<<27;count++;Delay(0xfffff);Delay(0xfffff);}else if(count==4){GPIOE_BSRR |= 1<<11; GPIOE_BSRR |= 1<<24; count=1;Delay(0xfffff);Delay(0xfffff);}else{GPIOE_BSRR |= 1<<24;count++;Delay(0xfffff);Delay(0xfffff);}}
//跑马灯控制函数,让4个灯轮流亮,最后全部重置熄灭
void LED_Turn_Run(void)
{while(1){GPIOE_BSRR &= ~(1<<8); GPIOE_BSRR |= 1<<24; Delay(0xfffff);Delay(0xfffff);GPIOE_BSRR |= 1<<25; Delay(0xfffff);Delay(0xfffff);GPIOE_BSRR |= 1<<26; Delay(0xfffff);Delay(0xfffff);GPIOE_BSRR |= 1<<27; Delay(0xfffff);Delay(0xfffff);GPIOE_BSRR |= 1<<8; GPIOE_BSRR |= 1<<9; GPIOE_BSRR |= 1<<10; GPIOE_BSRR |= 1<<11; Delay(0xfffff);Delay(0xfffff);}
}void KEY_Init(void)
{RCC_APB2ENR |=1<<3; GPIOB_CRL |=0X04000000;
}//static u8 fac_us=0;
void delay_us(u32 nus)
{ int i,cnt ;cnt = nus<<1 ;for ( i = 0 ; i < cnt ; i++ );}
void delay_ms(u16 nms)
{ int i ;for( i = 0 ; i < nms; i ++ )delay_us(1000) ;
} u8 KEY_Scan(void)
{ //键盘扫描,单按返回1,长按返回2u8 key_1= 0;int flag=0;//通过flag记录按键时间长短if(GPIOB_IDR & 0x40)key_1=1;else key_1=0;if(key_1==0){ delay_ms(100); if(key_1!=0) return 0;} while(key_1==0) {flag++;Delay(0xfffff);if(flag >= 15) return 2;//flag达到15则判定为长按if(GPIOB_IDR & 0x40)key_1=1;else key_1=0;if(key_1==0){delay_ms(100); if(key_1!=0) break;} }if(flag>0) return 1;//flag大于0但是没达到15判定为短按return 0;
}int main(void)
{u8 t=0;BoardInit();LED_Init();KEY_Init();while(1){t=KEY_Scan();if(t==1)//在main函数中进行判断按键状态{LED_Turn();}else if(t==2){LED_Turn_Run();}}return 1;
}