[STM32]:如何快速启动STM32单片机毕设-Keil5-标准库(小白上手指南)

[LOGO]:CoreKSets

           【核知坊】:释放青春想象,码动全新视野。          

            我们希望使用精简的信息传达知识的骨架,启发创造者开启创造之路!!!          

由于 Koro 能力有限,文中难免出现错误,如有发现请在评论区指出,Koro 看到后会尽快调整!!!


内容摘要你是否是即将毕业的电子与信息工程专业接班人?你的毕业设计是否与单片机相关?面对选题是否毫无头绪,无从下手?如果你正被这些问题困扰,不妨看看这篇文章。本文专为初涉嵌入式开发的你而撰写,围绕"如何快速启动一个 STM32 裸机项目"展开,帮助你理清开发流程、打开思路。无论你刚接触 STM32,还是在项目启动阶段卡壳,这里都能为你提供一个清晰的起点。看完这篇文章,你将不再迷茫,能够迅速进入毕业设计状态,迈出关键的第一步,甚至今晚都能睡个好觉 —— 因为你终于知道明天该干什么了。

关键词:STM32 Keil5 毕业设计 C语言


其他相关文章:

⛏正在赶稿中....


1.STM32裸机开发一般流程图


STM32裸机开发一般流程图
STM32裸机开发一般流程图

        一个以 main.c 为核心的、由多个 .c.h 文件组成的“网状结构”工程 → 经由 编译器和链接器 处理,生成机器能够识别的 二进制文件(如 .hex.bin) → 通过下载器 烧录到 STM32 芯片中,最终让芯片运行你的程序。

2.直入主题【以STM32F103型号,标准库为例】

2.1 前期准备

        开题报告已经可以看出你毕设基本需求了,需求要明确,有什么限制条件,完成什么样的功能。根据需求选择合适的STM32型号,大部分项目使用STM32F103系列就足够了。最常见的就是使用STM32最小系统板与传感器连接,完成完整的系统。

2.2 资料查找

参考论文,常用软件,模块资料,教程等。硬件最好准备齐全,方便直接进行调试。

  • 电商客服 ⭐⭐⭐⭐ -------------找到相关店铺,直接问有没有xxx资料

  • AI + 浏览器 ⭐⭐⭐ -------------找下载资源,文章

  • 哔哩哔哩 ⭐⭐⭐ -------------评论区有宝藏

  • github|gitee|gitcode ⭐⭐⭐ -----------找项目必备

  • 直接买 ⭐⭐ -------------有风险需谨慎

  • 微信搜索 ⭐⭐ -------------公众号白嫖

  • QQ xxx交流群 ⭐ -------------大佬们,有xxx资料吗

  • 其他渠道(如野火官网)⭐ ⭐ ⭐

小技巧:访问不了的网站可以尝试搜索xxx镜像站,例如谷歌学术镜像站。

2.3 Keil5安装

        B站视频教程,海量博客教学文章都可以找到。也就这几步:下载破解版安装包->安装固件库包->破解软件->打开软件并熟悉功开发界面。凡是从客服那获取的与硬件有关的网盘资料里大概率包含Keil5安装包,如果没有就多问几家吧,也可以去野火官网获取。安装CH340串口驱动与其他驱动--------驱动是一个可以识别与操控硬件的软件。

2.4 STM32基本知识

系统时钟:有节奏的滴答器,这是芯片正常运行必备前提。没了时钟,就像人没了心脏。

  • HSI: 内部高速时钟,8MHz,芯片内置,可以作为时钟源头

  • HSE:外部晶振,一般也是 8MHz,需要芯片引脚连接接晶振电路,在芯片外面,可以作为时钟源头

  • PLL:倍频器,放大频率(Hz),比如 HSE ×9 → 72MHz,芯片内部电路,可以人为配置;

  • PRE: 分频器,将某个频率源挑选过滤(除法),降低频率(Hz),芯片内部电路,可以人为配置;

  • System Clock(SYSCLK):真正驱动 MCU 运行的主时钟;

    system_stm32f10x.c 内配置,大约在110行代码处,或者自定义系统时钟初始化函数。

 #if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
 /* #define SYSCLK_FREQ_HSE    HSE_VALUE */
  #define SYSCLK_FREQ_24MHz  24000000
 #else
 /* #define SYSCLK_FREQ_HSE    HSE_VALUE */
 /* #define SYSCLK_FREQ_24MHz  24000000 */ 
 /* #define SYSCLK_FREQ_36MHz  36000000 */
 /* #define SYSCLK_FREQ_48MHz  48000000 */
 /* #define SYSCLK_FREQ_56MHz  56000000 */
 #define SYSCLK_FREQ_72MHz  72000000
 #endif

