自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(60)
  • 收藏
  • 关注

原创 C++——指针与内存

就比如定义一个定长的数组,那么它的长度在编译阶段就已经决定好了,此为编译阶段决策,通常我们认为自己定义的长度已经足够满足程序的需要,但实际情况是时刻变化的,可能长度远远不够,也可能长度过长,前者导致安全问题,后者导致空间浪费。指针是一种存储地址的变量,长度固定,通过&获得常规变量的地址,又通过*解引用出对应地址处存储的值。不过,以上这些只是指针功能的冰山一角,看着花里胡哨,其实总结来说只是指针为这些已经有名称的内存空间取了别名,让程序员能够更方便地访问这些地址和里面的值,真正的重头戏还在后面。

2026-02-14 18:05:08 631

原创 C++——由数组到string类简介

代码中使用了get函数两种可用方式,不带任何参数的形式的get()可以读取下一个字符,因此用来处理换行符,它和带参的get函数可以分开写,也可以像第二种那样用“.”连着写,这是因为带参数的get最后还是返回了一个对象,相当于用返回的对象再次调用了一次无参的get函数。<>中填写的是后面包含变量的类型,而vt则是程序员取的vector对象的名称,至于()中的n,其实可有可无,因为vector对象会自动根据之后插入的值调整长度,即使不添加n,长度也会先默认为0。

2026-02-09 17:54:36 601

原创 C++——不一样的I/O工具与名称空间

例如,有两个已经封装好的产品,一个属于A厂商,一个属于B厂商,这两个产品同时包含一个叫做add的函数,如果不添加名称空间,那么编译器并不能分辨到底是用哪个版本。可以看到,cout使用了<<来进行信息输出操作,实际上,<<可以看作消息传输路径,它将双引号中的内容传输给了cout对象,而接下来的显示由cout内部进行,并不需要程序员进行操作。输出语句最后的endl是换行符,它的功能和C语言中的\n一样,当然我们也完全可以去掉endl,在双引号内使用我们熟知的\n进行换行,这种写法C++也是允许的。

2026-02-06 20:40:25 604

原创 C++引入——初印象

随着时代发展,C++也不断进行规范化,在1998年制定的C++98标准是国际标准的开山之作,而后经历多次改进修订,C++11标准又是C++语言一次重大革新,为C++引入了更多现代编程的概念。当然,学过C语言的小伙伴们都能体会到一点,就是C语言中好多的语法在C++中同样适用,但是后续文章并不会完全重复地讲述这些相同点,而是有选择地挑一些不一样的地方讲述。C++语言是由丹麦科学家Bjarne Stroustrup构想并设计的,译为“带有类的C”,而++体现了该语言是C语言的升级与拓展版。

2026-02-03 17:40:16 87 1

原创 嵌入式开发学习日志55——软件定时器

前面在聊stm32的时候就有提到过定时器模块,不过当时的属于是硬件定时器,它的特点就是精度高,而FreeRTOS自然也提供了相应的定时器模块,不过是标题中描述的软件定时器,虽然精度并没有硬件那么高,但是应付周期性处理的任务来说已经绰绰有余。FreeRTOS会根据当前系统时间和定时器设置的超时时间,把定时器放到一个列表里,当系统时间到达定时器的超时时间时,就会触发回调函数。可以说,软件定时器是嵌入式开发中一个常见的工具,它能让你的时间管理变得更加灵活和高效,虽然它精度不高,但是绝对好用,够用。

2026-02-02 19:11:58 119

原创 嵌入式开发学习日志54——事件

整个事件组存储在一个EventBits_t类型的变量当中,这种类型的位数由名为configUSE_16_BIT_TICKS的宏来决定,不过在stm32中,这个宏一般被设置为0,也就是说,变量是32位的,而其中的。对于某些会产生危险的机器操作,如果贸然进行很可能造成无法挽回的损失,因此可以通过事件对这个操作进行多重“保险”(逻辑与的应用)。之间的同步,而多任务系统可不止有着一种情况,一旦遇到单个任务需要同步多个其他任务,又或者多个任务同步多个任务时,信号量显然无法满足需求了,那么此时又该怎么办呢?

2026-01-31 19:40:49 122

