STM32F103C8X的I/O按键扩展使用

众所周知,虽然STM32F1系列属于中低端的32位ARM控制器,但其功能也是极为强大。在继承了STM32F0的基础上,将核心频率、FLASH、RAM、ADC的性能与容量做出了极大的改进,并且增加了DAC模块和IIS、USB、CAN,SDIO总线通信功能,是目前最为常用的32位位控制器入门学习器件,其中I/O接口的扩展使用更是几乎所有工程中都需要用到的功能。使用外设按键开关通过32对一些对象进行控制更是工程中最为常用的几种I/O扩展之一。
首先,我们先以单个触点式开关按键为例,第一步了解按键的特性:
STM32F103C8X的I/O按键扩展使用_第1张图片
STM32F103C8X的I/O按键扩展使用_第2张图片
STM32F103C8X的I/O按键扩展使用_第3张图片
微机键盘通常使用机械触点式按键开关,其主要功能式把机械上的通断转换为电气上的逻辑关系。也就是说,它能提供标准的TTL逻辑电平,以便于通用数字系统的逻辑电平相容。机械式按键再按下或释放时,由于机械弹性作用的影响,通常伴随有一定的时间触点机械抖动,然后其触点才稳定下来。其抖动过程如下图1所示,抖动时间的长短与开关的机械特性有关,一般为5-10ms。在触点抖动期间检测按键的通与断,可能导致判断出错,即按键一次按下或释放错误的被认为是多次操作,这种情况是不允许出现的。为了克服你、按键触点机械抖动所致的检测误判,必须采取消抖措施。按键较少时,可采用硬件消抖;按键较多式,采用软件消抖。当按键未按下时12、34之间属于开通状态,按键按下时,12、34之间导通,13、24引脚长通。那么如何使按键可以给控制器发出信号从而达到控制的效果呢?
STM32F103C8X的I/O按键扩展使用_第4张图片
如图当开关断开时由于上拉电阻的作用,此时该脚电压为3.3v也就是信号1,当开关闭合时,该脚电压为0V,也就是信号0,由此法达到信号的输

接下来是信号在STM32的内部进行运算的过程,该步骤我们需要借助STM32Cube以及keil5来编程实现。
1.我们先使用STM32Cube对32进行我们期望的配置,这里我设定A7为开关信号的输入以及B12为所控制的灯所接的引脚。
STM32F103C8X的I/O按键扩展使用_第5张图片
2.用STM32Cube打开keil5,因为在该工程中,我只改写了main.c的代码,所以不在此张贴其他相关文件的代码。
以下是main.c的代码

#include "main.h"
#include "stm32f1xx_hal.h"

void SystemClock_Config(void);
static void MX_GPIO_Init(void);

int main(void)
{
 	uint8_t KeyStates;//定义一个无符号整形变量:KeyStates,'_t'即为typedef的缩写(个人理解)
	uint8_t LEDStates;//同上

  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  while (1)
  {
    KeyStates=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_7);//将从A7引脚读取的值赋给KeyStates
   if (KeyStates == GPIO_PIN_RESET)//检测到按键按下
	 {
		 HAL_Delay(30);
		 KeyStates = (HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_7));//延时消抖
		 if (KeyStates == GPIO_PIN_RESET)
		 {
			 if(LEDStates == GPIO_PIN_RESET)
			 LEDStates = 1;
			 else
			 LEDStates = 0;//将LED的状态反转
			 while (GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_7) );//打个监测到按键复位时跳出循环,可以防止按键按下时间过长造成的不稳定
		 }
		 if(LEDStates == 0)
		 {
			 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_RESET);//设定B12脚为输出信号脚,当LEDStates为0时B12输出低电平
		 }
		 else if(LEDStates == 1)
		 {
			 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_SET);//当LEDStates为1时B12输出高电平
		 }
	 }		 

		}
}
//以下为Cube所配置的程序
void SystemClock_Config(void)
{

  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
static void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct;

  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_SET);

  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 
                          |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = GPIO_PIN_12;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}
void _Error_Handler(char *file, int line)
{
  while(1)
  {
  }

}

#ifdef  USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line)
{ 

}

运行结果:使得当按键按下时LED灯亮,再按下时,LED灯灭。
应用:可将LED替换为继电器,从而使用按键驱动大功率器件的启动与关闭。


你可能感兴趣的:(STM32)