BUS总线:许多电线,用来传递时钟,数据等信息到各模块,就像人的血管一样,蔓延到手,脚。

中断: 临时打断正在运行的程序,运行完中断函数,返回打断的位置继续运行。就像你在开黑打游戏,你妈突然叫你去洗碗,洗完继续开黑。中断可以嵌套,比如洗碗的时候,你爷爷叫你帮他开电视,开完电视继续洗碗。----------中断函数是有限个的已经被声明了,你要做的只是填充中断函数里内容。

startup_stm32f10x_hd.s 文件里有全部中断函数名,以XXXX_IRQHandler 固定命名形式,一般在stm32f10x_it.c 里编辑,或者写到编译器找得到的自定义文件里。

 // 串口中断服务函数
 void USART_IRQHandler(void)
 {
   uint8_t ucTemp;
     if(USART_GetITStatus(USARTx,USART_IT_RXNE)!=RESET)
     {       
         ucTemp = USART_ReceiveData(USARTx);
     USART_SendData(USARTx,ucTemp);    
     }    
 }

GPIO:可以读电平/输电平的引脚,是芯片和外界的接口,可以用眼睛看到。

外设: MCU 自带的功能模块,电路在芯片里面,外的意思是指这些模块在 ARM Cortex-M(大脑) 核心外部。

常用外设:

外设通俗功能
USART串口通信,打印调试信息、连接蓝牙
SPI高速通信,连接 OLED 屏、Flash
I2C简洁通信,读取温湿度传感器
ADC模拟→数字,读取电压、传感器信号
DAC数字→模拟,比如音频输出
PWM(定时器)控制舵机、电机转速、LED 亮度,实质控制平均电压大小
RTC内置时钟模块
DMA数据高速搬运,绕过CPU,直达快车
Time精确定时器,指定一些定时操作,就像闹钟提醒干活
看门狗异常死机,自动重启机制

2.5 C语言基础

        为了能基本看懂代码,只需要了解常见的C语言语法即可,寄存器什么的看看就行,因为标准库已经把操作寄存器的函数都准备好了,直接用就好。下面的语法需要注意,如果不理解,请参考结尾章节使用AI学习:

语法通俗简介示例
变量定义给数据起个名字,用来存值int a = 5;
函数定义与调用,声明定义一个动作/功能,方便重复使用void LED_On(void) { GPIO_SetBits(GPIOA, GPIO_Pin_0); }
条件判断根据不同条件执行不同的代码块if (a > 0) { do_something(); } else { do_other(); }
循环语句重复执行一段代码for(int i=0; i<10; i++) { LED_Toggle(); }
数组一组相同类型的变量,按顺序排列int arr[5] = {1,2,3,4,5};
指针存储变量地址的变量,可用于间接访问或传递大数据int *p = &a; *p = 10;
结构体将多个变量打包成一个整体GPIO_InitTypeDef GPIO_InitStructure;
宏定义类似替换文本的快捷方式,常用于命名常量或简化代码#define LED_PIN GPIO_Pin_0
头文件引用导入需要使用函数/定义/结构体等#include "stm32f10x_gpio.h"
强制类型转换把一种数据类型“临时伪装”成另一种类型(uint32_t)0x40010800
结构体指针访问通过指针访问结构体成员,用于控制外设USART1->SR & USART_FLAG_TXE

在项目里,我们经常创建的文件就是 .c 和 .h两种文件,它俩可以看成一对:

📌 .h 就像“菜单目录”,告诉别人有哪些菜(功能)可以用;

📌 .c 就是“厨房操作”,是真正做菜的地方(实现细节)!

文件类型通俗解释主要内容
.h 文件说明书 / 接口定义文件函数声明、宏定义、结构体、引脚名等
.c 文件功能实现 / 实际代码逻辑函数的具体实现、变量定义、底层操作等

led.h

 #ifndef __LED_H
 #define __LED_H
 ​
 // 宏定义:定义引脚/端口
 #define LED_PORT GPIOA
 #define LED_PIN  GPIO_Pin_0
 ​
 // 函数声明:告诉使用者有哪些函数可以使用,这些函数必须在 led.c 里实现
 void LED_Init(void);
 void LED_On(void);
 void LED_Off(void);
 ​
 #endif