原创 嵌入式开发学习日志53——互斥量

它的机制就是将占据某种资源的低优先级任务的优先级暂时抬高,提高到等待这个资源的高优先级任务的优先级,这样即使中途有中优先级任务就绪也无法抢占CPU,而当这个任务执行完释放资源后,优先级又会恢复到一开始的级别,此时高优先级任务就可以使用了。更糟糕的是,若在高优先级任务阻塞期间,有一个中优先级任务就绪,而这个任务还不需要用到这个资源,那么不好意思,这个低优先级任务要被打断,将CPU使用权交给中优先级任务。而我们知道,优先级这东西在一开始就已经定好,越重要越紧急的任务往往优先级就会越高,往往也会优先执行。

2026-01-30 17:36:34 314

原创 嵌入式开发学习日志52——二值与计数信号量

此时液晶屏就会有多次无效刷新,浪费CPU资源,那么就可以在温湿度传感器采集到数据并发送给液晶屏,数据到达时发一个二值信号量给液晶屏,使它正式工作,而在其他时间使它处于阻塞状态,这样就完成了两个任务间的同步。每个资源都可以设置一个最大任务数量,这些任务通过获取信号量来获取资源,而每取走一个信号量,计数减一,直到为0时,阻塞试图继续获取资源的任务,直到有其他任务释放信号量。之后任何任务都可以从二值信号量资源中获取一个二值信号量,获取成功则返回正确,获取失败,任务就会按照之前讲过的阻塞时间等待信号量的释放。

2026-01-28 19:14:41 314

原创 嵌入式开发学习日志51——FreeRTOS之消息队列

当任务尝试从队列中读取消息,那么就可以设置一个阻塞时间,这个阻塞时间并非队列的阻塞,而是任务等待提取消息时阻塞的时间,这叫做出队阻塞。队列中可以存储有限的数据,这些数据在队列中被称作队列项目,而一个队列所能存储的最大的数据项目的数量被称为队列长度,这是在创建队列的时候程序员需要自己设置的内容。在图中任务A眼中,队列的最末端是数据10要存储的位置,是队列的尾部。一般情况下,队列会采用FIFO(先进先出)的存储缓冲机制,也就是向队列发送消息时数据会进入队列的尾部,而从中取出数据时会从队列的头部提取。

2026-01-27 17:49:45 412

原创 嵌入式开发学习日志50——任务调度与状态

在前面提到,如果只是创建任务的话任务是执行不起来的,需要将其放入任务调度器中供系统调度,这样才能保证任务的执行,而任务调度的关键就在于vTaskStartScheduler()函数。SVC被称为系统服务调用,用于任务的启动,部分操作系统只允许用户间接访问硬件,此时就需要通过SVC向系统服务函数发出呼叫,系统的SVC异常服务例程执行后,完成用户的呼叫请求。细心的读者应该也发现了,我在前面几次提到过挂起这个词,其实这就是任务的状态之一,之前提到的任务就绪也属于任务状态的范畴。运行就是任务正在占用处理器。

2026-01-26 17:50:50 290

原创 嵌入式开发学习日志49——任务动态创建

DRAM的存储单元采用的是电容为基础的电路,由于电容的放电会导致里面存储的变量信息逐渐失去,一般在芯片上没有集成DRAM控制器的情况下,不会建议使用DRAM来存储重要的变量信息。这里就可以看出和静态创建的区别了。静态创建时,我们预先定义好了任务控制块,因此需要将该控制块的句柄(指针)传递给xTaskCreateStatic()函数,而在动态创建中,由于是系统给我们定义好了堆栈和控制块,xTaskCreate()最后会返回一个指向控制块的句柄,此时的控制块就是动态分配后的一块内存。使用动态内存时,会使用。

2026-01-25 12:16:50 179

原创 嵌入式开发学习日志48——任务静态创建

当然,上述展示的代码都并不足以完全支撑点灯这个简单操作,在开始任务任务函数start_Task()中,还需要将静态任务创建函数的内容在复写一遍,不过这次的任务入口与任务名称要真正改为用于执行点灯操作的任务函数了。注意,这里的延时都是FreeRTOS中的阻塞延时,通过它才能将执行的任务挂起(任务状态之一,后面会提到),转而执行其他已经就绪的任务,实现多任务。总之,即便是想要执行一个简单的操作,既要有开始任务任务函数,也要有执行任务任务函数,前者用于开启后者,后者真正进行执行。

