外部中断
1.外部割り込みの概要
STM32F1の各IOポートは外部割り込みの割り込み入力として使用でき、STM32F103の割り込みコントローラーは19の外部割り込み/イベント要求をサポートしています。各割り込みにはステータスビットがあり、各割り込み/イベントには独立したトリガーとシールド設定があります。STM32F103の19の外部割り込みは次のとおりです。
- EXTI line 0〜15:外部IOポートの入力割り込みに対応
- EXTIライン16:PVD出力に接続
- EXTIライン17:RTCアラームイベントに接続
- EXTIライン18:USBウェイクアップイベントに接続されています
- EXTIライン19:イーサネットウェイクアップイベントに接続(インターネットタイプの製品)
STM32F103には、IOポート用に16本の割り込みラインしかありませんが、16本を超えるIOポートがあります。次の図は、GPIOと割り込みラインのマッピング関係を示しています
2.ハードウェア設計
使用されるハードウェアリソースは次のとおりです。
- インジケーターライトD1、D2
- ブザーBUZ
- 4つのボタン:KEY_UP、K1、K2、K3
ハードウェア接続の回路図は次のとおりです:K1、K2、およびK3がアクティブLOW、KEY_UPがアクティブHIであることに注意してください。したがって、K1、K2、K3をプルアップ、立ち下がりエッジトリガー割り込みに設定し、KEY_UPをプルダウン、立ち上がりエッジトリガー割り込みに設定する必要が
あります。STM32F103チップの単一のIOポートの最大出力電流は25mAで、ブザーの駆動電流は約30mAです。チップの最大出力電流は150mAです。ブザーで30mAを消費すると、チップの他のIOポートと周辺機器の電流は比較的タイトになります。したがって、IOポートはブザーを直接駆動するために使用されませんが、三極管は電流を増幅してからブザーを駆動するため、IOポートはブザーを制御するために1mA未満の電流を提供するだけで済みます。
この実験では、4つのオンボードボタンを使用して、外部割り込みを通じてオンボードの2つのLEDを制御します。消灯とブザー。その中で、KEY_UPはブザーを制御します; K1はD1を制御して1回押してオンにしてからオフにします; K2はD2を制御して1回押してオンにしてからオフにします; K3はD1とD2を同時に制御し、1回押して状態を1回フリップします
3.ソフトウェア設計
3.1 STM32CubeMX設定
- RCCは外部HSEを設定、クロックは72Mに設定
- PC0とPC2はGPIOプッシュプル出力モード、プルアップ、高速に設定され、デフォルトの出力レベルは高
- PB5はGPIOプッシュプル出力、高速モードに設定されています
- PA0はプルダウン、立ち上がりエッジトリガーに設定され、PE2 / 3/4はプルアップ、立ち下がりエッジトリガーに設定されます
- NVIC(Nested Vectored Interrupt Controller)で、EXIT Line0 / 2/3/4割り込みを確認して、PA0およびPE2 / 3/4割り込みを有効にします。右側の2つのオプションは、プリエンプション優先度と応答優先度を設定します
- プロジェクト名を入力し、プロジェクトパス(中国語以外)を選択し、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 : PE2 PE3 PE4 */
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4; //PE2/PE3/PE4
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; //下降沿触发
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 : PA0 */
GPIO_InitStruct.Pin = GPIO_PIN_0; //PA0
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; //上升沿触发
GPIO_InitStruct.Pull = GPIO_PULLDOWN; //下拉
HAL_GPIO_Init(GPIOA, &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);
}
ウィークシンボル割り込みコールバック関数のプロトタイプを見つけ、gpio.cでコールバック関数をカスタマイズします
__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
HAL_Delay(10);
switch(GPIO_Pin){
case GPIO_PIN_0:
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 GPIO_PIN_2:
HAL_GPIO_TogglePin(GPIOC,LED1_Pin);
break;
case GPIO_PIN_3:
HAL_GPIO_TogglePin(GPIOC,LED2_Pin);
break;
case GPIO_PIN_4:
HAL_GPIO_TogglePin(GPIOC,LED1_Pin);
HAL_GPIO_TogglePin(GPIOC,LED2_Pin);
break;
}
}
4.ダウンロードの確認
コンパイルが完了したら、開発ボードにダウンロードし、KEY_UPブザーを押して音を鳴らします。K1はD1を制御して1回押してオンにしてからオフにします。K2はD2を制御して1回押してもう一度オンにしてからオフにします。K3はD1とD2を同時に制御して1回押します彼らの状態は一度めくられる