我的STM32开发方案:CubeMX+VSCode+Keil5
写在前面: 在学习和使用STM32系列芯片开发板时,一般会使用CubeMX配置工程+keil5开发的模式。但是我并不喜欢keil5的界面和配色方案(不好调),代码补全也很难用。而隔壁的VS Code的编程界面、语法高亮以及AI插件非常好用,我就在思考如何将我代码编写的工作从keil5转移到VS Code中。 一开始,我采用的是很多人会选择的VS Code+STM32CubeIDE for Visual Studio Code插件的方案,但这种方案配置起来相当麻烦,从MDK-ARM转移到CMAKE也很容易出现一些问题,那么为了解决这些问题,我决定采用keil5和VS Code联合开发的方式,使用Keil5进行工程文件的配置和Debug;使用Keil Assistant插件,在VS Code中载入keil5的工程,进行程序的编写。 本文并非是在VS Code上面搭建STM32项目的详细教程,只是一种简单的在VS Code上面编辑下载Keil5工程的经验贴,只会介绍如何在现有的Keil5开发环境与VS Code进行对接,不会介绍如何下载安装和配置Keil5、Cub...
离散数学及其应用-个人笔记
本笔记根据屈婉玲教授编写的《离散数学及其应用整理》 持续更新中 第一章:命题逻辑的基本概念 1.1 命题与连结词 命题的相关定义: 命题: 能判断其真值的陈述句 真值: 真、假(0,1) 真命题: 真值为真的命题 假命题: 真值为假的命题 简单命题(原子命题): 不能被分解为更简单的命题的命题 复合命题: 由原子命题通过连结词组合成的命题 关于命题的判断: 判断是否为陈述句 判断它是否有唯一真值 关于连结词: 否定连结词(非) 合取连结词(交) 析取连结词(并) 蕴含连结词(非p并q) 等价连结词(相等) 注意:连结词运算顺序 (),┐,∧,∨,→ 1.2 命题公式及其赋值 命题公式相关定义: 命题常项(命题常元): 真值确定,不可改变的命题 命题变项(命题变元): 真值可以变化的命题 合式公式(命题公式): 将命题变项用连结词和圆括号按一定逻辑关系连接起来的符号串 子公式: 合式公式中也为合式公式的一部分 重言式(永真式): 在所有赋值下取值均为真的命题公式 矛盾式(永假式): 在所...
STM32:初识GPIO
从今天开始,我将开始更新有关于STM32的相关内容。如有不足请在评论区联系我,感谢大家的指正。 ps.此笔记使用STM32F407VET6开发板 什么是GPIO? GPIO,即General Porpose Intput Output。是通用输入输出端口的简称。可以通过软件控制其输出和输入。stm32芯片的GPIO引脚与外部设备连接起来,从而实现与外部通信,控制以及数据采集的功能。GPIO是STM32最基本的外设之一。 GPIO的工作模式 高电平与低电平: 在进行GPIO的功能讲解之前,我们需要先了解高/低电平这一概念: 在单片机中,高低电平是用来表示数字信号的两个不同状态。通常情况下,高电平对应于逻辑“1”,而低电平对应于逻辑“0”。具体的电压值取决于单片机的电源电压和它的电气标准。例如,在TTL(晶体管-晶体管逻辑)电平系统中,一般认为高电平是在2.4V以上(最高可达5V),而低电平是在0.4V以下。 GPIO的输入功能: GPIO的输入功能分为上拉输入、下拉输入、浮空输入以及模拟输入四种,下面将会一一说明。 上拉输入: IO内部闭合上拉电阻的开关,此...
C++学习第十弹:字符串
字符串是C++中重要的一部分,它是数据交互的桥梁、算法逻辑的载体,更是现代编程中无处不在的灵魂。本篇就来介绍一下C++中的字符串。 C++提供了以下两种类型的字符串表示形式: - - C 风格字符串 - C++ 引入的 string 类类型 C++ 引入的 string 类类型是以C风格字符串为基础的,因此先来介绍一下它。 C风格字符串: C 风格的字符串起源于 C 语言,并在 C++ 中继续得到支持。字符串实际上是使用 null 字符 \0 终止的一维字符数组。因此,一个以 null 结尾的字符串,包含了组成字符串的字符。 下面的声明和初始化创建了一个 RUNOOB 字符串。由于在数组的末尾存储了空字符,所以字符数组的大小比单词 RUNOOB 的字符数多一个。 1char site[7] = {'R', 'U', 'N', 'O', 'O', 'B', '\0'}; 请注意,在使用这种方法初...
C++学习第九弹:数组
C++ 支持数组数据结构,它可以存储一个固定大小的相同类型元素的顺序集合。数组是用来存储一系列数据,但它往往被认为是一系列相同类型的变量。 数组的声明并不是声明一个个单独的变量,比如 number0、number1、…、number99,而是声明一个数组变量,比如 numbers,然后使用 numbers[0]、numbers[1]、…、numbers[99] 来代表一个个单独的变量。数组中的特定元素可以通过索引访问。 所有的数组都是由连续的内存位置组成。最低的地址对应第一个元素,最高的地址对应最后一个元素。 数组是一个小难点,且很重要。 声明数组: 老规矩,使用数组前还是要对其进行声明,在 C++ 中要声明一个数组,需要指定元素的类型和元素的数量,如下所示: 1type arrayName [ arraySize ]; 这叫做一维数组。arraySize 必须是一个大于零的整数常量(也可以留空,但必须进行初始化),type 可以是任意有效的 C++ 数据类型。例如,要声明一个类型为 double 的包含 10 个元素的数组 balance,声明语句如...
C++学习第八弹:函数
在前面介绍C++的基础语法时,提到了每个C++都必须有一个主函数,实际上所有简单的程序都可以定义其他额外的函数。函数是一组一起执行一个任务的语句。我们可以把代码划分到不同的函数中,让每一个函数执行特定的任务。在使用函数时,需要对函数进行声明和定义,函数声明告诉编译器函数的名称、返回类型和参数。函数定义提供了函数的实际主体。 同时,C++标准库提供了大量的程序可以调用的内置函数可供直接调用。 定义一个函数: C++ 中的函数定义的一般形式如下: 1234return_type function_name( parameter list ){ body of the function} 在 C++ 中,函数由一个函数头和一个函数主体组成。下面列出一个函数的所有组成部分: 1. return_type:一个函数可以返回一个值。return_type 是函数返回的值的数据类型。有些函数执行所需的操作而不返回值,在这种情况下,return_type 是关键字 void。 2. function_name:这是函数的实际名称。函数名和参数列表一起构...
在时间长河中的永恒守望:芙莉莲与她的“人类刻度”
当绝大多数冒险故事在英雄加冕的礼花中落幕,《葬送的芙莉莲》却选择在五十年后的墓碑前启程。这部由MADHOUSE制作、斋藤圭一郎执导的2023年动画奇作,改编自山田钟人的同名漫画,以精灵魔法使芙莉莲为主角,展开了一场颠覆类型窠臼的灵魂朝圣。笔者认为,本作品是当之无愧的新时代异世界勇者番剧标杆。 《葬送的芙莉莲》巧妙地颠覆了传统奇幻冒险的叙事终点。故事始于一个看似完满的结局:勇者辛美尔带领着精灵魔法使芙莉莲、人类僧侣海塔、矮人战士艾冉,历经十年艰辛,成功击败魔王,为世界带来和平。然而,真正的故事,却在英雄们“退休”五十年后才缓缓拉开帷幕——以人类勇者辛美尔的自然衰老与死亡为起点。故事始于一个被忽略的“后日谈”:勇者辛美尔衰老离世。他的葬礼成为一道刺穿永恒的裂痕——对拥有千年寿命的芙莉莲而言,五十年的时光原不过指间流沙,直到冰冷的石碑迫使她直面时间的重量。昔日辛美尔笨拙的庆典邀约、未竟的流星之约,在死亡的回响中突然显影,成为她永远错过的情感密码。这位曾以十年光阴终结魔王时代的精灵,第一次被人类的生命尺度所灼伤。 于是芙莉莲踏上了反向的征途。不再为拯救世界,而是为打捞散落在旧日足迹里...
C++学习第七弹:判断
有时候,我们希望程序会根据条件的不同执行不同的操作,此时就要请出我们的判断语句了,C++中常用的判断语句有 if 语句和 switch 语句,下面将会分别介绍。 判断语句: if 语句和 if…else 语句: C++ 中 if 语句的语法: 1234if(boolean_expression){ // 如果布尔表达式为真将执行的语句} 如果布尔表达式为 true,则 if 语句内的代码块将被执行。如果布尔表达式为 false,则 if 语句结束后的第一组代码(闭括号后)将被执行。 ok,也是很浅显易懂,但是如果我们想让布尔表达式为假时执行另一个语句怎么办呢?答案就是使用 else。 C++ 中 if…else 语句的语法: 12345678if(boolean_expression){ // 如果布尔表达式为真将执行的语句}else{ // 如果布尔表达式为假将执行的语句} C++ 中 if…else if 语句的语法: 12345678910111213141516if(b...
C++学习第六弹:循环
军训结束了,现在来更新一下笔记。 在我们的程序中,往往会出现需要重复执行某段代码的情况,而语句一般是顺序执行的,当我们需要重复执行某个或某个语句组时,我们就会用到循环语句。循环语句有多种类型,以及循环控制语句,下面将一一列举。 循环类型: while 循环: 当给定条件为真时,重复语句或语句组。它会在执行循环主体之前测试条件。以下是C++中 while 循环的用法。 1234while(condition){ statement(s);} 在这段代码中,statement(s) 可以是一个单独的语句,也可以是几个语句组合而成的语句组。 condition 可以是任意形式表达式(如变量、算术运算、函数调用等)。编译器会将其结果隐式转换为 bool 类型,任何非0值都会被转换为 true ,0会被转化为 false 。 当条件为 false 时,程序将会继续执行紧接着循环的下一条语句。 风险提示:避免用浮点数做精确判零(如 while(x != 0.0)),因精度误差可能导致无限循环 。 while 循环的关键...
C++学习第五弹:运算符
运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。包括以下几种: - 算术运算符 - 关系运算符 - 逻辑运算符 - 位运算符 - 赋值运算符 - 杂项运算符 算数运算符: 运算符 描述 + 把两个操作数相加 - 从第一个操作数中减去第二个操作数 * 把两个操作数相乘 / 分子除以分母 % 取模运算符,整除后的余数 ++ 自增运算符,整数值增加 1 – 自减运算符,整数值减少 1 前几个比较好理解,对于自增/自减运算符给出如下实例: 123int a=1,b=1;a++;b--; 此时a=2,b=0。 关系运算符: 算符 描述 == 检查两个操作数的值是否相等,如果相等则条件为真。 != 检查两个操作数的值是否相等,如果不相等则条件为真。 > 检查左操作数的值是否大于右操作数的值,如果是则条件为真。 < 检查左操作数的值是否小于右操作数的值,如果是则条件为真。 ...
