包含 STM32 标签的文章

STM32F1 型号规则

STM32F1 型号以 STM32F103C8T6 为例: STM32: ARM-based 32-bit microcontroller F:代表芯片子系列 103:基本型 101、增强型 103、 C:引脚数,T:36 脚 C:48 脚 R:64 脚 V:100 脚 Z:144 脚 8:Flash大小,6:32KB,8: 64KB,B:128KB,C:256KB,D:384KB,E:512KB T:封装,H:BGA,T:LQFP,U:VFQFPN 6:工作温度范围,6:-40 ~ 85℃,7:-40 ~ 105...

Cortex-M3 HardFault_Handler 调试心得

这几天在 MDK 下调试 STM32 在进入 HardFault_Handler 异常中端原因的问题上花费了不少周折 简单来说应该采取下面的查找思路: 1、进入 HardFault_Handler 后根据 LR 确定异常发生处所使用的栈指针是 MSP 还是 PSP 2、查看 PSP(假设是 PSP)的值,在 RAM 中找到 PSP 所指的区域 3、地址按从低到高的顺序分别存放了 R0,R1,R2,R3,R12,LR,PC,XPSR 的顺序找出 PC 的值 4、根据 PC 的值找到异常程序的位置 5、分析异常程序位置的 FLASH 及 RAM 访问相关方面是否有异常值,一般是 RAM 被异常修改导致从此处取到了错误的访问地址引起的。 在 HardFault_Handler 打断点,在 Call Stack + Locals 窗口查看调用顺序,在某个入口点右键执行 Show Caller Code 跳到响应程序的位置再仔细查看出错原因...

STM32F1 库函数的宏定义

1、USE_STDPERIPH_DRIVER 宏定义 要在编译器中预定义这个宏: 而且在编译器中仅仅定义这一个宏就可以了。STM32F10X_HD 这类的宏在编译器中选好 MCU 型号后就自动确定下来对应的宏了。 2、HSE_VALUE 宏定义 HSE_VALUE 需要根据实际使用的晶体频率修改,RCC_GetClocksFreq 中会用它来算出系统时钟。因为 USART_Init、I2S_Init、I2C_Init 用到了 RCC_GetClocksFreq,所以如果不修改 HSE_VALUE 为实际情况下的值会出现串口波特率错误等问题。不要直接修改 stm32f10x.h 中的定义,而要在 stm32f10x_conf.h 中重新定义 HSE_VALUE: #undef HSE_VALUE #define HSE_VALUE ((uint32_t)xxx...

STM32 CAN 总线通信

CAN 是控制器局域网络 (Controller Area Network, CAN) 的简称,是由以研发和生产汽车电子产品著称的德国 BOSCH(没错,就是那个卖电动工具的博世)公司开发的,并最终成为国际标准(ISO 11898),是国际上应用最广泛的现场总线之一。 在北美和西欧,CAN 总线协议已经成为汽车计算机控制系统和嵌入式工业控制局域网的标准总线,并且拥有以 CAN 为底层协议专为大型货车和重工机械车辆设计的 J1939 协议。 CAN 采用多主工作方式,节点之间不分主从,但节点之间有优先级之分,通信方式灵活,可实现点对点、一点对多点及广播方式传输数据,无需调度。CAN 采用的是非破坏性总线仲裁技术,按优先级发送,可以大大节省总线冲突仲裁时间,在重负荷下表现出良好的性能。CAN 采用短帧结构传输,每帧有效字节为 8 个,传输时间短,受干扰的概率低。而且每帧信息都有 CRC 校验和其它检错措施,保证数据出错率极低。当节点严重错误时,具有自动关闭功能,使总线上其它节点不受影响,所以 CAN 是所有总线中最为可靠的。CAN 总线可采用双绞线、同轴电缆或光纤作为传输介质。它的直接通信距离最远可达 10km,通信速率最高达 1M bps(通信距离为 40m 时),总线上可挂设备数主要取决于总线驱动电路,最多可达 110 个。但 CAN 不能用于防爆区。 CAN网拓扑结构 CAN 是半双工的。收发数据要分时进行。不管 CAN 网络上挂多少设备,在同一时刻只能有 1 个发送数据。如果有多个需要同时发送则只有优先级别高的先发送,其它等待。控制器有收发两个接口,但是收发器的两个接口变成了 High 和 Low。CAN 总线式两线制的。在这点上可以与 Uart 控制器与 RS-485 收发器来类比。 CAN 协议目前有 2.0A 和 2.0B。CAN 2.0A 是 CAN 协议的 PART A 部分,此部分定义了 11bit 的标识区 。 CAN 2.0B 是 CAN 协议的扩展部分,也叫 PART B,定义了 29bit 的标识区,设计上与 CAN2.0A 兼容。通常支持 2.0B 协议的芯片同时也支持 2.0A。 STM32 单片机的 CAN 控制器接口有收、发两个口,互联型有两个 CAN 控制器。两个 CAN 都分别拥有自己的发送邮箱和接收 FIFO,但是他们共用 28 个滤波器。通过 CAN_FMR 寄存器的设置,可以设置滤波器的分配方式。 STM32 的过滤器组最多有 28 个(互联型),但是 STM32F103ZET6 只有 14个(增强型),每个过滤器组由 2 个 32 为寄存器,CAN_FxR1 和 CAN_FxR2 组成。过滤器有两种工作模式:屏蔽位模式和标识符列表模式。工作在屏蔽位模式时 CAN_FxR2 为 1 的位指示了接收到的标识位必须与 CAN_FxR1 相对应的位的 0 或 1 完全一致才能通过过滤器。如果 CAN_FxR2 全为 0 也就意味着不进行任何过滤。工作在标识符列表模式时 CAN_FxR1 和 CAN_FxR2 互不相干,CAN_FxR2 也是一个像 CAN_FxR1 的寄存器,当接收到的标识符与 CAN_FxR1 或 CAN_FxR2 完全匹配时才能通过过滤器。 STM32 提供了两种测试模式,环回模式和静默模式。环回测试模式不需要短接外部的两个脚,它是在内部环回的...