2026-01-24 20:15:29 447

原创 嵌入式开发学习日志47——任务创建与就绪列表

在该函数中,会涉及pxTaskCode(任务的函数名称)、pcName(任务名称)、ulStackDepth(任务栈大小)、pvParameters(任务形参)、uxPriority(任务优先级)等的定义,具体在创建时()内的参量要写什么还需要根据创建的形式来定。在任务的控制块中有一个xStateListItem的成员,将任务插入到就绪列表中,实际上就是将这个成员节点插入其中,就像两个齿轮,一个代表列表,一个代表任务的控制块,而xStateListItem就是齿轮上的卡槽,令两者顺利嵌合并且正常运作。

2026-01-04 19:17:46 249

原创 嵌入式开发学习日志46——FreeRTOS之列表与列表项

当然,除了这两个成员外,普通列表项还有其他成员,例如记录列表项值的xItemValue,以及指向上一个和下一个列表项的pxPrevious和pxNext。从作用上看,其实迷你和普通列表项并没有太大区别,但是由于有时候并不需要列表项的所有功能,为了节省足够的空间,就会使用迷你列表项。而至于列表以及列表项的初始化以及插入等操作,这一部分的源码是十分复杂的,有兴趣的读者可以自行去查阅,就当看小说了,在这里就不多赘述。列表项就是存放在列表中的项目,可以分为普通列表项以及迷你列表项。

2026-01-03 20:06:01 204

原创 嵌入式开发学习日志45——FreeRTOS之任务

由于多任务系统之中,各个任务之间是相互独立的,所以给每个任务都要分配一个栈空间,这所谓的栈空间,可以是全局数组,也可以是动态分配的内存空间。裸机系统之中,大伙熟知的系统的主体是main函数中的无限循环,在无限循环中,CPU执行你所编写的业务操作。系统为保证任务正常执行,每个任务额外定义控制块,里面存放了任务所有信息,比如任务的栈指针,任务名称,任务的形参等等。那么怎么个无法返回法呢?在裸机系统中,你的变量,无论全局的还是局部的,写哪儿都没事,但是在多任务系统中,需要放在一个名为栈的地方。

2025-11-25 19:02:06 240

原创 嵌入式开发学习日志44——FreeRTOS之系统特点与编程风格

首先是数据类型上,FreeRTOS对数据类型进行了重新的封装,新定义了portchar(效果和原来的char一致),删掉了int,改为16位的portshort和32位的portlong,此外还新增了portBASE_TYPE,它对应的虽然是long类型,但实际上是根据处理器的框架来决定是多少位的。在定义函数时,既要在函数名前加上返回值类型的缩写,比如void类型的v,还要加上文件名,比如函数是在task文件中定义的,返回值是void型,则函数名可以写作vTaskpriority()。

2025-11-18 19:21:58 337

原创 嵌入式开发学习日志43——FreeRTOS之引入

操作系统中的任务调度器就是用来决定某一时刻究竟是运行哪个任务,同时,RTOS的任务调度器是可预测的,这恰好满足了嵌入式实时环境要求的对某一事件做出实时的响应。实际上,当你的业务越来越多时,单纯的裸机系统是没法完全满足需要的,编程难度也会比之前大上很多,加入RTOS实现多任务的管理,能够有效减轻压力。但实际上,一个处理器核心一个时刻只能处理一个任务,之所以看起来像是多个任务同时进行,是因为任务之间的切换十分迅速,肉眼无法分辨,故看起来像是同时的。FreeRTOS,正如它的名字那般,是免费的。

2025-11-15 19:14:34 210

原创 嵌入式开发学习日志42——stm32之SPI工作方式

当CPOL=0时,由于开始的空闲状态时钟处于低电平,所以之后跳变为高电平的上升沿就被称作第一边沿,而当高电平再次变为低电平时,下降沿就会作为第二边沿。当CPOL=1时,两种边沿的规定大不一样,第一边沿变为了下降沿,而第二边沿变为了上升沿。当CPOL=1,CPHA=0时,同步时钟会采集下降沿的数据,当CPOL=1,CPHA=1时,上升沿数据会被采集,此时这两种模式被称为10和11模式。当CPHA=0时,串行同步时钟的第一边沿就会被采集数据,而当CPHA=1时,串行同步时钟的第二边沿就会被采集数据。

