LSI Jiu-Jitsu

電子工作とブラジリアン柔術

STM32で遊ぶ (3) - LEDチカチカ

前回構築したSW4STM32環境を使って、NUCLEO-F446REのLEDをチカチカさせてみます。(俗に言うエルチカ)
LEDはボード上にユーザー用として1つだけ実装されている「LD2」を使用します。
LD2の接続先はこちらの「UM1724 User manual」によると「PA5」か「PB13」と記載されています。
https://www.stmcu.jp/design/hwdevelop/nucleo/51836/
f:id:mohran:20200304225432j:plain

そして、回路図(Schematics)を見てみるとジャンパ線の「SB21」「SB29」「SB42」がLD2に関係しているようです。
f:id:mohran:20200304232747j:plain

ボードの裏側を見てみると「SB21」と「SB42」が接続されているので、PA5(GPIOA5)がLD2の制御に使用できることがわかりました。
f:id:mohran:20200304233736j:plain

プログラムですが、16BitのTIM6を使用して1秒周期で割り込みを発生させてLD2をHigh/Lowさせるようにしました。
(TIM6のクロックは90MHzなので、プリスケーラで10,000倍して9,000カウントで1秒割り込みを実現しています)
f:id:mohran:20200305000626j:plain

/**
  ******************************************************************************
  * @file    main.c
  * @author  Ac6
  * @version V1.0
  * @date    01-December-2013
  * @brief   Default main function.
  ******************************************************************************
*/

#include "stm32f4xx.h"

uint32_t led;

int main(void){
  led = 0;

  *(volatile unsigned int*)(RCC_BASE   + 0x30) = 0x00000001;   // RCC_AHB1ENR
  *(volatile unsigned int*)(RCC_BASE   + 0x40) = 0x00000010;   // RCC_APB1ENR
  *(volatile unsigned int*)(GPIOA_BASE + 0x00) |= 0x00000400;  // GPIOA_MODER
  *(volatile unsigned int*)(GPIOA_BASE + 0x14) = led;          // GPIOA_ODR

  *(volatile unsigned int*)(TIM6_BASE + 0x04) = 0x00000000;    // TIM6_CR2
  *(volatile unsigned int*)(TIM6_BASE + 0x0c) = 0x00000001;    // TIM6_DIER

  NVIC_EnableIRQ(TIM6_DAC_IRQn);

  *(volatile unsigned int*)(TIM6_BASE + 0x28) = 9999;         // TIM6_PSC
  *(volatile unsigned int*)(TIM6_BASE + 0x2c) = 9000;         // TIM6_ARR
  *(volatile unsigned int*)(TIM6_BASE + 0x24) = 0x00000000;   // TIM6_CNT
  *(volatile unsigned int*)(TIM6_BASE + 0x00) = 0x00000001;   // TIM6_CR1

  while(1){}

  return(0);
}

void TIM6_DAC_IRQHandler(void){
  if(led==0){
      led=0x20;
  }else{
      led=0x00;
  }

  *(volatile unsigned int*)(GPIOA_BASE + 0x14) = led;         // GPIOA_ODR
  *(volatile unsigned int*)(TIM6_BASE  + 0x10) = 0x00000000;  // TIM6_SR
}


「Project」→「Build All」でコンパイルします。
f:id:mohran:20200305111333j:plain


PCと接続します。
f:id:mohran:20200305112448j:plain


「Run」→「Debug Configurations...」からデバッガを設定します。
f:id:mohran:20200305112922j:plain
f:id:mohran:20200305113056j:plain


「Ac6 STM32 Debugging」をダブルクリックして、右側に表示されるウィンドウの「Search Project...」からelfファイルを選択します。
「Apply」→「Debug」でボードとの接続とロードが行われます。
f:id:mohran:20200305120448j:plain


何度か表示されるウィンドウは「No」を選択します。(Yesでも問題ないです)
f:id:mohran:20200305121057j:plain


「Resume」ボタンをクリックするとデバッグが開始され、1秒間隔でLD2がチカチカ繰り返せば成功です。
f:id:mohran:20200305123158j:plain


プログラム内のレジスタについては、こちらの「RM0390 Reference manual」を参考にしました。
https://www.stmcu.jp/stm32/stm32f446/
f:id:mohran:20200305123856j:plain

レジスタアドレスのdefine名は「CMSIS\device\stm32f4xx.h」を使用しています。

[参考記事]