led.c
 #include "led.h" // 包含头文件
 ​
 void LED_Init(void) {
     // 配置 GPIO 引脚
     GPIO_InitTypeDef GPIO_InitStruct;
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
     GPIO_InitStruct.GPIO_Pin = LED_PIN;
     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(LED_PORT, &GPIO_InitStruct);
 }
 ​
 void LED_On(void) {
     GPIO_ResetBits(LED_PORT, LED_PIN);
 }
 ​
 void LED_Off(void) {
     GPIO_SetBits(LED_PORT, LED_PIN);
 }
 ​为了防止重复包含错误,我们会定义一个常量避免重复定义:
 #ifndef __LED_H
 #define __LED_H
 ​
 //代码
 ​
 #endif

2.6 常用 Keil5 面板功能

常用快捷键:

快捷键功能说明
Ctrl + F7编译整个项目
Ctrl + S保存当前文件
Ctrl + F查找关键字
右键+Go To xxxx跳转查看某变量,函数源码
Ctrl + 滚轮字体放大,缩小

编译:,每次改动代码需要下载调试之前,必须编译

新建/打开/保存 :

程序下载到芯片:,需要使用Keil5能识别的烧录器

项目配置: ,魔术棒,主要选芯片型号,输出文件,.h 文件路径配置,下载器配置(可选)

选芯片:

输出文件:

C语言配置:

下载器配置:

常见下载方式:

下载方式接口类型是否需要 BootLoader常用工具特点说明
JTAG/SWD调试接口❌ 不需要ST-Link Utility、Keil✅最常用方式,支持下载+调试,速度快,可靠性高
串口下载(USART)串口(如 PA9/PA10)✅ 需要芯片内置 BootLoaderFlyMcu .bin文件✅适合没有调试器时使用,需设置Boot0=1, Boot1=0
仿真器下载J-Link、ST-LinkKeil、J-Flash 等商业版仿真器功能强大,支持更多芯片

2.7 观察项目文件结构

        大部分标准库项目都与上面相似,USER下的可以自定义修改文件内容,其他文件夹里的stm32fxxx_xxx形式的文件(标准库源文件)最好不要动,需要的时候打开看就行。什么时候看,看什么?需要使用STM32资源时直接调用标准库内置函数,看函数参数,功能注释,结构体内容,常量。

        上图的每个文件都代表 STM32 的一个外设或功能集合,例如需要使用 SPI外设连接一个 LCD 屏幕。你先做的是根据 STM32 参考手册找到有哪几个 SPI,选择一个合适的 SPI。查找它复用的是哪些引脚,按照引脚功能用杜邦线看引脚名称连接好 LCD 屏幕,然后查看SPI需要的引脚特性准备写代码。比如我们使用 SPI1 :

SPI 引脚功能对应引脚方向推荐 GPIO 模式说明
SCKPA5输出复用推挽输出(AF_PP)SPI 时钟线,主机输出
MISOPA6输入浮空输入(IN_FLOATING)主机输入,从机输出的数据线
MOSIPA7输出复用推挽输出(AF_PP)主机输出,从机输入的数据线
NSSPA4(可选)输出/输入推挽输出 / 浮空输入可选:软件控制片选,或硬件控制时配置为输入

2.8 编写代码

创建自定义 .c 和 .h 文件,项目里引入 .c。配置号魔术棒里的 C/C++ 选项卡 Include Paths选项添加 .h 文件父文件夹,目的是让编译器找到这个文件。(文件夹已经添加过的,可以不再配置)

初始化代码按照以下顺序编写:

步骤内容说明
开启外设时钟 stm32f10x_rcc.hRCC_APB2PeriphClockCmd(),外设没时钟就无法工作
配置 GPIO 引脚模式 stm32f10x_gpio.h设置为复用推挽输出、浮空输入等模式
编写外设初始化结构体参数 stm32f10x_spi.h设置外设的工作模式(主/从、时序等)
调用初始化函数初始化外设寄存器,完成配置
使能外设启动外设,准备通信
编写发送/接收函数(或使用中断/DMA)stm32f10x_exti.h根据需求使用轮询、中断或 DMA(可选)

SPI相关的内置函数直接可以看 stm32f10x_spi.h 底部函数声明:

 /** @defgroup SPI_Exported_Functions
   * @{
   */
 ​
 void SPI_I2S_DeInit(SPI_TypeDef* SPIx);
 void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct);
 void I2S_Init(SPI_TypeDef* SPIx, I2S_InitTypeDef* I2S_InitStruct);
 void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct);
 void I2S_StructInit(I2S_InitTypeDef* I2S_InitStruct);
 void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState);
 void I2S_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState);
 void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState);
 void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState);
 void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data);
 uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx);
 void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft);
 void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState);
 void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize);
 void SPI_TransmitCRC(SPI_TypeDef* SPIx);
 void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState);
 uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC);
 uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx);
 void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction);
 FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
 void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
 ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);
 void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);

