STM32CubeMX---状态机实现流水灯

源码下载链接:https://taileliekaishi.lanzoui.com/ikaaHgeybsd

注意:点击图片可放大查看

结构体的方式来封装点亮两个LED灯

// led.h文件:进行声明
#ifndef __LED_H_
#define __LED_H_

#include "MyApplication.h"

//定义枚举类型 
typedef enum
{
	// 赋值的数据可以随便写
	LED1 = (uint8_t)0x01,
	LED2 = (uint8_t)0x02,
}LED_Num_t;

// 定义结构体类型
typedef struct
{
	// 定义3个函数指针,其中函数的参数是传LED等的状态
	void (*LED_ON)(uint8_t); // 打开
	void (*LED_OFF)(uint8_t); // 关闭
	void (*LED_Flip)(uint8_t); // 反转
}LED_t;

// 外部声明
extern LED_t LED;

#endif
// led.c文件:具体的实现
/* Includes ------------------------------------------------------------------*/
#include "MyApplication.h"

/* Private define-------------------------------------------------------------*/

/* Private variables----------------------------------------------------------*/
static void LED_ON(uint8_t);
static void LED_OFF(uint8_t);
static void LED_Flip(uint8_t);
/* Public variables-----------------------------------------------------------*/
LED_t LED = 
{
	LED_ON,
	LED_OFF,
	LED_Flip
};
/* Private function prototypes------------------------------------------------*/  
// 打开LED灯
static void LED_ON(uint8_t LED_Num)
{
	switch(LED_Num)
	{
		case LED1: HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_RESET); break;
		case LED2: HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_RESET); break;
		default: System.Assert_Failed();
	}
	
}

// 关闭
static void LED_OFF(uint8_t LED_Num)
{
	switch(LED_Num)
	{
		case LED1: HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_SET); break;
		case LED2: HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_SET); break;
		default: System.Assert_Failed();
	}
}

// 反转
static void LED_Flip(uint8_t LED_Num)
{
	switch(LED_Num)
	{
		case LED1: HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin); break;
		case LED2: HAL_GPIO_TogglePin(LED2_GPIO_Port,LED2_Pin); break;
		default: System.Assert_Failed();
	}
}
// System.c文件:具体的运行函数
/* Includes ------------------------------------------------------------------*/
#include "MyApplication.h"

/* Private define-------------------------------------------------------------*/

/* Private variables----------------------------------------------------------*/
static void Run(void); 
static void Error_Handler(void);
static void Assert_Failed(void);
	
/* Public variables-----------------------------------------------------------*/
System_t System = 
{
	Run,                             
	Error_Handler,
	Assert_Failed
};

/* Private function prototypes------------------------------------------------*/      

/*
	* @name   Run
	* @brief  系统运行
	* @param  None
	* @retval None      
*/
static void Run()
{
	HAL_Delay(500);
	LED.LED_Flip(LED1);
	LED.LED_Flip(LED2);
}

/*
	* @name   Error_Handler
	* @brief  系统错误处理
	* @param  None
	* @retval None      
*/
static void Error_Handler()
{
	/* User can add his own implementation to report the HAL error return state */
}

/*
	* @name   Assert_Failed
	* @brief  函数参数错误处理
	* @param  None
	* @retval None      
*/
static void Assert_Failed()
{
	/* User can add his own implementation to report the file name and line number,
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
}

状态机思想

流水灯状态机结构示意图

// 状态机.h文件
#ifndef __STA_machine_H_
#define __STA_machine_H_

#include "MyApplication.h"

//定义枚举类型:定义两个状态
typedef enum
{
	STA1 = (uint8_t) 0x01,
	STA2 = (uint8_t) 0x02,
	STA3 = (uint8_t) 0x03,
	STA4 = (uint8_t) 0x04,
	
}STA_Machine_Status_t;

// 定义结构体类型:每一个状态里面都有一个函数执行
typedef struct
{
	STA_Machine_Status_t ucSTA_Machine_Status; // 状态机状态:用于切换状态机
	void (*Fun_STA1)(void);
	void (*Fun_STA2)(void);
	void (*Fun_STA3)(void);
	void (*Fun_STA4)(void);
}STA_Machine_t;

// 外部声明:用于System文件的调用
extern STA_Machine_t STA_Machine;

#endif


// 状态机.c文件

#include "MyApplication.h"

/* Private define-------------------------------------------------------------*/

/* Private variables----------------------------------------------------------*/
static void Fun_STA1(void);
static void Fun_STA2(void);
static void Fun_STA3(void);
static void Fun_STA4(void);
/* Public variables-----------------------------------------------------------*/
STA_Machine_t STA_Machine = 
{
	STA1, // 初试默认为状态1
	Fun_STA1,
	Fun_STA2,	
	Fun_STA3,
	Fun_STA4,	
};

/* Private function prototypes------------------------------------------------*/  
void Fun_STA1()
{
	HAL_Delay(500);
	LED.LED_Flip(LED1); // 灭灯
	LED.LED_Flip(LED2); // 灭灯
	
	//切换到状态2
	STA_Machine.ucSTA_Machine_Status = STA2;
}

void Fun_STA2()
{
	HAL_Delay(500); // 延时500ms:条件
	LED.LED_ON(LED1); // LED1亮
	LED.LED_OFF(LED2); // LED2灭
	
	//切换到状态3
	STA_Machine.ucSTA_Machine_Status = STA3;
}

void Fun_STA3()
{
	HAL_Delay(500); // 延时500ms:条件
	LED.LED_OFF(LED1); // LED1灭
	LED.LED_ON(LED2); // LED2亮
	
	//切换到状态4
	STA_Machine.ucSTA_Machine_Status = STA4;
}

void Fun_STA4()
{
	HAL_Delay(500); // 延时500ms:条件
	LED.LED_ON(LED1); // LED1亮
	LED.LED_ON(LED2); // LED2亮
	
	//切换到状态1
	STA_Machine.ucSTA_Machine_Status = STA1;
}


// 运行函数

static void Run()
{
	switch(STA_Machine.ucSTA_Machine_Status)
	{
		case STA1: STA_Machine.Fun_STA1(); break;
		case STA2: STA_Machine.Fun_STA2(); break;
		case STA3: STA_Machine.Fun_STA3(); break;
		case STA4: STA_Machine.Fun_STA4(); break;
		default: STA_Machine.ucSTA_Machine_Status  = STA1;
	}
}

// 主函数
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "MyApplication.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
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();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

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

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */
	MyInit.Peripheral_Set();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
			System.Run();
  /* USER CODE END 3 */
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_39903708/article/details/108437698