2025-10-29 13:09:07 366

原创 嵌入式开发学习日志41——stm32之SPI总线基本结构

由于SPI是一种高速的、全双工同步通信总线,并且在芯片上占据了极少的管脚,节省了更多的空间,所以越来越多芯片开始应用这种通信协议。SPI也有属于自己的特点。CS片选线则和上面三根线不同,每个从设备都会有一根独立的CS片选线连接到主机的引脚上,有多少设备就有多少根线,而片选线的功能就相当于I2C中的I2C寻址,也是用于主机对从设备的选择的。当主机要选择从设备时,该从设备的CS信号线就会被设置为低电平,此时该从设备就被选中,也就是所谓的片选有效,当CS线的电平被拉高,那么就代表通信结束,原理十分简单易懂。

2025-10-20 20:22:06 343

原创 嵌入式开发学习日志40——stm32之I2C协议层

当从机被寻址到并且可以接收时,会返回应答信号,此时由主机向从机传输数据,如果从机满了或者不想再接收时,就会在某次接收完数据后返回非应答信号(NACK),此时主机就会拉高电平,产生停止信号。第三种就是两者的综合,以先写再读为例,读和写的流程都和上面差不多,但是要注意,二者的连接需要重新发送起始信号,同时再次寻址,用方向位来改变操作。当然,如果从机不想再接收数据时,可以保持高电平,此时主机就会接收到非应答信号,那么主机就会拉高电平,发出终止信号终止数据的进一步传输。根据情况的不同,大抵可以分为三种形式。

2025-10-19 16:24:55 488

原创 嵌入式开发学习日志39——stm32之I2C总线物理层与常用术语

I2C总共有三种传输模式,按照传输速率划分,可以分为标准模式(100kbit/s),快速模式(400kbit/s),常用的也是这个,还有高速模式(3.4Mbit/s),但是绝大多数的I2C设备不支持高速,所以这里也不推荐。一个I2C总线只有两条线路,一条被称为双向串行数据线,顾名思义,就是用来发送数据(半双工,并非全双工),另一条是串行时钟线,用于数据收发的同步。既然提及了通信,光有物理层肯定是不够的,下一章会详细讲述有关I2C的协议层部分,看看I2C通信数据的传输都有什么标准和限制。

2025-10-17 20:17:46 288

原创 嵌入式开发学习日志38——stm32之看门狗

独立看门狗有一个12位递减计数器,开始时会设置一个初值,然后向下递减,在计数器归零之前,如果将计数器进行了重置计数,那么看门狗就不会产生复位信号,这个重置的操作就相当于喂狗,当然,如果没有进行重置,看门狗就会自动执行自己的功能,提醒你需要“喂狗”了。其次,窗口看门狗是7位递减计数器,它的“喂狗”操作限制也不一样,窗口窗口,是有一个特定的时间窗口,如果早于或者晚于这个时间窗口进行“喂狗”,都会导致程序复位。stm32自带了两个看门狗,一个是独立看门狗,一个是窗口看门狗,本章着重讲一下独立看门狗。

2025-10-08 11:46:41 623

原创 嵌入式开发学习日志37——stm32之USART

USART在stm32中应用最多的莫过于它的printf输出功能(学过C的小伙伴狂喜),你可以在特定位置加上printf语句对代码进行调试,一般情况下,串口都会正常将你想要输出的语句打印到串口助手上,但是,如果代码里有隐含的逻辑错误,那么很可能你没法看到语句的输出打印,那么这个时候,你就可以锁定问题所在了。其次是数据寄存器部分,它是低9位有效,但实际用起来却并非如此,USART控制寄存器中有M位,这个标志位决定了数据第9位是否有效,M位为0时,数据字长为8位,而当M位为1时,数据字长为9位。

2025-10-07 18:22:47 561

原创 嵌入式开发学习日志36——stm32之USART串口通信前述