要看具体信息可以右键+GoTo跳转到 stm32f10x_spi.c 的实现位置:

 
/** @defgroup SPI_Private_Functions
   * @{
   */
 ​
 /**
   * @brief  Deinitializes the SPIx peripheral registers to their default
   *         reset values (Affects also the I2Ss).
   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
   * @retval None
   */
 void SPI_I2S_DeInit(SPI_TypeDef* SPIx)
 {
   /* Check the parameters */
   assert_param(IS_SPI_ALL_PERIPH(SPIx));
 ​
   if (SPIx == SPI1)
   {
     /* Enable SPI1 reset state */
     RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, ENABLE);
     /* Release SPI1 from reset state */
     RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, DISABLE);
   }
   else if (SPIx == SPI2)
   {
     /* Enable SPI2 reset state */
     RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE);
     /* Release SPI2 from reset state */
     RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, DISABLE);
   }
   else
   {
     if (SPIx == SPI3)
     {
       /* Enable SPI3 reset state */
       RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE);
       /* Release SPI3 from reset state */
       RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, DISABLE);
     }
   }
 }

看不懂的,直接AI生成(配置代码非常成熟,但需要根据需求微调):我现在需要使用 STM32F103C8T6 的 SPI1 与一个 LCD 通信,帮我编写C语言,Keil5, 标准库初始化代码。

#include "stm32f10x.h"
 void SPI1_Init(void) {
     GPIO_InitTypeDef GPIO_InitStructure;
     SPI_InitTypeDef  SPI_InitStructure;
 ​
     // 开启 GPIOA 和 SPI1 的时钟
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1, ENABLE);
 ​
     // 配置 SCK (PA5) 和 MOSI (PA7) 为复用推挽输出
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(GPIOA, &GPIO_InitStructure);
 ​
     // 配置 MISO (PA6) 为浮空输入(可选,LCD 一般不用返回数据)
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
     GPIO_Init(GPIOA, &GPIO_InitStructure);
 ​
     // SPI1 配置:主机模式,8位数据,低电平空闲,1边沿采样
     SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // 全双工
     SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                      // 主模式
     SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                  // 8位数据
     SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;                         // 空闲时低电平
     SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;                       // 第一个时钟沿采样
     SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                          // 软件管理 NSS
     SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; // 分频系数,调整通信速度
     SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;                // 高位先传
     SPI_InitStructure.SPI_CRCPolynomial = 7;                          // CRC 多项式,默认即可
     SPI_Init(SPI1, &SPI_InitStructure);
 ​
     // 使能 SPI1
     SPI_Cmd(SPI1, ENABLE);
 }
 ​
 void SPI1_SendByte(uint8_t byte) {
     // 等待发送缓冲区空
     while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
     // 发送数据
     SPI_I2S_SendData(SPI1, byte);
     // 等待接收完成(也可省略)
     while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
     // 读取接收缓冲(清除标志位)
     (void)SPI_I2S_ReceiveData(SPI1);
 }
 ​

2.9 驱动文件(让模块运行起来)

        上一节的代码仅仅是初始化了 SPI 通信接口,这相当于只打通了和 LCD 通话的“电话线”。但 LCD 本身是一个复杂的显示模块,它内部有专用的驱动芯片,需要我们通过 SPI 发送一系列“特殊指令”来配置它,比如颜色格式、背景色、刷新方式、显示区域、睡眠模式等等。

        这些配置过程通常非常复杂,但你不用从零开始写。这些初始化代码早就有人帮你写好了! 通常会打包成一对文件,例如:LCD.c, LCD.h 。哪里找这些文件呢?电商客服!!!直接找你的卖家,问他要,没有就找它的同行,这些文件一般在例程项目文件夹里,名字非常显眼。

        文件准备好,就把它们当作新文件引入到项目了。然后直接复制粘贴里面的内容喂给AI,让他帮你解释,并更具自己的要求进行调整。你要在LCD实现什么功能,请直接使用LCD.h 声明的函数,不够的可以自定义。其底层逻辑就是(其他通信协议类似):用 SPI 发送特定格式的数据(通常来自 LCD 控制芯片的手册),间接控制 LCD 内部寄存器。不同寄存器决定 LCD 的不同行为,最后在屏幕上呈现出不同的效果。

