【STM32】HAL库调用HAL_SPI_Transmit出现HartFault问题

发布者:星尘之泪最新更新时间:2021-10-14 来源: eefocus关键字:STM32  HAL库 手机看文章 扫描二维码
随时随地手机看文章

问题描述:

HAL库调用硬件SPI发送函数HAL_SPI_Transmit会导致程序进入HartFault


// flash 页大小(字节)

#define FLASH_SPI_PAGE_SIZE       (256)


static uint8_t write_buffer[FLASH_SPI_PAGE_SIZE + 4];


spi1_write(W25QXX_CHANNEL, (uint8_t *)write_buffer, (length + 4));


/**

 * @brief SPI写入

 * @param *txBuffer 发送字节集

 * @param txLength 发送长度

 * @return spi发送的长度

 * */

uint32_t spi1_write(SPIChannel channel, uint8_t *txBuffer, uint32_t txLength)

{

  if(channel == W25QXX_CHANNEL)

  {

    W25QXX_CHANNEL_ON;

  }


  HAL_SPI_Transmit(&hspi2, txBuffer, txLength, 500);


  if(channel == W25QXX_CHANNEL)

  {

    W25QXX_CHANNEL_OFF;

  }


  return txLength;

}


原因分析:

Debug发现进入HartFault之前最后一句话是

在这里插入图片描述

是该揭开它真正面纱的时候了:我们再看出现问题的那条语句:


hspi->Instance->DR = *((uint16_t *)pData);


再看我们数组的定义:uint8_t

出现问

题这条语句把我们定义的uint8_t 数组转换成了uint16_t 同时进行半字的操作(同时操作两个byte)。这样看确实提高了执行效率,但是却也埋下了隐患。


产生这样的问题,我们就不得不扯得更远一点,arm内核对数据的非对齐数据访问。


Arm对内存的访问支持字(4byte)、半字(2byte)、字节(1byte)的直接访问,但是呢他们是有一定的要求的:


存取字时要求地址按字对齐,也就是地址要是4的整数倍,如0x0000、0x0004、0x0008(该地址只是举例,mcu的地址分配请参考具体手册的地址映射图)

存取半字是要求地址按半字对齐,也就是地址是2的倍数,这样假如通过0x0001、0x0003这样非2倍数的地址来读取一个半字就会产生错误

存取字节简单,只要地址不超范围就可以

这么看来是不是有点清晰了,我们出现错误的地方不就是在操作一个半字(uint16占用两个byte也就是半字),那么进入到了hardfault应该就是操作了非半字对齐的地址。


下面我们将write_buffer地址打印出来:


rtt_printf("0x%08xn",write_buffer);

在这里插入图片描述

很显然,这个地址并不是非半字对齐的地址。

解决方案:

将write_buffer定义成uint32_t即四字节对齐即可。

static uint32_t write_buffer[(FLASH_SPI_PAGE_SIZE + 4 )>>2];

在这里插入图片描述

关键字:STM32  HAL库 引用地址:【STM32】HAL库调用HAL_SPI_Transmit出现HartFault问题

上一篇:【STM32】解决引脚复用成PWM开漏输出峰值达不到外部上拉的电
下一篇:【STM32】Debug下禁用看门狗

推荐阅读最新更新时间:2024-11-10 17:17

