実験(7): NVIC割り込み応用: 正確な遅延を伴うLED点滅実験

1. 実験の目的と課題

目的:

1. NVIC の使い方を学びます。

2. KEIL5 のシミュレーションとデバッグをマスターします。

タスク:

1. 要件に従ってプログラムを作成し、原則的な注意事項を書き留めます。

2. プログラムの動作結果を確認し、それが正しいかどうかを分析します。

3. 構築されたプロジェクトの検証と試運転を完了します。

2. 実験要件

ターゲットボード上の赤色 LED を一定時間点滅させます。オン時間は 500ms、オフ時間は 500ms です。同時に、メイン プログラムで 32 ビットの符号なし変数 CountOfToggle を定義して赤色 LED の点滅数をカウントし、赤色 LED が点滅を完了するたびにこの変数の値をデバッグ ウィンドウに出力します。達成するために中断します。

3. 実験内容と手順

1. 回路図を設計する

図 1 RGB LED ライトと STM32 マイクロコントローラー インターフェイス回路

2. ソフトウェア設計

  • バックグラウンド (メインプログラム):

図 2 に示すように、バックグラウンド プロセスはシステムの初期化と無限ループで構成されます。

図2 バックグラウンドプログラムのフローチャート

1) システムの初期化

この例の STM32F103 マイクロコントローラは、電源が投入されてリセットされた後、まず初期化ピン PA1 (赤色 LED に接続された多重化ピン)、NVIC の初期化、初期化などの一連の初期化機能を通じてシステムの初期化作業を完了します。 TIM2などの

  • PA1ピンを初期化します。

ピン PA1 は LED1 に接続されています。

  • NVICを初期化します。

NVIC を初期化します (TIM2 割り込みを設定します)。

  • TIM2を初期化します。

通常の設定タイマーに加えて、STM32F103 マイクロコントローラーのタイマー割り込みを使用する必要がある場合は、タイマーの関連する割り込みソースを有効にする必要があります。具体的には、この実験で TIM2 を初期化するソフトウェア プロセスを図 3 に示します。

図 3 TIM2 の初期化

この例の TIM2 の初期化プロセスの各ステップは、STM32F103x 標準ペリフェラル ライブラリ内の対応するライブラリ関数をプログラミングすることで実装できます。

2) 無限ループ

無限ループはバックグラウンド プログラムに不可欠な部分です。システムの初期化が完了すると、常にこの無限ループで実行されます。この例のバックグラウンド ループでは、継続的に TIM2 をクエリして、割り込みフラグ変数 flag (初期値 0) を更新し、対応する処理を実行します。

flag の値が 0 の場合 (つまり、TIM2 の更新が発生していないか、処理されている場合)、マイクロコントローラーはこの時点では何もせず、無限ループの先頭に戻ってクエリを続行します。

フラグの値が 1 の場合 (つまり、TIM2 の更新割り込みが発生して処理されない場合)、マイクロコントローラーはこの時点で赤色 LED に接続されているピン PA1 の出力を反転し、その回数を記録します。赤色の LED が点滅し、フラグをゼロにクリアします。無限ループの先頭に戻り、クエリを再開します。

  • フォアグラウンド (TIM2 割り込みサービス ルーチン)

この例のフォアグラウンド ソフトウェアは、500ms ごとに実行される TIM2 割り込みサービス プログラムで構成されています (TIM2 の更新により中断されます)。

実験では、TIM2更新割り込みの処理(赤色LEDの点灯や点滅回数のカウントなど)はメインプログラムで実装されており、TIM2更新割り込みフラグ変数の値に応じて実行されます。したがって、

したがって、TIM2割り込みサービス ルーチンは非常に短く、その主な仕事はフラグ変数を 1 に設定することです。具体的なプロセスを図 4 に示します。

図 4 TIM2 割り込みサービス ルーチンのフローチャート

TIM2 更新割り込みフラグ変数 flag を 1 に設定するステップに加えて、フォアグラウンド プロセスの他のステップは、対応するライブラリ関数を使用してプログラミングすることによって実現できます。

3. 実験手順

(1) Keil uVision5 開発環境を実行し、プロジェクトを作成します。

(2) main.c ファイルをプロジェクトに追加します。この実験では LED ライトと OLED ディスプレイを使用するため、図 5 に示すように、LED および OLED 関連ファイルがプロジェクトに移植されます。

図 5 ファイルの移行

(3) プロジェクトにタイマー関連ファイルを追加します。今回の実験ではタイマー割り込みを使用するので、Timer.c と Timer.h の 2 つのファイルを作成し、タイマー割り込み (汎用タイマー TIM2) を開き、最初に Timer のソースコードを記述します c を図 6 に示します。

図 6 Timer.c コードの書き込み

(4)図 7 に示すように、プロジェクト エンジニアリング ツールを移植できるように、将来のプロジェクト ファイルの移植を容易にする Timer.h プログラムを作成します。

図 7 Timer.h プログラムの書き込み

エラーや警告なしで正常に実行およびデバッグできます。

