前言在很久很久很久以前C 语言和 STM32走在一条幽静的道路上他们在一起过上了幸福的生活一、 问题引入… 1二、 寄存器的基础概念… 1三、 STM32 寄存器实例解析… 3GPIO 输入/输出 → 对应 GPIOx_CRL / GPIOx_CRH / GPIOx_IDR /… 3定时器Timer→ 对应 TIMx_ARR / TIMx_PSC / TIMx_CNT 等… 4串口通信UART→ 对应 USARTx_SR / USARTx_DR /… 4ADC 模数转换 → 对应 ADCx_CR1 / ADCx_CR2 / ADCx_SQR1 等… 5PWM 输出脉宽调制→ 对应 TIMx_CCR1 / TIMx_ARR… 6复位与时钟 → 对应 RCC_CR / RCC_CFGR 等…6四、 从软件层面理解地址与封装… 7五、 地址值与寄存器位使能的关系…11六、 地址值的封装… 13七、 CAN 初始化函数–“CAN_Init”的解析…16首先看这个语句… 16第 156 行定义的是定义初始化状态跳转对应的宏定义得到下面的图片这里定义了两个地址值 0X 00 和 0X01 将其转化位二进制可以知道… 16在对应寄存器可知如下…17接着就看这一句… 17再接着… 183.1 先查看“CAN_MCR_SLEEP”的宏定义…183.2 解除睡眠模式的方法… 193.3 初始化的方法… 1914.判断是否初始化是否成功… 22八、 对“.hex”文件的解析…25九、 浅谈寄存器寻址的方式… 27十、 寄存器方式启动 GPIOA 总线下的 Pin_0… 29源代码… 30源代码寄存器启动的代码… 30现象如下… 31十一、 总线方式启动 GPIOA 总线下的 Pin关于 C 程序在 STM32 下具体做了什么事情一、问题引入在华清学习的这一段时间首先在老师的带领下巩固了 C 语言相关知识。本人在大学就读机械相关专业期间运用课余时间自学 STM32 并率领成员落地相关自动化项目。并取得设计专年级第一的成绩。但在自学期间有很多的问题这些问题有幸在华清远见的老师的带领下解决了。非常感谢。言归正传大学自学期间最令我头疼的事情是区区几行 C 语言代码怎么能控制我们的硬件。驱动传感器、LED、甚至是网络的呢二、寄存器的基础概念在华清学习期间令我听到最多的关键字就是“寄存器”结合 AI 我们先梳理寄存器是什么好这个 AI 解释我看不懂一、但是我可以很负责任的跟你们说寄存器就是存放相关的工具的小盒子。为了解释这个概念。我给你们看一下由华清老师提供的技术文档1在这里感谢这名名老工程师从业十几年的资源非常实用。感谢感谢 TOP1:名称CAN 主控制寄存器作用用于配置和控制 CANController Area Network控制器局域网外设核心工作模式与关键行为的重要寄存器 TOP2:名称ADC 状态寄存器(ADC_SR)作用ADC 状态寄存器ADC_SR用于反映 ADC 转换状态与监测模拟看门狗情况具体作用如下 TOP3:名称GPIOx_CRL作用具体作用如下用于配置 GPIO 端口的低 8 位引脚 Pin0 ~ Pin7的工作模式和输出类型。2所以看明白了吗关键就是华清上课一直所说的“寄”“存”“器”寄存器内封装了相关对应的功能。这些功能对应了相关的功能。比如说下面这些例子都是单片机/STM32 里最常见的“寄存器 - 功能”对应你可以对应着理解“寄存器是如何封装硬件能力的”三、STM32 寄存器实例解析GPIO 输入/输出 → 对应 GPIOx_CRL / GPIOx_CRH / GPIOx_IDR / GPIOx_CRL / GPIOx_CRH 端口配置寄存器就像你给引脚“选职业”(参照玩王者荣耀)——让 Pin0 是当“输入引脚”还是“输出引脚”输出时速度多快输入时是浮空/上拉/下拉……写这些寄存器的值就是在给引脚“分配工作”。 GPIOx_IDR 输入数据寄存器像“看引脚现在干啥呢”——读取 IDR 寄存器就能知道外部电路给这个引脚灌了高电平还是低电平比如按键有没有被按下。 GPIOx_ODR 输出数据寄存器像“指挥引脚干啥呢”——往 ODR 写 0 或 1引脚就会输出低电平或高电平比如让 LED 亮/灭。3定时器Timer→ 对应 TIMx_ARR / TIMx_PSC / TIMx_CNT 等定时器就像“芯片里的电子秒表”用来计时、产生周期性中断、输出 PWM波……靠的就是一系列寄存器配合 TIMx_ARR 自动重装载寄存器相当于“定闹钟的时间”——写这个寄存器的值就是设置定时器“数到多少后触发事件”比如数到 1000 就溢出。 TIMx_PSC 预分频器寄存器相当于“给秒表调快慢”——写这个值能改变定时器计数的“基准频率”比如把 72MHz 主频分成 7200 分频计数速度就变慢计时更久。 TIMx_CNT 计数器寄存器相当于“秒表现在走到多少了”——读这个寄存器就能知道定时器当前计了多少个数写这个寄存器还能“重置秒表”比如清零重新开始计时。串口通信UART→ 对应 USARTx_SR / USARTx_DR /串口用来和外设/电脑收发数据全靠寄存器控制“啥时候发、啥时候收、发多快、收没收到” USARTx_SR 状态寄存器相当于“串口的「状态指示灯」”——读这个寄存器能知道“有没有收到数据发送缓冲区空没空有没有出错”比如 RXNE1 表示“收到新数据啦可以读了”。 USARTx_DR 数据寄存器4相当于“串口的「收发缓冲区」”——往 DR 写数据串口就会自动把这个数据发出去读 DR就能拿到串口刚收到的数据。 USARTx_BRR 波特率寄存器相当于“串口的「说话速度调节器」”——写这个寄存器的值就能设置串口通信的波特率比如 9600、115200决定每秒发多少个 bit。ADC 模数转换 → 对应 ADCx_CR1 / ADCx_CR2 / ADCx_SQR1 等ADC 是把“模拟电压比如传感器输出的 0~3.3V”转成“数字量芯片能处理的 0~4095”的模块靠寄存器控制“采哪个通道、多快速度采、采多少次平均” ADCx_CR1 控制寄存器 1相当于“ADC 的「总开关模式选择」”——写这个寄存器能打开/关闭 ADC选择是单次转换还是连续转换选择扫描模式一次采多个通道等。 ADCx_CR2 控制寄存器 2相当于“ADC 的「触发方式对齐方式」”——写这个寄存器能设置 ADC是软件触发还是外部引脚触发设置转换结果左对齐还是右对齐方便读数。 ADCx_SQR1~SQR4 序列寄存器相当于“ADC 的「通道队列」”——写这些寄存器能设置“先采哪个通道、再采哪个通道、一共采多少个通道”让 ADC 按顺序自动扫描多个模拟输入。 ADCx_DR 数据寄存器5相当于“ADC 的「转换结果缓存区」”——ADC 完成一次转换后数字量结果会自动存在 DR 里软件读 DR 就能拿到这次采样的电压对应的数字值。PWM 输出脉宽调制→ 对应 TIMx_CCR1 / TIMx_ARRPWM 是用来输出“高低电平占空比可调”的脉冲信号比如控制电机转速、LED 亮度核心也是寄存器配合 TIMx_ARR 自动重装载寄存器相当于“PWM 的「周期长度」”——写这个值决定 PWM 一个周期有多长比如 ARR1000就是 1000 个计数周期为一个 PWM 周期。 TIMx_CCR1 捕获/比较寄存器 1相当于“PWM 的「占空比调节」”——写这个值决定在一个 ARR 周期内高电平持续多久比如 CCR1500ARR1000那占空比就是 50%。 TIMx_CCER 捕获/比较使能寄存器相当于“PWM 的「通道开关」”——写这个寄存器的位能打开/关闭某个 PWM 通道比如只让 CH1 输出 PWMCH2 不输出。复位与时钟 → 对应 RCC_CR / RCC_CFGR 等芯片要正常工作得先“上电复位”“配置时钟频率”这些都靠 RCCReset and Clock Control寄存器 RCC_CR 时钟控制寄存器相当于“芯片的「电源开关时钟源选择」”——写这个寄存器能启动/关闭 HSE外部高速晶振、HSI内部高速 RC 振荡器等时钟源还能看时钟有没有稳定比如 PLLRDY1 表示锁相环已经稳定可以用 PLL 时6钟。 RCC_CFGR 时钟配置寄存器相当于“芯片的「时钟分频器外设总线选择」”——写这个寄存器能把高速时钟比如 72MHz分频后分配给 APB1、APB2 等不同外设总线比如让 GPIO 总线跑 36MHz让定时器总线跑 72MHz还能选择系统时钟是用 HSE 还是 PLL 倍频后的时钟。好四、从软件层面理解地址与封装这里仅仅只是我们从硬件层面上理解一块芯片如何让一堆元器件完成对应的功能的。接着为了解开这个疑惑。我开始第二轮 STM32 的学习。终于真相大白还是这三张图 TOP1: TOP2:78 TOP3:看到了吗地址值这是关键接着再看老师经常操作的库文件未来追根溯源我又有了重大发现 这里的地址值与官方提供的《STM32F1XX 中文参考手册》一一对应。 譬如宏定义 地址值 说明9CAN_MCR_INRQ ((uint16_t)0x0001) 初始化请求CAN_MCR_SLEEP ((uint16_t)0x0002) 睡眠模式请求CAN_MCR_TXFP ((uint16_t)0x0004) 发送 FIFO 优先级CAN_MCR_RFLM ((uint16_t)0x0008) 接收 FIFO 锁定模式CAN_MCR_NART ((uint16_t)0x0010) 禁止自动重传CAN_MCR_AWUM ((uint16_t)0x0020) 自动唤醒模式CAN_MCR_ABOM ((uint16_t)0x0040) 自动总线关闭管理CAN_MCR_TTCM ((uint16_t)0x0080) 时间触发通信模式CAN_MCR_RESET ((uint16_t)0x8000) CAN 软件主复位我们重点关注“地址值”这一列再结合中文参考手册