STM32中的shell框架搭建

STM32和电脑的关系

  • 可以将上位机给下位机发送的信息当做是控制命令
  • 下位机给上位机发送的信息当做是硬件本身的状态

初始化函数的优化

批量化调用同类型函数,有同样的数据类型,放一块 - 数组

定义一个数组, 函数指针数组, 数组中包含的都是一个一个的函数指针, 就是函数的首地址

|--LED_Init--|--BEEP_Init--|--UART_Init--|--...--|--....--|--0--|将近期所有的初始化函数放到一个数组里

回忆知识:函数指针:

C语言指针进阶(一)------深入详解"函数指针"与"指针函数"-CSDN博客

以下变量的类型:

|------------------|----------------|
| int a; | int |
| int* pa; | int* |
| int a[5]; | int [5] |
| int (*p)(void); | int (*)(void) |

小窍门:把定义中的变量名去除就是变量类型

objectivec 复制代码
    typedef  int (*p_t)(void);


	p_t arr[] = {LED_Init, BEEP_Init, UART_Init};

	for(int i = 0; i < 3; i++){
		p_t p;
		p = arr[i];
		p();
	}

代码实现

objectivec 复制代码
// @file init.h
#ifndef __INIT_H 
#define __INIT_H

#include "stm32f10x.h"

// 声明函数指针数据类型 
typedef void (*PINIT_T)(void);

// 声明全部硬件的初始化函数 
extern void DEVICE_Init(void);


#endif
objectivec 复制代码
// @file  init.c
#include "init.h"
#include "led.h"
#include "beep.h"
#include "systick.h"
#include "key.h"
#include "exti.h"
#include "uart.h"

// 定义函数指针数组, 存储所有初始化函数的首地址
static PINIT_T init_func[] = {
	LED_Init,			// led灯初始化
	BEEP_Init,		// beep初始化 
	Systick_init,	// 滴答定时器初始化
	KEY_Init,			// 按键初始化
	My_EXTI_Init,	// 中断初始化 
	UART_Init,		// 串口初始化 
	0
};

void DEVICE_Init(void)
{
	// pfunc存储数组首地址
	// pfunc存储数组下表为0存储区的首地址
	PINIT_T* pfunc = init_func;
	for(; *pfunc; pfunc++){
		(*pfunc)(); 
	}
}

可将原代码中的

objectivec 复制代码
	LED_Init(); // led灯的初始化
	BEEP_Init(); // BEEP的初始化
	Systick_init(); // 滴答定时器的初始化 
	KEY_Init();			// 按键的初始化
	My_EXTI_Init(); // EXTI初始化 

所有的初始化用init取代

objectivec 复制代码
DEVICE_Init();// 所有硬件的初始化

命令匹配优化

objectivec 复制代码
		// 字符串匹配 
		if(!strcmp(buf, "led on")){
			LED_On(); // 开灯 
			UART_Puts("LED ON");
		}else if(!strcmp(buf, "led off")){
			LED_Off(); // 关灯 
			UART_Puts("LED OFF");
		}else if(!strcmp(buf, "beep on")){
			BEEP_On(); // 打开蜂鸣器 
			UART_Puts("BEEP ON");
		}else if(!strcmp(buf, "beep off")){
			BEEP_Off(); // 关闭蜂鸣器 
			UART_Puts("BEEP OFF");
		}else{
			UART_Puts("invalid command\n");
		}
		UART_Puts("\n");

在main函数中,接收来自cpu发送的字符串进行判断,需要单个去进行匹配,这时候新建cmd.h和cmd.c专门优化这部分匹配,适配后期的匹配

cmd.h

objectivec 复制代码
#ifndef __CMD_H  
#define __CMD_H

#include "stm32f10x.h"

// 声明函数指针数据类型 
typedef void (*cb_t)(void); //这里需要注意对函数指针进行typedef的定义方法,而不是typedef void (* )(void) p_t

// 声明命令的数据类型 
typedef struct{
	char* name;
	cb_t callback; 
}cmd_t;

// 用于匹配函数 
extern cmd_t* find_cmd(char* name);//这里要注意返回的cmd_t类型的结构体,需要用地址来取


#endif

cmd.c

objectivec 复制代码
#include "cmd.h"
#include "led.h"
#include "beep.h"
#include "string.h"

// 定义描述所有命令的数组 
cmd_t cmd[] = {
	{"led on", LED_On},
	{"led off", LED_Off},
	{"beep on", BEEP_On},
	{"beep off", BEEP_Off}
};
// 获取数组长度 
#define  CMD_NUM(x)   (sizeof(x) / sizeof(x[0])) //使用宏的方式进行定义,方便后期调用

// 命令匹配函数 
// 参数 - 用户输入的操作命令 
// 和某个命令匹配成功, 需要传递给其它函数什么数据,可以直接调用对应的函数呢?
cmd_t* find_cmd(char* name)
{
	int i = 0;
	for(i = 0; i < CMD_NUM(cmd); i++){
		if(!strcmp(name, cmd[i].name))
			return &cmd[i];// 返回匹配成功命令的首地址
	} 
	
	return 0;
}

main.c

objectivec 复制代码
#include "stm32f10x.h"
#include "led.h"
#include "beep.h"
#include "system.h"
#include "systick.h"
#include "key.h"
#include "exti.h"
#include "uart.h"
#include "string.h"  // strcmp函数声明 
#include "init.h"
#include "cmd.h"


#define  BUF_LEN   128
static char buf[BUF_LEN]; // 定义数组存储从上位机读取到的字符串 
static cmd_t* pcmd;


int main(void){
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //--|--
	
	DEVICE_Init();// 所有硬件的初始化


	while(1){
		// 下位机->上位机:请输入命令 
		UART_Puts("please input your command:");
		// buf = "led on"/"led off"/"beep on"/"beep off"
		// 上位机发送的命令在buf数组中
		UART_Gets(buf, BUF_LEN); 
		
		// 命令匹配, 参数就是上位机输入的命令 
		pcmd = find_cmd(buf);
		if(pcmd != 0) // 匹配成功
			pcmd->callback(); // 调用对应的函数
		else
			UART_Puts("invalid command\n");
		UART_Puts("\n");
	}

}

实验效果

从上位机给下位机发送led on,STM32主板中的LED会亮,发送led off则会熄灭

相关推荐
森旺电子2 小时前
51单片机仿真摇号抽奖机源程序 12864液晶显示
单片机·嵌入式硬件·51单片机
不过四级不改名6774 小时前
蓝桥杯嵌入式备赛教程(1、led,2、lcd,3、key)
stm32·嵌入式硬件·蓝桥杯
小A1594 小时前
STM32完全学习——SPI接口的FLASH(DMA模式)
stm32·嵌入式硬件·学习
Rorsion4 小时前
各种电机原理介绍
单片机·嵌入式硬件
善 .7 小时前
单片机的内存是指RAM还是ROM
单片机·嵌入式硬件
超级码农ProMax7 小时前
STM32——“SPI Flash”
stm32·单片机·嵌入式硬件
Asa3198 小时前
stm32点灯Hal库
stm32·单片机·嵌入式硬件
end_SJ10 小时前
初学stm32 --- 外部中断
stm32·单片机·嵌入式硬件
gantengsheng11 小时前
基于51单片机和OLED12864的小游戏《贪吃蛇》
单片机·嵌入式硬件·游戏·51单片机
嵌入式小强工作室11 小时前
stm32 查找进硬件错误方法
stm32·单片机·嵌入式硬件