(5) main.c プログラムを作成し、図 8 に示すように、タイマ 2 割り込み関数 (タイミング割り込み) を呼び出し、メインプログラム内で初期化設定、フラグビット判定、LED 点滅を行います。

図 8 main.c プログラムの作成

4. デバッグの検証と結果

(1) 図 9 に示すように、開発ボードをコンピュータに接続し、STLINK を使用してプログラムを STM32 マイクロコントローラに焼き付けます。

図 9 書き込みプログラム

(2) プログラムが書き込まれた後、図 10 に示すように、OLEDに表示される LED フラッシュの数を観察します。

図 10 OLED は LED フラッシュの数を表示します

4. 実験的なコード分析

(1) Timer.c プログラム:

#include "stm32f10x.h"                  // Device header

void Timer_Init(void){
	//开启时钟,TIM2是APB1的时钟外设
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
    	
	//选择时基单元的时钟,可以不选,默认上电后选择内部时钟
	TIM_InternalClockConfig(TIM2);
	
	//配置时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//指定时钟分频
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//计数器模式
	TIM_TimeBaseInitStructure.TIM_Period = 5000 - 1;//ARR自动重装器的值
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;//PSC预分频器的值
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//重复计数器的值,高级定时器使用
	
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
	
    //手动清除中断标志位,避免刚初始化完就进入中断
	TIM_ClearFlag(TIM2,TIM_IT_Update);
	
	//使能中断
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
	
	//配置NVIC
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
	
	//启动定时器
	TIM_Cmd(TIM2,ENABLE);
    
}

(2) main.c プログラム:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "OLED.h"
#include "Timer.h"

uint32_t CountOfToggle;//计数变量
uint8_t flag = 0;//标志位

int main(void)
{
	OLED_Init();
	Timer_Init();
	LED_Init();
	
	OLED_ShowString(1, 1, "Num:");
	
	while (1)
	{
		OLED_ShowNum(1, 5, CountOfToggle / 2, 5);
		if(flag == 1)
		{
			LED1_Turn();
			flag = 0;
			CountOfToggle++;
		}
	}
}

void TIM2_IRQHandler(void)
{
	//判断中断
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
	{
		flag = 1;
		//清除中断标志位
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}

5. 実験の概要

この実験は、組み込みシステムにおける NVIC の使用法を学習し、割り込みを使用してターゲット ボード上の赤色 LED の点滅を実現する方法を習得し、各点滅が完了した後に OLED ディスプレイに LED の点滅数を表示することを目的としています。実験では、NVIC の概念と使用法を理解し、STM32F1 シリーズ マイクロコントローラーでの NVIC の使用方法、およびペリフェラルの動作を制御するための割り込みハンドラーの使用方法に精通する必要があります。

まず、メイン プログラムで 32 ビットの符号なし変数 CountOfToggle を定義して LED の点滅回数を記録し、タイマー割り込みを使用して LED の点滅時間を制御し、GPIO を使用して LED スイッチを制御する必要があります。プログラムの起動段階では、タイマーと GPIO、および NVIC の関連設定を初期化する必要があります。タイマー割り込みでは、LED のスイッチと CountOfToggle の値を制御し、I2C プロトコルを通じて CountOfToggle の値を OLED ディスプレイに送信する必要があります。

実験では次の点に注意する必要があります。

  • プログラムを作成するときは、チップ モデルに応じて正しいヘッダー ファイルとライブラリ ファイルを選択し、KEIL で正しいコンパイルとダウンロード オプションを設定して、プログラムが正しくコンパイルされてマイクロコントローラーにダウンロードできるようにする必要があります。
  • NVIC を使用する場合、優先順位の設定に注意する必要があり、通常、割り込みの処理が時間内に行われるように、割り込みの優先順位はタスクの優先順位よりも高くする必要があります。
  • タイマ割り込みを使用する場合は、必要な点滅時間が得られるように、タイマのクロックソースと分周数に応じて、タイマのカウント周期とカウンタのオーバフローの時間間隔を設定する必要があります。
  • GPIO を使用する場合は、GPIO ポートの初期化と構成、および GPIO ポートの状態を制御する方法に注意する必要があります。

この実験を通じて、NVIC の概念と使用法をより深く理解し、割り込みを使用して周辺機器の動作を制御する方法を学び、I2C プロトコルを使用して OLED ディスプレイにデータを転送し、よりハードウェア関連の対話方法を習得しました。同時に、プログラムを作成する過程で、コードの読みやすさと保守性を向上させるコードスタイルとコメントの重要性に気づきました。プログラムをデバッグするときに、KEIL のシミュレーション ツールとデバッグ ツールを使用して問題をより迅速に特定して修正する方法も学びました。

全体として、この実験は私にとって非常に有益であり、組み込みシステムの開発とデバッグについての理解が深まり、将来の研究と仕事のための良い基盤も築かれました。

ソースコード:実験 7

おすすめ

転載: blog.csdn.net/qq_61228493/article/details/131211075