相较于串口通信,并行通信的信息传输速率更快,控制起来更简单,但是由于用到的数据线较多,所以成本较高,同时很难控制接收方同时接收数据,传输时的抗干扰能力也不强。这种通信的好处显而易见,传输线少,长距离传输时成本就比较低,并且可以借助现有的设备进行,但是因为要处理每一位数据,数据传送的控制会比较复杂。半双工通信可以实现数据的双向传输,但是这个双向传输仍然有限制,不能同时进行,发送方到接收方传输时,接收方就无法向发送方进行数据传输。全双工通信更加全面,可以实现数据的同步双向传输,不过,成本会比较高。

2025-10-06 16:45:14 372

原创 嵌入式开发学习日志35——stm32之超声波测距

首先,由单片机向trig引脚发射一个10us或以上的高电平信号,trig引脚接收到之后,让模块对外发射8个40khz的超声波,此时,Echo引脚就会自动变为高电平,当模块接收到反射回来的超声波时,Echo引脚会再次变为低电平。其实要注意到,单独的单片机定时器模块产生中断,并不能直接帮助我们确定传播时间,因为定时器模块加入的是我们自己设置的时间参数,真正的传播时间并不清楚,只能获得定时器产生中断的次数,因此这里还要结合外部中断,更准确地计算出传播时间。知道原理后,又该如何用代码实现超声波测距呢?

2025-10-05 18:58:56 514

原创 嵌入式开发学习日志34——stm32之RTC实时时钟系统

BKP有一个极其重要的特点,它可以由两个电源进行供电,当外部提供的VDD被切断,BKP仍然可以使用后背电源VBAT继续供电,只有当两个电源都被切断时,BKP才会结束工作。RTC作为独立定时器,并没有先前介绍的通用定时器有那么多计数方式,它只能向上计数,而且由于有两种电源,所以为了保证VDD被切断后定时器仍然能够正常运转,RTC的时钟来源外部低速时钟LSE(32.768khz)RTC的时钟配置都存放于后备区域中,而数据也正是存储在RTC模块的备份域,结合BKP,RTC模块就可以做到安全有效地存储用户数据。

2025-10-04 19:26:25 385

原创 嵌入式开发学习日志33——stm32之PWM舵机简单项目

解决完定时器模块的初始化后,设置PWM的工作模式,Mode这里就选择最常用到的PWM1模式;为计算方便的数值,PSC取71,ARR+1取20k。源文件部分,还是先开启需要用到的时钟,这里要用到PA1引脚,因此开启GPIOA时钟,由于之后要用到复用输出模式,所以还要开启AFIO时钟。至于TIM2定时器模块,在初始化时没有采用上次手动输入参数的形式,由于项目的目标明确,所以先计算出pwm的频率。在主函数中,直接通过按键按下的形式实现舵机角度的旋转,但是这里对底层代码进行讲述,main函数中的部分暂时不讲。

2025-10-03 20:38:35 334

原创 嵌入式开发学习日志32——stm32之PWM

例如,有一个正弦波模拟信号,它既有0V的部分,也有最高3.3v的部分,但是对于计算机系统来说,只能进行0和1的识别,stm32也只能输出0v或者3.3v,此时正弦波显然有不属于这两个数值的部分,那么只要有足够的脉宽,就可以用PWM进行编码,从而输出1.5v。那么具体如何操控,要看选择的PWM模式,在这里以最常见到的PWM1模式为例,计数器CNT以递增的方式进行计数,CNT的计数值如果小于CCR的,那么就会输出高电平,如果CNT>CCR,那么就会输出低电平。(3)初始化PWM,设置模式以及极性,使能PWM。

2025-10-02 19:26:52 515

原创 嵌入式开发学习日志31——stm32之外部中断与定时器中断的差别与选择

但是以上说的这些只是它们的不同之处,真正让它们无法被替代的,还是各自所能应对的业务场景。其次,EXTI外部中断更适合于外部动态环境,这是因为它的触发条件十分多样,可以通过电平或者边沿检测进行中断的触发,灵活性更好。EXTI是由外部事件触发的,例如引脚电平的高低变化,而定时器则是通过内部定时器计数器模块的计数溢出或者达到阈值,来决定是否触发中断。总之,理清楚两者间的差别对于业务场景应用时的选择是十分重要的,而且在向下讲述更多有关stm32的强大功能前,适当缓一缓,整理一下思绪也是很有必要的。

