(mcu) 嵌入式基础简单入门(程序架构分析)

2024-08-27 09:52

本文主要是介绍(mcu) 嵌入式基础简单入门(程序架构分析),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 💽前言
  • 💽软件框架
    • 📀工具环境
    • 📀模板工程
    • 📀编译后
    • 📀Code
    • 📀典例举例
  • 💽Keil 使用notes
  • ⭐END
    • 🌟关注我

💽前言

本文为一份简单入门笔记,以 stm32 单片机为例。

**声明:**由于笔者不是专业人员,仅作为入门初学者,因此本文避免不了的有专业性错误,请自行甄别。

完全以一位纯应用型软件工程师的角度进行学习和思考。

嵌入式软件还是遵循软件的本质:基于下层的支持为上层提供应用服务。

只是我们目前互联网上的大多数软件是基于操作系统或者虚拟机或解释器等等基础。

而单片机是直接操作硬件,是直接基于硬件提供的功能。

💽软件框架

**声明:**本文以软件架构分析为核心。

📀工具环境

关键和工具不是本文重点。

基于 STM32CubeMX 图形化配置硬件。

使用 Keil 进行软件开发。

📀模板工程

使用 CubeMX 生成的框架架构

工程名:20240824

  • .ioc & .mxproject
    • CubeMX 工程文件
  • Core
    • 硬件信息生成的代码框架
    • 特别注意 system_stm32f4xx.c 在 Keil 中是显示在 Drivers 文件夹中
  • Drivers
    • 具体对应硬件的驱动代码
      • CMSIS
        - 基于硬件芯片原厂架构的文件(基于芯片的最底层)
        - STM32 xxx
        - 基于 CMSIS 的二次开发
        - 一般属于暴露给用户开发的接口
  • MDK-ARM
    • .uvprojx & .uvoptx
      • 对用 Keil 的工程文件
    • startup_stm32f407xx .s
      • 默认配置的汇编文件
C:.
│  .mxproject
│  20240824.ioc
│  
├─Core
│  ├─Inc
│  │      gpio.h
│  │      main.h
│  │      stm32f4xx_hal_conf.h
│  │      stm32f4xx_it.h
│  │      
│  └─Src
│          gpio.c
│          main.c
│          stm32f4xx_hal_msp.c
│          stm32f4xx_it.c
│          system_stm32f4xx.c
│          
├─Drivers
│  ├─CMSIS
│  │  ├─Core
│  │  ├─Core_A
│  │  ├─DAP
│  │  ├─Device
│  │  ├─Documentation
│  │  ├─DSP
│  │  ├─Include
│  │  ├─NN
│  │  ├─RTOS
│  │  └─RTOS2
│  │       LICENSE.txt
│  └─STM32F4xx_HAL_Driver
│              
└─MDK-ARM20240824.uvoptx20240824.uvprojxstartup_stm32f407xx.s

📀编译后

在编译后会在 MDK-ARM 文件夹下生成编译的中间文件:

其中 20240824 是项目名。其中同名文件夹下的是最核心的中间文件,其中包含可烧文件

C:.
│  20240824.uvguix.windows
│  20240824.uvoptx
│  20240824.uvprojx
│  startup_stm32f407xx.lst
│  startup_stm32f407xx.s
│
├─20240824
│
├─DebugConfig
│
└─RTE

可烧入文件

  • axf:包含数据,地址,代码,debug调试等信息,可以用下载器直接烧到板子上

  • hex:包含数据,地址信息

  • bin:包含数据(最终都是转到bin)

因此一般文件大小为 .bin < .hex < .axf

在这里插入图片描述

📀Code

注意:由于是使用 CubeMX 生成的,因此可能后续会有硬件的修改,因此 CubeMX 会在代码中注入注释表示。

即在下面形式的代码区间内编写代码才不会被下次重新生成框架代码所移除。

/* USER CODE BEGIN Includes */
// 自己的代码
/* USER CODE END Includes */