2.10 编译报错怎么办?

        请将看不懂的错误直接发送给AI,他会帮你分析原因。但要注意不要被AI带偏,最好的编写习惯是,代码有些改动时,尽早编译,这样你可以提供更多的信息给AI。比如,我在xxx地方添加了xxx代码之后编译xxxx报错。

2.11 编译通过 0 错误,下载芯片后没有预期反应?

问题类型描述
🧠 程序逻辑错误死循环、分支跳转逻辑混乱,程序卡住或走错分支导致无输出
🔁 无限阻塞比如等待某个外设就绪,结果它永远没准备好,程序卡死在 while
🧹 内存操作错误指针未初始化、数组越界、内存越界写入等,容易引起死机或奇怪行为
⚙️ 初始化错误外设参数设置错了(如 SPI 时序、GPIO 模式配置错误),导致功能无响应
🔌 硬件接线问题电源、引脚未接好、LCD 或传感器没接上/接错,程序正常但看不到任何效果
🔍 输出未调试程序正常跑,但你没设置串口输出/LED 反馈,看不出运行状态,误以为出错了

2.12 调试必备程序

功能用处
Delay_ms模拟等待,常用于初始化等待
LED_Blink判断程序是否运行,调试必备
USART + printf串口输出信息,实时调试变量和状态


3. 如何使用浏览器与生成式AI解决你的STM32开发问题?


对于浏览器和AI两种工具,我的观点:

        浏览器搜索提供了广泛的信息来源,适用于探索性学习或需要多角度理解问题,获取最新数据、新闻、论坛和技术文档。但需要花时间筛选和辨别信息的相关性和可靠性,可能会遇到信息过载的情况。通常问题字数较少且会加上一些关键词(怎样xxx,xxx如何xxx,xxx怎么使用,什么是xxxx,为什么xxx,xxx会xxx......)。例如STM32如何下载程序,毕业设计弄不出来会延毕吗等,xxx传感器如何使用。

        AI是一种"浓缩版浏览器",它会将你的问题(前提是你的问题非常明确,字数挺多)不断精细化,使用某个专业领域的内容回答你,适合解决具体、明确的问题。它可以节省时间,提高效率,但也可能存在信息滞后或不准确的情况,尤其是在处理需要深入理解或创造性思维的问题。一般使用AI解决一些范围较小的问题,例如帮我规划xxx项目进度,如何解决C语言xxx报错,给我一个USART窗口调试程序,告诉我xxx代码功能,告诉我xxx函数如何使用。噢,对了,请在你提供的信息后面加上一段分隔符(-。.=),然后把要求写下来。例如xxxBUG(1000字符)------------------C语言报错,帮我解决;xxxxxx.............................以上是我提供的方案,请给我一些建议。

        每当你有一个问题,你最先做的应当是将问题分解并描述清晰。请记住以下问题表达建议,这其实是一个我经常使用的AI小公式,每次使用它都会加快我找到答案的速度,找不到的话只能自己减少关键词去浏览器搜索,或着问人:

发生时间(可选) + 问题场景 + 错误现象(可选) + 预期结果 + 已尝试的解决方法(可选) + 限制条件(可选)+指令

以下是一个示例:

  • (AI版)我是电子与信息专业的学生,我不知道如何开始我的毕设:基于单片机的个人健康助手的设计。目前我只准备好了一块STM32开发板,xxx型号心率传感器,xxx型号温度传感器,xxx型号重力传感器(问题场景)。我的系统需要完成这些功能:1.该设备需要放置在人的手臂上,需要接触皮肤 2.传感器数据需要通过数据线发送到电脑上显示 3.摔倒警报提示 4.心率,温度参数异常警报提升(预期结果)。老师要求我使用C语言和标准库编写程序(限制条件)。------------------------请根据我的情况帮我规划行动(指令)

  • (浏览器版)基于单片机的个人健康助手

4. 总结


        本文简单介绍了STM32单片机开发流程,Keil5基本使用方式,源码编写方式,常见问题解决方式,最后介绍了如何使用AI,浏览器解决开发中的任何问题。


感谢阅览,如果你喜欢该内容的话,可以点赞,收藏,转发。

由于 Koro 能力有限,有任何问题请在评论区内提出,Koro 看到后第一时间回复您!!!


其他精彩内容:

⛏正在赶稿中....


参考内容:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值