2025-10-01 20:12:25 453

原创 嵌入式开发学习日志30——stm32之定时器中断简单项目练习

但是值得注意的是,相比于用开关控制LED的外部中断EXTI,定时器中断每隔固定的时间就会让灯泡自动亮起,实现一个小的“自动化”操作,可谓解放双手。下面就是中断操作绕不开的NVIC初始化,具体步骤在之前详细介绍过了,这里就不多赘述,但要注意的是,定时器通道也需要通过查表来确认,不能随便写。由定时器中断控制的点灯操作和其他中断一样,在中断产生前灯泡是不会亮的,但是一旦中断产生,中断函数就会执行,此时灯泡就会亮起。最后,最最重要的是,定时器使能,也就是所谓的开启定时器,否则你就干瞪眼看着灯泡啥事儿都不发生吧。

2025-09-27 17:34:09 351

原创 嵌入式开发学习日志29——stm32之定时器中断

stm32的通用定时器首先包含一个16位自动重载计数器(简称CNT),这是之后经常会出现的非常重要的一个东西,,它可以进行向上或者向下的自动重载,而这个计数器可以由可编程预分频器驱动,一般设置的参数在1-65535之间,这在后面设置预分频系数时会用到。在了解完时钟系统之后,终于可以正式进入定时器中断的学习了,而stm32的定时器数量和功能也非常多,分基本,通用,高级三类定时器,每类定时器的功能层层递进,不过在此以通用定时器为主。(2)初始化定时器参数,如自动重载值,计数方式,分频系数。

2025-09-21 20:22:52 461

原创 嵌入式开发学习日志28——stm32之时钟系统

首先让我们看向HSE外部高速时钟,由片上的晶振提供8MHz的频率给PLL锁相环进行倍频,之后得到想要的72MHz并将时钟放到PLLCLK中寄存,在需要时输出到SYSCLK,由SYSCLK传到AHB预分频器进行分频,然后传给外设,一般进入APB1时会进行二分频,所以常会是36MHz(也是上限),而进入APB2时,可以将72MHz全部传入。PLL,锁相环(学电工的不会陌生)。在图中标出A位置的MCO,一个可以进行时钟输出的IO口,从图上就能看出它能输出哪些时钟,,而这输出的时钟可以作为其他系统的时钟源。

2025-09-18 12:00:53 1166

原创 嵌入式开发学习日志27——stm32之基于外部中断的简单项目实现

中断线路是和你选择的引脚有关,而EXTI模式选择中断,触发方式这里选择的是下降沿触发,当然也可以选择上升沿或者双边沿,最后一定要对中断线路进行使能,这相当于开启了该线路,这样后续才能使用。接下来就是参数的配置,首先是中断通道的选择,这里是外部中断,线路1,不过要注意的是,中断通道的选择可不是和线路一一对应的,需要专门去查看对应的文件去找到线路对应正确的通道。之后就像外部中断的文章里写的那样,需要对外部中断线路进行映射,这个函数记忆起来也很简单,只需要记住括号里要填的是映射的引脚类型以及引脚编号即可。

2025-09-16 11:34:37 367

原创 嵌入式开发学习日志26——stm32之基于GPIO的简单项目实现

而下面就是通过对调用结构体成员的知识的应用了,代码里需要初始化的总共有三个,Mode就是工作模式,在这里一般选择推挽输出,由于输出还分通用复用,我们这里不用复用,所以PP前是Out而非AF。首先就是GPIO引脚的使能,由于时钟系统是挂载在APB2总线上(后面时钟树会讲),所以第一行开启时钟的名称就以APB2开始(好记),我们要初始化的是PA引脚,因此我们是能的对象就是GPIOA,而ENABLE就是使能的意思。首先是头文件,为了防止某些代码的重复编译,所以这里用上了之前C语言中的宏定义的知识。

2025-09-15 20:56:22 203

原创 嵌入式开发学习日志25——stm32之工程创建