PWM控制电机速度的基本原理
做STM32智能小车的实验中会用到定时器PWM输出,来改变直流电机的转速。分享本文了解如何通过PWM实现对电机速度的控制。 PWM控制电机速度的基本原理 PWM(Pulse Width Modulation),也就是脉冲宽度调制。 PWM中有一个比较重要的概念,占空比:是一个脉冲周期内有效电平在整个周期所占的比例。 为了实现IO口上电压的持续性变化,可以调节PWM的占空比。这也能够使外设的功率进行持续性变化,最终控制直流电机转速的快慢。如何调节PWM波形的输出就是重点。相关推荐:STM32中PWM的配置与应用详解。 上图中的ARR是我们给定时器的一个预装载值,CCRx的上下变化是产生P
[单片机]
PWM控制电机速度的基本原理
STM32之CAN详解
简介:bxCAN有3个主要的工作模式:初始化模式、正常模式和睡眠模式。 当bxCAN处于睡眠模式,软件必须对CAN_MCR寄存器的INRQ位置’1’并且同时对SLEEP位清’0’,才能进入初始化模式。 有2种方式可以唤醒(退出睡眠模式)bxCAN:通过软件对SLEEP位清’1’,或硬件检测到CAN总线的活动。 1 bxCAN工作模式 bxCAN有3个主要的工作模式:初始化模式、正常模式和睡眠模式。 在硬件复位后,bxCAN工作在睡眠模式以节省电能,同时CANTX引脚的内部上拉电阻被激活。软件通过对CAN_MCR寄存器的INRQ或SLEEP位 置’1’,可以请求bxCAN进入初始化或睡眠模式。一旦进入了初始化或睡眠模
[单片机]
<font color='red'>STM32</font>之CAN详解
基于STM32、ESP32,钢铁侠打造机械臂设计
一直是稚晖君很感兴趣的一个方向,而在中他认为最实用的非臂莫属。正巧,半年前稚晖君偶然淘到了一台二手机械臂,这让他有些激动。然而,喜悦之情还没持续多久,稚晖君就有些不开心了:在他花了一些时间将这台机械臂研究透彻,并自己开发了一套 K 后,感到了一点不妙:“这个手子不太行啊”。 稚晖君表示,目前市面上的机械臂都不够酷,因此决定要自己造一台很酷的机械臂,并将其取名为 Dummy(取自钢铁侠中一只名为 Dummy 的机械臂)。为此他总结了一份架构设计图(由于该图较长,中为滚动呈现,因此本文仅截取部分): 准备 既然是要设计一台机械臂,那就需要从硬件开始准备,毕竟无论软件再重要,也需要一个优质的载体才
[机器人]
STM32单片机(12) 红外信号接收解码(外部中断)
本程序主要利用外部中断,实现红外遥控器信号接收解码,并利用串口通信把编码传至计算机显示 注:请用质量好点的遥控器实验,用了劣质遥控器浪费了一天时间,数据位接收总是不完整,后来用宿舍空调遥控器就解码成功了 相关资料 STM32单片机学习(2) 外部中断 http://blog.csdn.net/leytton/article/details/38063335 STM32单片机学习(3) 串口中断通信 http://blog.csdn.net/leytton/article/details/38393553 STM32单片机学习(7) 串口通信printf重定向 http://blog.csdn.net/leytton/ar
[单片机]
STM32接口FSMC/FMC难点的理解
一,FSMC简 FSMC,即灵活的静态存储控制器,能够与同步或异步存储器和 16 位 PC 存储器卡连接, STM32 的 FSMC 接口支持包括 SRAM、NAND FLASH、NOR FLASH 和 PSRAM 等存储器。 二,FSMC存储块 STM32F767的FMC将外部存储器划分为6个固定大小的256M的存储区域,如下图 如图: FSMC分为4块,每块256M字节又被划分为4*64,即四个片选 NOR / PSRAM使用块1,共256M NAND闪存使用块2,3,共512M PC卡使用块4,共256M 三,存储块1(Bank1)寄存器 STM32 的 F
[单片机]
stm32库函数记录
一、系统初始化函数执行完毕各时钟的状态 二、三类(总线上的)时钟函数 2.1、外设时钟使能函数 void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState); void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewStat e); void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewStat e); 此3 个时钟使能函数也是 STM32
[单片机]
<font color='red'>stm32</font>库函数记录
PS2无线遥控手柄与STM32单片机通信
PS2无线遥控手柄 接下来要做一个小车玩玩,在网上淘了一个PS2无线遥控手柄,用于控制小车的前进、后退等功能。 实物图如下: 其中有两个PS2游戏摇杆,对应的驱动原理参见下文: PS2游戏摇杆原理及控制实现 接收器 与这个手柄配套的还有一个接收器,用于接收PS2无线遥控手柄发送过来的数据 该接收器一共有六个引脚,分别定义如下: 注意: 当接收器上的绿灯常亮时,证明手柄和接收器配对成功,可以正常进行数据通讯。如果手柄和接收器断开了,按手柄上的 START 键即可恢复配对; 当手柄上的MODE指示灯没有点亮的时候,游戏摇杆四个方向输出按键键码值;当点击 MODE 按键后,手柄上的MODE指示灯变亮(红色),
[单片机]
编译STM32错误之一:Error: L6218E: Undefined symbol TIM_Cmd
注意要包含头文件:#include stm32f10x_tim.h 还有要把stm32f10x_tim.c加进工程。
[单片机]