但由于本文是初学的学习笔记,因此本篇文章中展示的内容无视该规则。

main

下面是 main 的主题逻辑,核心就是 初始化-服务轮询 架构。

int main(void) {/*** Reset of all peripherals, Initializes the Flash interface and the Systick.* 重置所有外设,初始化Flash接口和系统棒。* =========================================================================* hal是stm32的三种不同应用库的一种**/HAL_Init();/*** Configure the system clock* 配置系统时钟* ==========================* 系统(硬件)总体(所有)的时钟* 相关的配置和初始化,相当于一个总开关* 保证芯片是正常能跑起来的*/SystemClock_Config();/*** Initialize all configured peripherals* 初始化所有配置的外设* =====================================* 在 CubeMX 中进行配置的外设专门的定制化初始化* 如:定时器,串口等*/MX_GPIO_Init();MX_TIM1_Init();MX_USART1_UART_Init();MX_USART2_UART_Init();/* USER CODE BEGIN 2 *//*** 业务代码* 一般为业务的初始化*/myservice_init();/*** 执行 while(1) 轮询* 一般为业务的状态机*/while (1) {myservice_state();}
}

中断

stm32f4xx_it.c/h 文件中,是中断处理的函数,如下面的形式:

#ifndef __STM32F4xx_IT_H
#define __STM32F4xx_IT_H#ifdef __cplusplus
extern "C" {
#endifvoid NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
void BusFault_Handler(void);
void UsageFault_Handler(void);
void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
void USART2_IRQHandler(void);#ifdef __cplusplus
}
#endif#endif /* __STM32F4xx_IT_H */

MDK-ARM/startup_stm32f407xx.s 文件中可看到映射,也就是说这些是框架直接帮我们做了,不用我们考虑链接的问题。

__Vectors       DCD     __initial_sp               ; Top of StackDCD     Reset_Handler              ; Reset HandlerDCD     NMI_Handler                ; NMI HandlerDCD     HardFault_Handler          ; Hard Fault HandlerDCD     MemManage_Handler          ; MPU Fault HandlerDCD     BusFault_Handler           ; Bus Fault HandlerDCD     UsageFault_Handler         ; Usage Fault HandlerDCD     0                          ; ReservedDCD     0                          ; ReservedDCD     0                          ; ReservedDCD     0                          ; ReservedDCD     SVC_Handler                ; SVCall HandlerDCD     DebugMon_Handler           ; Debug Monitor HandlerDCD     0                          ; ReservedDCD     PendSV_Handler             ; PendSV HandlerDCD     SysTick_Handler            ; SysTick Handler

📀典例举例

通过 MX_GPIO_Init() 了解嵌入式的本质,就是配置硬件操作。

void MX_GPIO_Init(void) {GPIO_InitTypeDef GPIO_InitStruct = {0};/*** GPIO Ports Clock Enable* GPIO端口时钟使能* ======================* 开了C H A 三个组的时钟* 仅是启动open,还没用* 如果没开,即使下面初始化成功了,硬件还是没反应*/__HAL_RCC_GPIOC_CLK_ENABLE();__HAL_RCC_GPIOH_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();/*** Configure GPIO pin Output Level* 配置GPIO引脚输出电平* ================================* GPIOC           引脚*组*的地址(C组)* GPIO_PIN_14     引脚号* GPIO_PIN_RESET  表示低电平*/HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14, GPIO_PIN_RESET);/*** Configure GPIO pin : PC14* 配置GPIO引脚:PC14* =========================* 配置这个引脚的基本参数*/GPIO_InitStruct.Pin   = GPIO_PIN_14;GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull  = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}

然后具体的业务操作,一个典型的应用就是:

  • myservice_init(); 对串口的buffer进行初始化,

  • myservice_state(); 对缓冲区进行状态机的处理。

这段数据业务逻辑,不做具体展示了。一般来说串口接受数据就是靠上文中介绍的中断函数。(当然也有办法不通过中断操作)

💽Keil 使用notes

添加头文件路径

