(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

相关文章

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

mysql中的服务器架构详解

《mysql中的服务器架构详解》:本文主要介绍mysql中的服务器架构,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、mysql服务器架构解释3、总结1、背景简单理解一下mysqphpl的服务器架构。2、mysjsql服务器架构解释mysql的架

MySQL中的表连接原理分析

《MySQL中的表连接原理分析》:本文主要介绍MySQL中的表连接原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、环境3、表连接原理【1】驱动表和被驱动表【2】内连接【3】外连接【4编程】嵌套循环连接【5】join buffer4、总结1、背景

SQLite3 在嵌入式C环境中存储音频/视频文件的最优方案

《SQLite3在嵌入式C环境中存储音频/视频文件的最优方案》本文探讨了SQLite3在嵌入式C环境中存储音视频文件的优化方案,推荐采用文件路径存储结合元数据管理,兼顾效率与资源限制,小文件可使用B... 目录SQLite3 在嵌入式C环境中存储音频/视频文件的专业方案一、存储策略选择1. 直接存储 vs

嵌入式数据库SQLite 3配置使用讲解

《嵌入式数据库SQLite3配置使用讲解》本文强调嵌入式项目中SQLite3数据库的重要性,因其零配置、轻量级、跨平台及事务处理特性,可保障数据溯源与责任明确,详细讲解安装配置、基础语法及SQLit... 目录0、惨痛教训1、SQLite3环境配置(1)、下载安装SQLite库(2)、解压下载的文件(3)、

解析C++11 static_assert及与Boost库的关联从入门到精通

《解析C++11static_assert及与Boost库的关联从入门到精通》static_assert是C++中强大的编译时验证工具,它能够在编译阶段拦截不符合预期的类型或值,增强代码的健壮性,通... 目录一、背景知识:传统断言方法的局限性1.1 assert宏1.2 #error指令1.3 第三方解决

python中Hash使用场景分析

《python中Hash使用场景分析》Python的hash()函数用于获取对象哈希值,常用于字典和集合,不可变类型可哈希,可变类型不可,常见算法包括除法、乘法、平方取中和随机数哈希,各有优缺点,需根... 目录python中的 Hash除法哈希算法乘法哈希算法平方取中法随机数哈希算法小结在Python中,

Java Stream的distinct去重原理分析

《JavaStream的distinct去重原理分析》Javastream中的distinct方法用于去除流中的重复元素,它返回一个包含过滤后唯一元素的新流,该方法会根据元素的hashcode和eq... 目录一、distinct 的基础用法与核心特性二、distinct 的底层实现原理1. 顺序流中的去重

从入门到精通MySQL 数据库索引(实战案例)

《从入门到精通MySQL数据库索引(实战案例)》索引是数据库的目录,提升查询速度,主要类型包括BTree、Hash、全文、空间索引,需根据场景选择,建议用于高频查询、关联字段、排序等,避免重复率高或... 目录一、索引是什么?能干嘛?核心作用:二、索引的 4 种主要类型(附通俗例子)1. BTree 索引(

Redis 配置文件使用建议redis.conf 从入门到实战

《Redis配置文件使用建议redis.conf从入门到实战》Redis配置方式包括配置文件、命令行参数、运行时CONFIG命令,支持动态修改参数及持久化,常用项涉及端口、绑定、内存策略等,版本8... 目录一、Redis.conf 是什么?二、命令行方式传参(适用于测试)三、运行时动态修改配置(不重启服务