推荐帖子

Hi-Fi/AV放大器维修图集 486页
Hi-Fi/AV放大器维修图集486页
wzt 电源技术
有偿服务:使用ucgui设计一个界面,有经验者进
因最近手上任务比较多,再加上对ucgui不是很熟悉,所以想把一个项目的GUI界面外包出去,可以使用ucgui模拟器实现,我自行移植即可。有意者请加QQ:570101566了解详细需求。有偿服务:使用ucgui设计一个界面,有经验者进ucguibuider 还需要对应的响应函数哈。不仅仅是界面
fengxu0217 实时操作系统RTOS
低价出 AM3359的开发板,和一块 三星4412开发板
照片如图,一块AM359的 带屏幕,九成新,资料不怎么齐全,目前只有linux部分的,但是够用。不适合入门学习。300元一块三星4412的,cortexA9四核,基本全新,资料齐全,有入门资料,适合入门者学习。500元可以淘宝交易需要的联系QQ429512065本站强荐:185娱乐R城.足球R真_人.彩票齐全R手机可投R注任何游戏.首次开户送10元.首存送58元.信誉绝对保证185.cc低价出AM3359的开发板,和一块三星4412开发板大概有什么资料也得截
2638823746 淘e淘
内存泄漏,请帮忙看看问题出在哪里?
voidCRS2USBDlg::OnTimer(UINTnIDEvent){//TODO:Addyourmessagehandlercodehereand/orcalldefaultHKEYhKey=HKEY_LOCAL_MACHINE;DWORDnumSubKey=0;DWORDi;DWORDsizeSubKey;
BlueSummer 嵌入式系统
问个傻傻的问题
一直没太明白keil编译时全局变量是存放在哪个区的,今天在程序里面试了下,定义几个全局变量后,code区的大小一直未变,倒是Xdata区的变大了。我的理解是这样的,在编译的时候,不也应该在代码区给全局变量分配地址吗,这样程序运行过程中才可以找得到这个变量。如果定义在xdata区,又因为xdata不是属于ram区吗,掉电后不是会丢失?现在全迷糊了,以前没考虑过这么多,乱了!!!问个傻傻的问题变量不管是什么类型都是处于RAM中,Code区是程序代码存放的地方,只能定义程序区的常量。XD
ena 51单片机
430F149键盘中断问题,急!!
键盘采用中断方式,可是我按键盘后,程序没反映,跟踪时有键盘的值,在P1键盘中断中,先判断键盘的值,再做标志位,然后在主程序根据标志位来完成任务!现在不知道是什么问题,多按几下却能够得到响应的希望结果,现在请问专家和高手们,你们的键盘是做如何处理的,能否发个简短的程序啊!430F149键盘中断问题,急!!程序贴来看看~查询!! 引用: 键盘采用中断方式,可是我按键盘后,程序没反映,跟踪时有键盘的值,在P1键盘中断中,先判断键盘
transhuman 微控制器 MCU
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved