キー入力
1.はじめに
この実験では、STM32F103のIOポートを入力として使用する方法を紹介します。IOポートを入力として使用する場合、IDRの内容を読み取ることにより、IOポートのステータスが読み取られます。
この実験では、ボード上の4つのボタンを使用して、2つのLEDとブザーのオンとオフを制御します。その中で、KEY_UPはブザーを制御します; K1はD1を制御して1回押してオンにしてからオフにします; K2はD2を制御して1回押してオンにしてからオフにします; K3はD1とD2を同時に制御し、1回押して状態を1回フリップします
2.ハードウェア設計
使用されるハードウェアリソースは次のとおりです。
- インジケーターライトD1、D2
- ブザーBUZ
- 4つのボタン:KEY_UP、K1、K2、K3
ハードウェア接続の回路図は次のとおりです。K1、K2、K3がアクティブLOW、KEY_UPがアクティブHIであり、外部にプルアップおよびプルダウン抵抗がないため、STM32F1でセットアップおよびプルダウンする必要があります
。STM32F103チップのシングルIOポートが最大です。出力電流は25mAで、ブザーの駆動電流は約30mAです。チップ全体の最大出力電流は150mAです。ブザーで30mAが消費されると、チップの他のIOポートと周辺機器の電流は比較的きつくなります。そのため、ブザーを直接駆動するためにIOポートは使用されませんが、電流はトランジスターによって増幅されてからブザーが駆動されるため、ブザーを制御するためにIOポートは1mA未満の電流を提供するだけで済みます
3.ソフトウェア設計
3.1 STM32CubeMX設定
- RCCは外部HSEを設定、クロックは72Mに設定
- PC0とPC2はGPIOプッシュプル出力モード、プルアップ、高速に設定され、デフォルトの出力レベルは高
- PB5はGPIOプッシュプル出力、高速モードに設定されています
- PA0はGPIO入力モード、プルダウンモードに設定され、PE2 / PE3 / PE4はGPIO入力モード、プルアップモードに設定されます
- プロジェクト名を入力し、プロジェクトパス(中国語以外)を選択し、MDK-ARM V5を選択します。IPごとに「.c / .h」ファイルのペアとして生成されたペリフェラルの初期化を確認します。「コードを生成」をクリックしてプロジェクトコードを生成します
3.2 MDK-ARMソフトウェアプログラミング
- PC0 / PC1 / PB5 / PA0 / PE2 / PE3 / PE4の初期化関数をgpio.cファイルで確認できます
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {
0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOE_CLK_ENABLE(); //开启GPIOE时钟
__HAL_RCC_GPIOC_CLK_ENABLE(); //开启GPIOC时钟
__HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟
__HAL_RCC_GPIOB_CLK_ENABLE(); //开启GPIOB时钟
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, LED1_Pin|LED2_Pin, GPIO_PIN_SET); //LED1/LED2默认输出是电平为高电平
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(BUZ_GPIO_Port, BUZ_Pin, GPIO_PIN_RESET); //BUZ默认输出是电平为低电平
/*Configure GPIO pins : PEPin PEPin PEPin */
GPIO_InitStruct.Pin = K_LEFT_Pin|K_DOWN_Pin|K_RIGHT_Pin; //PE2/PE3/PE4
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; //输入
GPIO_InitStruct.Pull = GPIO_PULLUP; //上拉
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/*Configure GPIO pins : PCPin PCPin */
GPIO_InitStruct.Pin = LED1_Pin|LED2_Pin; //PC0/PC1
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; //推挽输出
GPIO_InitStruct.Pull = GPIO_PULLUP; //上拉
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; //高速
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = K_UP_Pin; //PA0
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; //输入
GPIO_InitStruct.Pull = GPIO_PULLDOWN; //下拉
HAL_GPIO_Init(K_UP_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = BUZ_Pin; //PB5
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; //推挽输出
GPIO_InitStruct.Pull = GPIO_NOPULL; //无上下拉
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; //高速
HAL_GPIO_Init(BUZ_GPIO_Port, &GPIO_InitStruct);
}
- プロジェクトのアプリケーションファイルディレクトリにkey.cファイルを作成し、キー関連の関数を記述します
/***********************************************************
*函 数 名: KEY_Scan(uint8_t mode)
*功 能: 按键处理函数
*形 参: mode:0 不支持连续按;1 支持连续按
*返 回 值: 返回按键值 0:表示未有按键按下
* 1:KEY_RIGHT按下 2:KEY_DOWN按下
* 3:KEY_LEFT按下 4:KEY_UP按下
***********************************************************/
uint8_t KEY_Scan(uint8_t mode)
{
static uint8_t key = 1; //按键松开标志
if(mode == 1){
//支持连按
key = 1;
}
if(key&&(KEY_UP==1||KEY_DOWN==0||KEY_LEFT==0||KEY_RIGHT==0)){
HAL_Delay(10); //按键消抖
key = 0;
if(KEY_UP==1) return K_UP_PRES;
else if(KEY_DOWN==0) return K_DOWN_PRES;
else if(KEY_LEFT==0) return K_LEFT_PRES;
else if(KEY_RIGHT==0) return K_RIGHT_PRES;
}
else if(KEY_UP==0&&KEY_DOWN==1&&KEY_LEFT==1&&KEY_RIGHT==1){
key = 1;
}
return 0;
}
- プロジェクトのヘッダーファイルディレクトリにkey.hファイルを作成し、関連するステートメントを記述します
#ifndef _KEY_H_
#define _KEY_H_
#include "stm32f1xx.h"
//操作HAL库函数读取IO口状态
#define KEY_RIGHT HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)
#define KEY_DOWN HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)
#define KEY_LEFT HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_2)
#define KEY_UP HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)
//定义按键按下时的键值
#define KEY_RIGHT_PRES 1
#define KEY_DOWN_PRES 2
#define KEY_LEFT_PRES 3
#define KEY_UP_PRES 4
uint8_t KEY_Scan(uint8_t mode);
#endif
- main.c関数に関連プログラムを記述します
int main(void)
{
/* USER CODE BEGIN 1 */
uint8_t key;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
key = KEY_Scan(0);
switch(key){
case KEY_UP_PRES:
HAL_GPIO_WritePin(GPIOB,BUZ_Pin,GPIO_PIN_SET);
HAL_Delay(300);
HAL_GPIO_WritePin(GPIOB,BUZ_Pin,GPIO_PIN_RESET);
HAL_Delay(300);
break;
case KEY_LEFT_PRES:
HAL_GPIO_TogglePin(GPIOC,LED1_Pin);
break;
case KEY_DOWN_PRES:
HAL_GPIO_TogglePin(GPIOC,LED2_Pin);
break;
case KEY_RIGHT_PRES:
HAL_GPIO_TogglePin(GPIOC,LED1_Pin);
HAL_GPIO_TogglePin(GPIOC,LED2_Pin);
break;
}
HAL_Delay(10);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
4.ダウンロードの確認
コンパイルが完了したら、開発ボードにダウンロードし、KEY_UPブザーを押して音を鳴らします。K1はD1を制御して1回押してオンにしてからオフにします。K2はD2を制御して1回押してもう一度オンにしてからオフにします。K3はD1とD2を同時に制御して1回押します彼らの状態は一度めくられる