STM32CubeMX入门
前言
cubemx是一个可以自动生成代码的单片机学习和使用的软件,非常方便,但同时配置时需要注意芯片以及外设的各个引脚的配置以及使用情况
C语言:内存四区
下载
直接在官网上下载
基础配置 RCC 配置
需要完成的如下
新建工程,选择 MCU 或者 ST 芯片
在右侧查找自己所使用的芯片型号,然后选择对应的芯片
打开 RCC,将始终源设置为外部时钟,有两种即 HSE 和 LSE,即高速外部时钟和低速外部时钟。如果板子上添加有晶振的话一般需要此设置,一般是设置外部高速时钟为谐振器(包括晶振和陶瓷)。
然后配置时钟树
一个需要注意的问题
如果在中文路径下,在生成代码之后,在第一次编译时会有一个报错,就是找不到对应的启动文件,报错的具体内容为 xxx.sct(7): error: L6236E: No section matches selector - no section to be FIRST/LAST.
实际上这个错误就是就是 startup 开头的汇编文件 startup_stm32f407xx.s 没有添加到整个项目中,这个文件是用来启动整个项目的,这个文件可以在该项目地址下 ...
GPIO八种工作模式
前言
简介
GPIO 是通用输入输出端口的简称,可以通过软件控制其输出和输入。stm32 芯片的 GPIO 引脚与外部设备相连来实现与外部的通信,控制以及信息的采集功能
上拉和下拉
当闭合上图中的 VDD 处的开/关时,此时设置为上拉通路导通,这时候如果不接入外设或者电路断开时,整条回路的电压时断路时的电压,也就相当于电阻不存在,这时候中间处的电平被拉高为 VDD 的电平,也就是处于高电平
如果闭合 VSS 处的开关时,也就是打开下拉电阻,这时候没有外部输入的时候,中间点处电压为 VSS
实际上在 stm32 内部的上拉实际上是一个弱上拉,也就是通过上拉电阻的电流很小,如果想要输出一个大电流,就需要外接上拉电阻了,其实就是增加导线的输出电流。而对于下拉电阻,是让 stm32 的 CPU 引脚输出低电平,结果由于后续电路影响输出的低电平达不到 GND。这时候接入下拉电阻是为了降低导线的输出电流。当上下拉电阻都不开启,此时是浮空模式,引脚的电压是不确定的,此模式下的管脚电压会时不时改变
在 stm32 中上下拉以及浮空模式的配置是通过 GPIOx_CRL 和 GPIOx_CRH 寄存器控 ...
IIR滤波器设计
前言
IIR(Infinite Impulse Response)数字滤波器是指无限长冲激响应数字滤波器,因其具有良好的幅频响应特性,被广泛应用于通信、控制、生物医学、振动分析、雷达和声呐等领域
IIR滤波器的设计可以通过设计一个模拟滤波器,进而利用脉冲响应不变法或者双线性变换法来进行数字滤波器的设计。
设计思路
通常利用模拟滤波器的理论和设计方法来设计 IIR 数字滤波器。设计过程是:先根据技术指标要求设计出一个相应的模拟低通滤波器,得到模拟低通滤波器的传递函数 H(s)H(s)H(s) ,然后再按照一定的转换关系将设计好的模拟滤波器的传递函数转换为数字滤波器的系统函数 H(z)H(z)H(z) 。转换方法有两种:脉冲响应不变法和双线性映射法
利用模拟滤波器设计数字滤波器,就是从已知的模拟滤波器传递函数 H(s)H(s)H(s) 设计数字滤波器传递函数 H(z)H(z)H(z) ,这是一个由 s 平面到 z 平面的映射变换,这种映射变换应该遵循两个基本原则
H(z)H(z)H(z) 的频响要能模仿 H(s)H(s)H(s) 的频响,即 s 平面的虚轴应该能映射到 z 平面的单位圆 ...
C语言可变参数的原理及实现
前言
使用过 C 语言的人都会知道 printf 函数,它的参数中有固定参数 format 和可变参数 ... ,那 format 后面的参数个数不确定,类型也不确定,这些参数都存放在栈中。在 format 中在特定的位置指定对应可变参数的类型,也就是根据 format 里的格式依次将数据取出
原理
所有可变参数都存放在栈中。在 format 中在特定的位置指定对应可变参数的类型,也就是根据 format 里的格式依次将数据取出。而取出的动作需要用到 va_arg va_list va_end 这些宏定义,而且取出可变参数的时候,就相当于是指针指向栈中存放数据的位置,然后将指针不断移动来取出数据。
所以就需要对应着可变参数的数量,一定要注意,一旦出现可变参数数量不对应的情况,那就会产生 crash ,主要还是由于参数的数量如果少于使用参数的数量时,就会导致访问栈内存溢出,从而导致 crash
由于参数分为两个部分:固定参数和可变参数,至少需要有一个固定参数,可变参数的数量可以有多个,声明中使用 ... 表示
va_list
1typedef char * va_list;
实际上就是一 ...
AT&T汇编基础语法
前言
参考
x86 Assembly Guide
编译
编译汇编语言可以使用 GNU 编译器 gcc 和 汇编器 as 或者 gas。一个快速了解汇编语言的方式就是去看编译器输出的汇编程序。使用 gcc -S a.c 可以将 C 语言编译为汇编语言,就可以查看对应的汇编语言了。使用 gcc a.s 就可以把对应的的汇编语言编译为可执行文件了。使用 gcc a.s -c 或者 as a.s 可以将汇编语言编译为可重定位目标文件
例如在 C 语言中经典的 hello world 程序
12345#include <stdio.h>int main() { printf("hello, world"); return 0;}
编译为汇编代码为
123456789101112131415161718192021222324252627282930313233343536373839404142434445 .file "a.c" .text .section .rodata.LC0: .string "hel ...
bochs+gdb调试工具链
前言
bochs 中自带一个反汇编器,这只能查看可执行文件的反汇编之后的指令,但是如果书写 C 语言的话,就使得调试非常麻烦(无计可施),所以利用 bochs 来写操作系统还是挺困难的,同时也没有办法查看各个变量的状态和 cpu 的状态。一旦遇到问题就很被动,所以介绍一个 bochs+gdb 的一个调试工具链
bochs安装与配置
安装环境
123sudo apt-get install g++ sudo apt-get install makesudo apt-get install libx11-dev xserver-xorg-dev xorg-dev
安装 bochs
123456wget https://udomain.dl.sourceforge.net/project/bochs/bochs/2.6.8/bochs-2.6.8.tar.gztar zxvf bochs-2.6.8.tar.gzcd bochs-2.6.8/./configure --prefix=/your_path/bochs --enable-gdb-stub --enable-disasm --en ...
gcc内置原子操作
前言
Gcc 4.1.2版本之后,对 X86 或 X86-64 支持内置原子操作。也就是不需要引入第三方库(如pthread)的锁保护,即可对1、2、4、8字节的数值或指针类型,进行原子加/减/与/或/异或等操作
__sync 接口
具体信息查看 Built-in functions for atomic memory access
type __sync_fetch_and_add (type *ptr, type value, ...) 将 value 加到 *ptr 上,并且结果保存在 *ptr 上,返回操作之前的 *ptr 的值
type __sync_fetch_and_sub (type *ptr, type value, ...) 从 *ptr 减去 value ,结果保存到 *ptr ,并返回操作之前 *ptr 的值
type __sync_fetch_and_or (type *ptr, type value, ...) 将 *ptr 与 value 相或操作,结果保存在 *ptr 中,返回操作之前 *ptr 的值
type __sync_fetch_and_and ...
xv6-kernel上
前言
由于 xv6-kernel 的代码是在 qemu+riscv 中进行仿真的,所以首先我们需要安装 qemu 和 riscv 仿真工具链
riscv工具链
下载源码
源码地址为
risc-v
也可以直接使用 git 指令下载
1git clone https://gitcode.com/riscv-collab/riscv-gnu-toolchain/overview
这里直接下载默认分支
下载模块
打开下载的源码目录下,找到名为 .gitmodules 的文件,这里面就是每个子模块的路径和分支。如果没有梯子,就可以根据其对应的名字在 Gitee 上查找对应的模块,然后直接将其下载到 riscv-gnu-toolchain 这个文件夹下,但是对应的模块要下载到对应的文件夹里。不仅如此,还需要下载该模块对应的分支,分支一定不能错。可以使用如下指令
1git clone -b branch_name url module_name
其中 branch_name 是分支名称, url 是下载链接,也就是 Gitee 上对应的模块的仓库地址, module_name 就是需要将这个模块放入 ...
xv6-kernel下
xv6
内核模式的中断处理
当一个进程获得一个 trap 时,会调用 stvec 寄存器中存储的 uservec 然后进入 usertrap 函数,在函数中会进入内核处理状态,并且将内核中断向量 kernelvec 写入到 stvec 寄存器中。所以在内核模式下发生中断的话会进入 kernelvec ,然后进入 kerneltrap 中。处理结束之后再从中退出到主管模式中去。在 usertrapret 中会将 uservec 写入 stvec 寄存器,然后退出用户模式,以此来保证用户模式下发生中断会在用户中断处理中进行处理
kernelvec
这个是在内核模式下发生中断时运行的第一行代码,这里将会保存原先的内核寄存器,然后进入 kerneltrap 函数进行处理中断,然后返回之后重新加载寄存器,回到原来的进程继续处理
123456789101112131415161718192021222324252627.globl kerneltrap.globl kernelvec.align 4kernelvec: # 将栈指针减少 256 个字节,相当于是向下走 256 个字节 ...
python基础学习
前言
Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言
Python 是解释型语言: 这意味着开发过程中没有了编译这个环节。类似于 PHP 和 Perl 语言
Python 是交互式语言: 这意味着可以在终端中的 Python 提示符 >>> 后直接执行代码
Python 是面向对象语言: 这意味着 Python 支持面向对象的风格或代码封装在对象的编程技术
Python 是初学者的语言: Python 对初级程序员而言,是一种伟大的语言,它支持广泛的应用程序开发,从简单的文字处理到 WWW 浏览器再到游戏
安装
linux
安装依赖环境
1yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel
下载python
1wget https://www.python.org/ftp/python ...
verilog基础语法
前言
这是一种计算机硬件语言,是可以模拟计算机的一种仿真语言,语法上与 C 语言相似。本文主要是笔者为了学习《计算机组成原理》而去了解的一种语言
介绍
Verilog 是一种硬件描述语言,用于数字电路的系统设计。可对算法级、门级、开关级等多种抽象设计层次进行建模
继承了C语言的多种操作符和结构,与另一种硬件描述语言 VHDL 相比,语法不是很严格,代码更加简洁,更容易上手
Verilog 不仅定义了语法,还对语法结构都定义了清晰的仿真语义。因此, Verilog 编写的数字模型就能够使用 Verilog 仿真器进行验证
Verilog 环境搭配
在终端使用指令来安装
1sudo apt-get install iverilog
配置 vscode
安装插件
waveTrace 插件
verilog-HDL 插件
Verilog Format 插件
配置
在 linux 上安装 ctags
找到 ctags 的安装路径,将其添加到 vscode 的设置 Verilog>ctags:Path 中
将 vscode 中设置的 Verilog>linting:Liner 设置 ...
es基础
代码
简介
es 与 js 的关系就是,前者是后者的规范,后者是前者的一种实现
环境配置
nodejs
nodejs 的下载安装与一般的软件无异,从官网找到并且下载安装就好
npm
需要使用镜像下载: 镜像地址
直接在终端执行下列命令就可完成安装
1npm install -g cnpm --registry=https://npmmirror.com/
语法
let关键字
特点
声明的变量只在当前的代码块中有效
不满足变量提升,也就是必须在声明之后使用变量,不然会报错
不允许重复声明同一个变量
1234{ let a = 0;}a = 1; // 报错
const关键字
特点
声明之后变量不可改变
声明时必须初始化
不满足变量提升,也就是必须在声明之后使用变量,不然会报错
只在当前的代码块中有效
不允许重复声明同一个变量
12const a = 1;a = 2; // 报错
变量解构赋值
解构可以用于对象,也可以很方便的将现有的对象的方法赋值到某个变量,对象的顺序没有要求,但是必须与属性同名才能得到正确的值
12var {age, name ...
js基础
代码
前言
JavaScript 是一种轻量级的脚本语言,所谓脚本语言就是指它不具备开发操作系统的能力,而只是用来编写控制其他大型应用程序的脚本。 JavaScript 是一种嵌入式语言,本身提供的核心语法不算很多,可用于 html 和 web ,更可广泛应用于服务器,PC等设备
类似于 C 语言,一行一行的执行,每一行就是一条语句
优点
操控浏览器的能力
广泛的使用领域
易学
与ECMAScript 的关系
ECMAScript 和 JavaScript 的关系,前者式后者的规格。后者是前者的一种实现
将js引入到html文件中
嵌入到文件中
需要在 <body> 标签之内嵌入
123456<body> <script> var num = 10; console.log(num); </script></body>
引入独立js文件
要在 script 标签内定义 type 和 src 属性
1<script type="text/javascript" src=". ...
vue基础
代码
简介
vue 是前端优秀框架,是一套用于构建用户界面的渐进式框架
特点
简单
易学
…
安装使用
使用命令行安装
vue cli 是一个基于 vue.js 进行快速开发的完整系统
1npm install -g @vue/cli
测试,在终端输入以下指令测试是否安装成功
1vue --version
一些功能
使用下列指令打开一个 gui 界面来引导项目创建等一系列操作
1vue ui
创建项目
在终端使用下列指令创建一个项目
1vue create projectname
输入之后需要使用上下按键来选择默认项目模板
可以选择手动选择,然后按照如下选择
文件目录说明
目录/文件
说明
build
项目构建(webpack)相关代码
config
配置目录,包括端口号等。初学可以使用默认的。
node_modules
npm 加载的项目依赖模块
src
这里是我们要开发的目录,基本上要做的事情都在这个目录里。里面包含了几个目录及文件:
assets
放置一些图片,如 logo 等,还可以放全局使用的 css 文件
components
目录里 ...
css基础
代码
前言
CSS 是层叠样式表,又叫级联样式表,后缀名为 .css ,用于是 html 中元素样式的定义
CSS 的主要作用是为了让网页具有美观一致的页面
导入到html
内联样式
要使用内联样式,需要在相关标签内使用 style 属性,其中的 style 属性可以包含任何 CSS 属性
但是缺乏整体性和规划性,不利于维护,维护成本高
1<p style="background-color: green; color:red">段落</p>
内部样式
当单个文档需要特殊样式时,就应该使用内部样式表,可以使用 <style> 标签在文档头部定义内部样式表
这使得单个页面内的 CSS 代码具有统一性和维护性,便于维护,但是在多个页面之间容易混乱
外部样式
实际上是引入外部 css 文件作为不同网页的统一样式,可以实现通过改变一个文件来改变整体的样式,需要注意的是, link 标签在文档的头部才能引入,可以链接到样式表
1<link rel="stylesheet" type="text/css&q ...
html基础
代码
前言
html 是一种描述网页的语言,是一种超文本标记语言,是一套标记标签,标签是被尖括号包围的关键字
html 需要有 DOCTYPE 的声明,是文档类型的缩写,声明位于文档最前面
1<!DOCTYPE html>
html标签
定义 html 文档,这个元素是一种声明文档为 html ,而且其他的元素必须包含在内,限定文档的开始和结束
head标签
用于定义文档的头部,文档的头部描述了文档的各种属性和信息,包括文档的标题,在 web 中的位置以及其他和文档的关系等。大部分内容都不会被看到
body标签
定义文档的主体,元素包含文档的所有内容,比如文本,图像等,会在页面中直接显示
title标签
可以定义文档的标题,显示在浏览器窗口的标题栏或者状态栏上,是在 head 标签中必须要包含的标签, title 标签有利于 SEO 优化
meta标签
用来描述一个网页文档的属性,关键词等
标题标签
标题是通过 <h1>~<h6> 标签进行定义的,其中 <h1> 定义最大的标题, <h6> 定义最小的标题
其中生成标题的快捷键 ...
GTest使用
前言
在编写代码中有 bug 很常见,通过编写完备的单元测试,可以及时发现问题,并且在后续的代码改进中持续观测是否引入了新的 bug ,使用 GTest 是一个不错的选择
GTest 可以用作代码的检测,一般来说可以搭配 CTest 来进行测试
单元测试
就是对程序中最小的单元进行测试,最小的可测试单元可以是一个函数,一个调用过程,一个类等
对于 C/C++ 来说,测试一般是一个函数,检测目标函数在所有可能的输入下,函数执行过程和输出是否符合预期
在测试功能中,每一个单元都是一个可执行文件,实现了 main 函数,所以要在 CMakeLists.txt 中使用 add_test 命令来添加测试用例
测试用例
指的是对一项特定的任务进行测试,体现着测试方案,方法,技术和策略等,包括测试目标,环境,输入数据,步骤,预期结果和测试脚本等
对于上述单元测试,就是在不同输入下,目标函数的预期执行过程和输出,不同的情形可以有一个或者多个测试用例,编写测试用例尽量覆盖所有输入情况,特别是边界值,特殊值和异常
GTest介绍
是 Google 开源的一个跨平台的 C++ 单元测试框架( Google ...
CMakeLists编写
前言
CMake是一个跨平台的构建系统,能自动生成各种平台和编译器的构建文件,相对于直接编写 makefile 文件,编写 CMakeLists 文件不需要考虑太多的文件之间的依赖关系,它可以自动帮你管理复杂项目的构建过程,检测依赖关系,生成目标文件,编译静态库和动态库等,减少手动管理的负担
可以看看这个知乎专题 CMake实践应用专题 - 知乎 (zhihu.com) ,下面的内容几乎都是从这里整理的
CMake一般使用流程
生成构建系统
通过 cmake 指令生成构建系统,可以在命令行中输入 cmake --help 来看到 cmake 指令支持的详细参数,常用参数如下
参数
作用
-S
指定源文件根目录,该目录下必须包含 CMakeLists.txt 文件
-B
指定构建目录,构建生成的中间文件和目标文件的生成路径
-D
指定变量,格式为 -D = , -D 后的空格可省
例如,使用当前目录为源文件目录,其中包含 CMakeLists.txt 文件,使用 build 目录作为构建目录,设定变量 CMAKE_BUILD_TYPE 为 Debug
1cm ...