默认配置下是无头文件相关的内容的

在这里插入图片描述

添加头文件

在这里插入图片描述

字符集设置

在这里插入图片描述

添加一个组

这个组是只针对工程,而不是外部的具体文件和文件夹(不会自动识别)

在这里插入图片描述

配置烧写器

在这里插入图片描述




⭐END

🌟关注我

关注我,学习更多C/C++,算法,计算机知识

B站:

👨‍💻主页:天赐细莲 bilibili

这篇关于(mcu) 嵌入式基础简单入门(程序架构分析)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1111331

相关文章

python获取指定名字的程序的文件路径的两种方法

《python获取指定名字的程序的文件路径的两种方法》本文主要介绍了python获取指定名字的程序的文件路径的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 最近在做项目,需要用到给定一个程序名字就可以自动获取到这个程序在Windows系统下的绝对路径,以下

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

从入门到精通详解Python虚拟环境完全指南

《从入门到精通详解Python虚拟环境完全指南》Python虚拟环境是一个独立的Python运行环境,它允许你为不同的项目创建隔离的Python环境,下面小编就来和大家详细介绍一下吧... 目录什么是python虚拟环境一、使用venv创建和管理虚拟环境1.1 创建虚拟环境1.2 激活虚拟环境1.3 验证虚

从基础到高级详解Python数值格式化输出的完全指南

《从基础到高级详解Python数值格式化输出的完全指南》在数据分析、金融计算和科学报告领域,数值格式化是提升可读性和专业性的关键技术,本文将深入解析Python中数值格式化输出的相关方法,感兴趣的小伙... 目录引言:数值格式化的核心价值一、基础格式化方法1.1 三种核心格式化方式对比1.2 基础格式化示例

redis-sentinel基础概念及部署流程

《redis-sentinel基础概念及部署流程》RedisSentinel是Redis的高可用解决方案,通过监控主从节点、自动故障转移、通知机制及配置提供,实现集群故障恢复与服务持续可用,核心组件包... 目录一. 引言二. 核心功能三. 核心组件四. 故障转移流程五. 服务部署六. sentinel部署

Python 基于http.server模块实现简单http服务的代码举例

《Python基于http.server模块实现简单http服务的代码举例》Pythonhttp.server模块通过继承BaseHTTPRequestHandler处理HTTP请求,使用Threa... 目录测试环境代码实现相关介绍模块简介类及相关函数简介参考链接测试环境win11专业版python

从基础到进阶详解Python条件判断的实用指南

《从基础到进阶详解Python条件判断的实用指南》本文将通过15个实战案例,带你大家掌握条件判断的核心技巧,并从基础语法到高级应用一网打尽,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录​引言:条件判断为何如此重要一、基础语法:三行代码构建决策系统二、多条件分支:elif的魔法三、

Python WebSockets 库从基础到实战使用举例

《PythonWebSockets库从基础到实战使用举例》WebSocket是一种全双工、持久化的网络通信协议,适用于需要低延迟的应用,如实时聊天、股票行情推送、在线协作、多人游戏等,本文给大家介... 目录1. 引言2. 为什么使用 WebSocket?3. 安装 WebSockets 库4. 使用 We

Java List 使用举例(从入门到精通)

《JavaList使用举例(从入门到精通)》本文系统讲解JavaList,涵盖基础概念、核心特性、常用实现(如ArrayList、LinkedList)及性能对比,介绍创建、操作、遍历方法,结合实... 目录一、List 基础概念1.1 什么是 List?1.2 List 的核心特性1.3 List 家族成

基于Python编写自动化邮件发送程序(进阶版)

《基于Python编写自动化邮件发送程序(进阶版)》在数字化时代,自动化邮件发送功能已成为企业和个人提升工作效率的重要工具,本文将使用Python编写一个简单的自动化邮件发送程序,希望对大家有所帮助... 目录理解SMTP协议基础配置开发环境构建邮件发送函数核心逻辑实现完整发送流程添加附件支持功能实现htm