加完后还没结束,因为如果你不将这个start的路径设置好,keil还是找不到你项目的文件,点击下方图片的魔术棒,点开C/C++,点击“include paths”来帮忙添加路径,跳出来下面那个框后选右上角的虚线框框来新建空白路径,点省略号之后就可以往里添加了。这时候,新项目就创建好了,但是这仅仅只是开头,真正重要的还在后面,也就是所谓的文件关联(没错,你新建了没用,你外部有文件导入到新建的文件中时,你keil里收不到)。这个软件可是个硬骨头,在没有任何指导的情况下,新手是很难直接上手的,可以说相当不友好。

2025-09-14 13:30:57 795

原创 嵌入式开发学习日志24——stm32之外部中断

EXTI的功能有两个,除了上述的产生中断外,还有一个就是产生事件,这从EXTI控制器共有20个中断/事件线就可以看得出来。上章简单介绍了一下stm32的中断系统,进一步,想要实现程序的中断,还要学会应用stm32不同的中断方式,本章就来聊聊中断的方式之一——外部中断,也称EXTI(Extern Interrupt)。所谓EXTI,也就是外部中断,它的工作过程是通过检测GPIO引脚的电平变化,向NVIC(嵌套向量中断控制器)发出中断请求,经过NVIC的判断之后,即可中断CPU程序,转而执行中断服务程序。

2025-09-13 10:49:21 348

原创 嵌入式开发学习日志23——stm32单片机之中断系统简介

如果抢占式优先级是相同的,那么就会比较响应优先级,不过此时肯定有高抢占式优先级的事件在执行中断(也称中断嵌套),那么高响应优先级的事件会先一步排队,如果二者都相同,那么最终会根据中断表中的顺序来决定哪个事件先执行中断。stm32中的中断是根据各自的中断优先级进行排队的,它总共有60个可屏蔽中断通道,每个通道都有对应的8位中断控制字,但一般只有高四位有效,同时优先级数字并非越大优先级越高,而是越小级别越高。在有效的高四位中,也被详细划分了两种中断,一种是抢占式中断,一种是响应式中断。(5)编写中断服务函数。

2025-09-08 10:54:23 175

原创 嵌入式开发学习日志22——stm32单片机之GPIO口

至于通用和复用的区别,GPIO口的部分引脚具有第二功能,在通用的情况下,只需要通过IO口内部晶体管的交替工作即可输出高低电平,但是启用复用功能,就要依赖其他的外设作为信号源,绕开内部的ODR(输出数据寄存器)。在开漏模式下,GPIO口内部p-mos管是处于挂机状态,只有n-mos管在工作,遇到高电平时n-mos管截止,所以最后呈现出来是高阻态,遇到低电平时n-mos管导通,最后接上VSS。在开漏模式下,可以读取引脚电平,但是一般情况下高电平情况下呈现高阻态,低电平接VSS。为什么两者会有这样的区别?

2025-09-07 11:51:51 207

原创 嵌入式开发学习日志21——stm32单片机简介

M全称microelectronics,意为微控制器,注意,微处理器和微控制器有很大区别,微控制器是集成CPU,存储器(ROM/RAM),I/O接口以及定时器等模块集合形成的单芯片系统,而微处理器仅有一个核心CPU,需要接外设才能工作。单片机是嵌入式开发十分重要的一环,而stm32作为开发的常客,被广泛应用于智能小车,无人机,无线通信等嵌入式领域,而本次的学习也是围绕着这个核心展开的。stm32功能强大,性能十分优异,同时片上资源丰富,功耗低,这也是为什么会选择stm32。

2025-09-04 16:47:06 282

原创 嵌入式开发学习日志20——C语言之动态内存分配

第三个是realloc,它的格式为void* realloc(void *p,size_t size),根据它的参数列表其实就可以推测出它的功能,第一个参数其实就是指向了一片动态内存空间的指针,而后面的参数就是空间大小,realloc的功能便是将指针指向的空间大小重新进行分配,分配的大小由realloc中的参数决定。这时这片空间就会变成独立的状态,你没法向里面写入数据,但是这片空间又会一直在那占据内存,久而久之,你的内存就会变少,这就是所谓的内存泄露,在单片机的使用中,我们要严格杜绝这一现象发生。

2025-09-03 16:50:55 414

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除