読者です 読者をやめる 読者になる 読者になる

CCWO

挫けそうになるブログ

STM32 F401RE キッチンタイマー

F401RE STM32

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

今度はUARTとSW3つとLEDを使って、キッチンタイマーを作成しました。
STM32CubeMXの設定はこんな感じで
f:id:CCWO:20160916002347p: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		GPIOC
#define	LED_PIN			GPIO_PIN_2
#define	LED_ON			GPIO_PIN_SET
#define	LED_OFF		GPIO_PIN_RESET
#define	SW_0				GPIO_PIN_13
#define	SW_1				GPIO_PIN_0
#define	SW_2				GPIO_PIN_1
#define	SW_OFF			GPIO_PIN_SET
#define	SW_ON			GPIO_PIN_RESET

#define	mSW0	1
#define	mSW1	2
#define	mSW2	4

volatile int time_count = 0;

// state
#define	SET	0
#define	RUN	1

char State = SET;

/* 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 DGetSwitch(void);
char GetSwitch(void);
void ShowCount(void);
void Beep(int mode);
char sio_getc(void);		// UARTから1文字取得
void sio_putc(char);		// UARTに1文字を出力
void sio_puts(char *);	// UARTに文字列を出力
/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

void HAL_SYSTICK_Callback(){
	int ms;
	if(State == RUN){
		if(ms == 1000){
			time_count--;
			ms = 0;
		}
		ms++;
	}
}

char DGetSwitch()
{
	// スイッチの状態を返す
	char swmask;
	if(HAL_GPIO_ReadPin(GPIOC, SW_0) == SW_ON){
		swmask |= mSW0;
	}
	if(HAL_GPIO_ReadPin(GPIOC, SW_1) == SW_ON){
		swmask |= mSW1;
	}
	if(HAL_GPIO_ReadPin(GPIOC, SW_2) == SW_ON){
		swmask |= mSW2;
	}
	HAL_Delay(20);
	return swmask;
}

void WaitOff()
{
	// スイッチが全て開放されるまで待つ
	while(DGetSwitch()) ;
}

char GetSwitch()
{
	// スイッチが押されるまで待ってから、スイッチの状態を返す
	char sw;
	WaitOff();
	do{
		sw = DGetSwitch();
	}while(sw == 0) ;
	return sw;
}

void ShowCount()
{
	char str[16];
	int min, sec;
	min = time_count / 60;
	sec = time_count % 60;
	sprintf(str, "%02d:%02d\n", min , sec);
	sio_puts(str);		
}

void Beep(int mode)
{
	if(mode){
		HAL_GPIO_WritePin(LED_PORT, LED_PIN, LED_ON);
	} else {
		HAL_GPIO_WritePin(LED_PORT, LED_PIN, LED_OFF);
	}
		
}

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);
}
/* USER CODE END 0 */

int main(void)
{

  /* USER CODE BEGIN 1 */
	char sw;
	int min, sec;
	char *modestr[2] = {(char *)"SET ", (char *)"RUN "};
	int lastval;
  /* 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 */
	sio_puts(modestr[State]);
	time_count = 0;
	ShowCount();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  if(State == SET){
		  sw = GetSwitch();
		  sec = time_count % 60;
		  min = time_count / 60;
		  switch(sw){
			  case mSW0: {
				  WaitOff();
				  State = RUN;
				  sio_puts(modestr[State]);
				  lastval = time_count;
				  Beep(0);
				  break;
			  }
			  case mSW1: {
				  sec = (sec + 5) % 60;
				  break;
			  }
			  case mSW2: {
				  min = (min + 1) % 16;
				  break;
			  }
		  }
		  time_count = min * 60 + sec;
		  ShowCount();
	  } else {
		  if(lastval != time_count){
			  ShowCount();
			  lastval = time_count;
		  }
		  sw = DGetSwitch();
		  if(sw == mSW0){
			  State = SET;
			  sio_puts(modestr[State]);
		  }
		  if(time_count == 0){
			  ShowCount();
			  Beep(1);
			  State = SET;
			  sio_puts(modestr[State]);
		  }
	  }
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

  }
  /* USER CODE END 3 */

}

まだまだかなり雑だ・・・。もうちょい頑張るかも。
f:id:CCWO:20160916002601j:plain
白ボタンで5秒増加、黒ボタンで1分増加って感じで基板上の青色ボタンでスタートorストープってなってます。
赤色LEDで終了をお知らせします。
ちょっとまだまだしょぼいですが・・・もしかしたら改良することがあるかもw
見た目の方はちょっと楽して画面の更新はなくしましたが、こんな感じです。
(これはぱぱっと終わらせるためにmsでカウントを下げてるのでSWのディレイ分の20msごとに減っていますね。)
f:id:CCWO:20160916002442p:plain