STM32 定时器

预分频器(TIMx_PSC) 预分频器的值 PSC[15:0],计数器的时钟频率 CK_CNT 等于 fCK_PSC / (PSC[15:0] + 1)。也就是说 PSC[15:0] 等于分频数 - 1。 自动重装载寄存器(TIMx_ARR) 自动重装载的值 ARR[15:0],用于作为计数器的初始值(向下计数)或溢出值(向上计数)。下图的 ARR 被设置为 0x36,溢出发生在计数值为 0x36 的后部,所以实际计数了 0x37 个数(从 0 开始)。所以 ARR 的值应该为 计数值 - 1。 PWM PWM 模式 1 在向上计数时,一旦 TIMx_CNT < TIMx_CCR1 时通道 1 为有效电平,否则为 无效电平;在向下计数时,一旦 TIMx_CNT > TIMx_CCR1 时通道 1 为无效电平(OC1REF=0),否 则为有效电平(OC1REF=1)。 PWM 模式 2 在向上计数时,一旦 TIMx_CNT < TIMx_CCR1 时通道 1 为无效电平,否则为 有效电平;在向下计数时,一旦 TIMx_CNT > TIMx_CCR1 时通道 1 为有效电平,否则为无效电 平。 CC1P:输入/捕获 1 输出极性(Capture/Compare 1 output polarity) CC1 通道配置为输出: 0:OC1 高电平有效 TIM_OCPolarity_High 1:OC1 低电平有效 TIM_OCPolarity_Low 例如: TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //PMW模式1(向上计数时CNT < CCR2时输出低电平) TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = TIM_TimeBaseStructure.TIM_Period / 2; //50%占空比 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //低电平为有效电平 TIM_OC2Init(TIM2, &TIM_OCInitStructure)...

STM32 软件模板

创建文件目录如下: Doc 用于存放文档; Libraries 用于存放各种库,其中的 STM32Lib 是不可缺少的内核与标准外设的驱动库。原则上,所有的库都不要做任何修改,保持与原始发行状态一致。 MDK-ARM 是与 RVMDK 编译器相关的文件夹,存放工程文件、各种输出文件等; User 目录用于存放我们自己开发的代码 mcu 为 MCU 外设驱动程序文件夹; lib 为一些库程序的文件夹; bsp 为其他板载器件的驱动程序。 MDK 开发环境只支持一级组结构,所以组结构就是扁平化了的。一般包含 STM32Lib、Startup、User、Doc 等组。 把内核及标准外设的驱动(C 文件)加入 STM32Lib 组: Startup 为启动代码组,要从 .\Libraries\STM32Lib\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm 文件夹选择一个。 将 main.c、配置、中断服务等文件加入 User 文件夹并加载到 User 组。 stm32f10x_conf.h 头文件在 stm32f10x.h 中通过判断有无 USE_STDPERIPH_DRIVER 宏定义而确定是否引用。 此外还需要配置工程,定义单片机系列(如定义 STM32F10X_CL)、选择使用标准外设驱动库 USE_STDPERIPH_DRIVER Include Paths 中配置所有需要引用的头文件所在目录 配置时钟晶体的频率 在需要操作内核或标准外设的地方直接引用库的头文件(stm32f10x.h)即可: 在编译的时候可以看到所有的库文件都被编译了,速度很慢,如果没有使用某个库文件,可以选择不编译它。 取消选择 Include in Target Build 即可。 在 C/C++ 选项卡中选中 One ELF Section per Function 选项可将用不到的函数排除在编译结果之外,从而减小生成程序的大...