【STM32】嵌入式实验二 GPIO 实验 (前三个设计)

发布于:2024-04-18 ⋅ 阅读:(95) ⋅ 点赞:(0)

1. 按键亮灯

设计 GPIO 实验项目 1,功能:当按键 KB1 按下时,实验板上全彩发光二极管周边 的发光二极管全亮,当按键 KB2 按下时跑马灯 D0 闪亮。

实验要求基于寄存器的GPIO配置,所以需要手动操作寄存器来配置时钟和输入输出模式(如果不要求,在cubemx里可以直接配置)。

跑马灯和按键KB1,KB2的端口模式为推挽输出和输入,因此需要编程将它们设置为对应的模式:

 参考下面的端口位配置表,

一个端口占用配置寄存器的四位来设置工作模式,可以知道CRL(0-7(低八位)的引脚对应CRL配置寄存器)里输出跑马灯和输入按键KB1,KB2的每个端口应配置为:0011(16进制0x3)和0100(16进制0x4)

 那么,使用 CubeMX 创建工程,只设置芯片选型、 系统时钟、调试端口; GPIO 配置在程序中通过寄存器配置完成。

按键按下为低电平,所以检测 数据输入寄存器(GPIOx_IDR)与(&)上对应位为1的数的 结果,比如PE0就是与 0x01。

if((GPIOE->IDR&0X01)==0){
			flag=1;
		}
		else if((GPIOE->IDR&0X02)==0){
			flag=2;
		}

功能是 当按键 KB1 按下时,实验板上全彩发光二极管周边 的发光二极管全亮,当按键 KB2 按下时跑马灯 D0 闪亮,因为跑马灯是高电平点亮,就是数据输出寄存器 GPIOF_ODR 对应位 置为1,D0闪亮的话就是对这一位不断取反,这一位异或1其他位异或0即可。

if(flag==1){
		    GPIOF->ODR|=0XFF;
		}
		else if(flag==2){
		  GPIOF->ODR^=0X01;
			HAL_Delay(50);
		}

主要代码如下:

#flag设为全局变量,方便调试查看
int flag=0;
int main(void)
{

  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();


  /* Initialize all configured peripherals */
  MX_GPIO_Init();

	
	RCC->APB2ENR|=1<<7;//使能PORTF时钟
	GPIOF->CRL&=0X00000000;
	GPIOF->CRL|=0X33333333;//PF.0-PF.7推挽输出
	GPIOF->ODR=0X00;//清除显示
	
	RCC->APB2ENR|=1<<6;//使能PORTE时钟
	GPIOE->CRL&=0X00;
	GPIOE->CRL|=0X44;//PE.0-PE.1开漏输入
  while (1)
  {
   
		if((GPIOE->IDR&0X01)==0){
			flag=1;
		}
		else if((GPIOE->IDR&0X02)==0){
			flag=2;
		}
		else flag=0;
		
		
		if(flag==1){
		    GPIOF->ODR|=0XFF;
		}
		else if(flag==2){
		  GPIOF->ODR^=0X01;
			HAL_Delay(50);
		}else{
			GPIOF->ODR=0X00;
		}
		
  }
}

2.顺时针方向旋转的跑马灯

实现顺时针方向旋转的跑马灯,跑马灯延时 0.2 秒。按照灯的顺序,将GPIOF_ODR 对应位 置为1。

基于寄存器:

RCC->APB2ENR|=1<<6;
	GPIOE->CRL&=0X00000000;
	GPIOE->CRL|=0X44;

//while里

for(int i=0;i<8;i++){
		GPIOF->ODR=0X01<<i;
//这里的延时不是0.2s,自行调整
		for(int k=0;k<100000;k++);
		}

HAL库:

uint16_t x=0x0001;
for(int i=0;i<8;i++){
		//GPIOF->ODR=0X01<<i;
		//for(int k=0;k<100000;k++);
			HAL_GPIO_WritePin(GPIOF,x<<i,1);
			HAL_Delay(200);
			HAL_GPIO_WritePin(GPIOF,x<<i,0);
		}

 3.按键控制跑马灯方向

编写程序,当按键 KB1 按下时,跑马灯按顺时针方向旋转,按下 KB2 时,跑马灯 按逆时针方向旋转。

结合前两者代码,为了方便,逆时针用新的变量y=0x0080 右移 来选择八个灯的引脚。

RCC->APB2ENR|=1<<6;
	GPIOE->CRL&=0X00000000;
	GPIOE->CRL|=0X44;
	uint16_t x=0x0001;
	uint16_t y=0x0080;
  while (1)
  {
		if((GPIOE->IDR&0X01)==0){
			flag=1;
		}
		else if((GPIOE->IDR&0X02)==0){
			flag=2;
		}
		else if(HAL_GPIO_ReadPin(GPIOD,GPIO_PIN_6)==0){
		    flag=3;
		}
		//else flag=0;
		
		
		
		
		if(flag==1){

			for(int i=0;i<8;i++){
			HAL_GPIO_WritePin(GPIOF,x<<i,1);
			HAL_Delay(200);
			HAL_GPIO_WritePin(GPIOF,x<<i,0);
		}
			
		}
		else if(flag==2){
			for(int i=0;i<8;i++){
			HAL_GPIO_WritePin(GPIOF,y>>i,1);
			HAL_Delay(200);
			HAL_GPIO_WritePin(GPIOF,y>>i,0);}
			
		}else if(flag==3){

		}else{
		GPIOF->ODR=0X00;
		}
		
  }

}


网站公告

今日签到

点亮在社区的每一天
去签到

热门文章