CCWO

挫けそうになるブログ

STM32 F401RE ストップウォッチ

開発環境
・評価ボード NUCLEO-F401RE
IDE MDK-ARM V5 and STM32CubeMX
・OS windows 10 pro
・本

ボタンとUARTを使ってストップウォッチを作ってみました。
本ではLCD使ってだったのですが、LCDつなげるのめんどうだったので・・・・w
CubeMXの設定はこんな感じで。
f:id:CCWO:20160915221823p:plain
・main.c

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"

/* USER CODE BEGIN Includes */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart2;

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
#define	LED_PORT		GPIOA
#define	LED_PIN			GPIO_PIN_5
#define	LED_ON			GPIO_PIN_SET
#define	LED_OFF		GPIO_PIN_RESET
#define	SW_PORT		GPIOC
#define	SW_PIN			GPIO_PIN_13
#define	SW_OFF			GPIO_PIN_SET
#define	SW_ON			GPIO_PIN_RESET

#define	SET		0
#define	RUN		1
#define	STOP	2

char State = SET;
volatile int time_count = 0;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void Error_Handler(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);

/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
char sio_getc(void);		// UARTから1文字取得
void sio_putc(char);		// UARTに1文字を出力
void sio_puts(char *);	// UARTに文字列を出力
char GetSwotcj(void);
void ShowCount(void);
void Beep(void);
/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

void HAL_SYSTICK_Callback(){
	if(State == RUN)
		time_count++;
}

char sio_getc()
{
	char ch;
	while(HAL_UART_Receive(&huart2, (uint8_t *)&ch, 1, 1000)==HAL_TIMEOUT) ;
	return ch;
}

void sio_putc(char ch)
{
	HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 1000);
}

void sio_puts(char *str)
{
	HAL_UART_Transmit(&huart2, (uint8_t *)str, strlen(str), 1000);
}

void ShowCount()
{
	char str[10];
	static int lastval = -1;
	int val = time_count / 10;
	int ms, sec, min;
	if(lastval == val)
		return;
	
	ms = val % 100;
	sec = (val / 100) % 60;
	min = (val / 6000);
	sio_puts("\033[2J");
	sio_puts("\033[0;0H");
	sio_puts("Stop Watch\n");
	sprintf(str, "%02d:%02d:%02d\n", min, sec, ms);
	sio_puts(str);
}

char GetSwitch()
{
	if(HAL_GPIO_ReadPin(SW_PORT, SW_PIN) == SW_ON){
		HAL_GPIO_WritePin(LED_PORT, LED_PIN, LED_ON);
		return 1;
	}else{
		HAL_GPIO_WritePin(LED_PORT, LED_PIN, LED_OFF);
		return 0;
	}
}

/* USER CODE END 0 */

int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART2_UART_Init();

  /* USER CODE BEGIN 2 */
	State = SET;
	time_count = 0;
	sio_puts("Stop Watch\n");
	ShowCount();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  if(GetSwitch()){
		  switch(State){
			  case SET:{
				  State = RUN;
				  break;
			  }
			  case RUN: {
				  State = STOP;
				  break;
			  }
			  case STOP:{
				  time_count = 0;
				  State = SET;
				  break;
			  }
		  }
		  while(GetSwitch())
			  ShowCount();
	  }
	  ShowCount();
				  
			  
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

  }
  /* USER CODE END 3 */

}

こんな感じになりました。ただ、参考の本には1msのタイマー割り込みの処理が書かれていなかったので追加しました。
f:id:CCWO:20160915221632j:plain
ちょっと急ごしらえのプログラムだったので画面キャプチャソフトだとちらついてうつらなくて(´・_・`)仕方なくiPhoneで・・・w