抛开 tab 和空格哪个好看不谈,不同编译器设置格式不同,空格比较保险。
用户关键字:打出来的时候会高亮。
代码提示:(symbols after 是几个字符后开始提示关键字的意思)
以上的四个配置会保存在 global.prop 文件里,以后重装保存这个文件就可以保存配置。
shift tab 整体左移,直接 tab 右移。
函数变量快速定位:魔术棒-output-browse information。右键 goto definition 即可跳转。
快速注释:有一个 // 的符号,选中代码段后点击一下即可快速注释。
快速打开头文件:右键头文件名-open document xxx.h
replace 是替换。
build output 窗口里双击 error 是可以快速定位过去的。
窗口视图恢复默认状态的方法:window à Reset View to Defaults + Reset
c99中的标准库文件。
& | ~ ^ << >> 没啥多说的。
给某一位赋值:1. 先&把其他位保留,该位置0,再|把其他位保留,该位置1. temp &= 0xFFFFFFBF; temp |= 0x00000040;
temp &= ~(1<<6); temp |= 1<<6;
#define PI 3.14159
#define __set_task_state(tsk, state_value) \
do { (tsk)->state = (state_value); } while (0)
一定要用 do while(0) ,这样程序才会按照我们期望的方式执行。
宏定义为什么要使用do{……}while(0)形式_土豆爸爸的博客-CSDN博客
宏定义避免影响控制流程,比如宏定义的函数里面可以 return 就比较危险。
宏定义传参避免参数变化,如 (SQUARE(a++))
用 extern 声明的函数或变量代表是在其他文件定义的。
typedef unsigned char uint8_t;
char *ptr="234";
tab 设置为4个字符。
80列后的字符分行。
相对独立的代码块,变量之间加空行。
多行语句不要写在一行里。if 语句也是,而且 if 语句后面哪怕只有一个语句也不要偷懒,加大括号。while 后面没有执行语句的话可以不用大括号。
左括号另起一行。
if、swich、case、for、do、while 后加空格。
sizeof、typedof、alignof 后面不加空格。
指针的*靠近变量名,而不是数据类型。
= + - < > * / % | & ^ <= >= == != ? : 左右加空格。
一元操作符后不加空格, & * + - ~ ! sizeof typeof alignof __attribute__ defined。
++ – . -> 前后都不加空格。
逗号和分号只在后面加空格。
注释 /* 内容 */ 和内容之间加空格。
星数必须100个。和代码开始隔一行。
函数注释:
代码注释:
过长放在代码前。
标识符命名:小写,下划线分割,这是 unix 风格。
常用反义词:
循环变量允许 ijk。可以用 g_ p_ 开头表示是全局变量或指针。
不用 u8 u16 u32,使用:
函数命名同变量。
宏命名全大写,单词间用下划线分隔。
函数:一个函数只实现一个功能。
函数之间空行分隔,export 紧跟着函数。
嵌入式开发 linux 常用 goto,清理操作之类很方便。
函数嵌套不建议>4层。
函数要处理好输入参数的合理性,出现错误也能准确返回错误信息。
只在本文件范围内定义的函数变量 static 修饰。
一个变量最好不要多用途。
少用全局变量,避免全局变量和局部变量重名。
初始化尽量使用初值。直接赋值或者 ?: 赋值。
明确全局变量的初始化位置,且减少不必要的数据类型转化。
内核 ARM 厂商授权,外设其他公司添加。板子上黑色的 STM32 一整个就是 arm 公司架构和已发半导体公司合作的结果。
主动单元可以给被动单元发起通信。
以总线矩阵为分界线,左边是主动单元,右边是被动单元。
ICode 直接连接到 FLASH 而不需要总线矩阵做中介,里面存储的是程序,这样访问程序速度很快。
ICode 总线对应图中的 IBus。
外设分为不同频率满足不同外设的需求。
cortex-M3 内核:
左上和右上是跟踪调试,左下是下载。
SDIO 和时钟:
APB 外设:
ICode:
以及一些正点课件里没有详细展开说明的内容:从上到下依次是电源,电源管理,外部晶振,看门狗计时器。
此外,互联型的开发板还会添加网络模块的主动单元,不过我们的不是。
在 ARM Cortex-M4 中,FSMC 是一种嵌入式外设,它代表外部存储器接口。FSMC 支持连接到存储器、LCD 显示器和其他外部设备,可以实现高速数据传输和存储器扩展,以满足大多数嵌入式系统的要求。——ChatGPT
CCM 存数据,访问速度快,但是不支持 DMA。
总线时钟频率:
AHB1/2:168/180MHz (Max)
APB1:42/45MHz (Max)
APB2:84/90MHz (Max)
系统原理图基本和 F1 差不多。
32位单片机,32位地址总线。
存储单元按字节编址。就是说有2^32个按字节编址的存储单元。
每个存储单元的寻址范围:0x0000_0000~0xFFFF_FFFF。
存储器自己是没有地址的,是我们给他映射过去的。
前三个是学习的重点。
寄存器是单片机内部的控制结构,我们的目的归根结底就是控制寄存器,进而控制单片机。
我们主要学习外设寄存器。给寄存器地址命名的过程叫寄存器映射。如 0x4001080c -> GPIOA_ODR。
stm32 GPIO 每组16个 IO 口,比51多一倍。
名字:GPIOx_ODR。
地址偏移:基于 00 最小的地址加一个偏移值。
寄存器复位值:0x0000_0000.
寄存器位表:查看每个位的偏移量,名称,权限。
位功能描述:比如1亮灯,0灭灯。
操作寄存器:比较逆天的方式是直接操作寄存器地址。
*(unsigned int *)(0x4001_080c)=0xFFFF;
寄存器映射:
#define GPIOA_ODR *(unsigned int *)(0x4001_080c)
GPIOA_ODR=0XFFFF;
但是上百上千个寄存器,怎么计算地址和映射?
三者求和计算总线基地址。
总线基地址:APB1 0X4000_0000,APB2 0X4001_0000,AHB 0X4001_8000.
在存储器映像图里可以看到:
比如 GPIOA,外设基地址 0X4001_0000,偏移量 0X800. = 0X4001_0800.
其中的一个寄存器 GPIOA CRH 基于 GPIOA 外设基地址的偏移地址 0X04. = 0X4001_0804.
批量定义寄存器用结构体会很方便。
左边,我们定义了一个7*4的连续空间,因为结构体也是连续存储。
然后通过右边的方式定义了开头指针,则从上到下地址逐渐变大存储。
详细内容可以看 stm32f103xe.h 文件中。可见前几行的内容对应 block0 block1.