标签: stm32f4

如何使用STM32CUBEF4 HAL库通过i2c读取传感器数据?

我想使用最新的HAL库而不是标准外设库.

我想读出BMA250E G传感器的chip_id,但它不起作用.

aRxBuffer的值始终保持为0x00.但它应该是0xf9!

我的代码有什么问题?

?#?include? "stm32f4xx_hal.h" 

#define I2Cx_SDA_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define I2Cx_SDA_PIN GPIO_PIN_9
#define I2Cx_SDA_GPIO_PORT GPIOB
#define I2Cx_SDA_AF GPIO_AF4_I2C1

#define I2Cx_SCL_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define I2Cx_SCL_PIN GPIO_PIN_6
#define I2Cx_SCL_GPIO_PORT GPIOB
#define I2Cx_SCL_AF GPIO_AF4_I2C1

#define I2Cx_CLK_ENABLE() __HAL_RCC_I2C1_CLK_ENABLE()
#define I2Cx_FORCE_RESET() __HAL_RCC_I2C1_FORCE_RESET()
#define I2Cx_RELEASE_RESET() __HAL_RCC_I2C1_RELEASE_RESET() 
Run Code Online (Sandbox Code Playgroud)
?#?define? I2C_ADDRESS 0x18 

static void SystemClock_Config(void); 

uint8_t aTxBuffer[2],aRxBuffer; 

int main()
{ 
    HAL_Init(); 
    SystemClock_Config(); 
    I2C_HandleTypeDef I2cHandle;

    I2cHandle.Instance = I2C1;
    I2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
    I2cHandle.Init.ClockSpeed = 400000;
    I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; 
    I2cHandle.Init.DutyCycle = I2C_DUTYCYCLE_16_9;
    I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; 
    I2cHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
    I2cHandle.Init.OwnAddress1 = 0; 
    I2cHandle.Init.OwnAddress2 …
Run Code Online (Sandbox Code Playgroud)

stm32 i2c stm32f4

4
推荐指数
1
解决办法
3万
查看次数

使用 EXTI Line 进行软件中断

我正在使用 STM32F4,我想生成一个软件中断。问题是我如何在中断处理程序中知道中断是由软件还是由连接到 EXTI 线的引脚产生的?

embedded interrupt stm32f4

4
推荐指数
1
解决办法
3807
查看次数

STM32 位置无关二进制文件

我正在使用以下 CFLAGS 为 Cortex-M4 (STM32F4) 编译我的 FreeRTOS 应用程序:

-fpic -msingle-pic-base -mpic-data-is-text-relative -mpic-register=r10
Run Code Online (Sandbox Code Playgroud)

-fpic为链接器设置了标志。

矢量表已正确复制到 RAM,并更改了当前正在启动的特定固件插槽设备的偏移值。

然而,从开始时隙固件主应用程序后,在设备挂起HardFaultIMPRECISERRCFSR寄存器。执行以下行时,它发生在vPortSVCHandler 中

ldmia r0!, {r4-r11, r14}
Run Code Online (Sandbox Code Playgroud)

此操作后,链接寄存器值等于0000 0000

我还应该做些什么来为 STM32 正确创建位置无关的应用程序?重新定位全局偏移表?如果是,在内存中的哪个位置?


编辑

根据以下问题,我的目标是使用引导加载程序和 2 个固件插槽创建应用程序。我需要 FLASH 中的固件插槽,以便我的设备能够在运行时更新。为什么我需要用 PIC 标志编译固件?每个插槽在内存中都有自己的空间。默认情况下,它是为第一个插槽地址编译的。从第二个插槽运行这样的二进制文件,为第一个插槽准备,是不可能的,因为数据访问等(老实说,这是我第一次使用 GOT 和 PIC 编译)是基于程序计数器寄存器值(当前位置在程序存储空间)。固件更新使用当前未使用的下一个空闲插槽。因为我不知道当前正在使用哪个,所以我需要构建可以在所有插槽(在这种情况下为 2)上正常工作的二进制文件。这就是为什么在阅读了许多网站、主题等之后。

我从引导加载程序切换到主应用程序的流程如下:

  1. 检查应该使用哪个固件插槽
  2. 禁用 IRQ。
  3. 将向量表复制到 RAM。两个插槽的那部分 RAM 相同。在复制过程中,我正在更改每个地址的偏移量,因此它们将与特定的固件插槽兼容。默认地址没有偏移,它在编译后阶段被删除。
  4. 根据 RAM 中向量表的第一个字设置堆栈指针。将向量表复制到 RAM 时,该地址不会更改。
  5. 设置 SCB->VTOR。
  6. 执行数据同步屏障 DSB()。
  7. 从复制到 RAM 的向量表跳转到重置处理程序。

在 old_timer 发布答案后编辑

因此,我尝试为两个插槽编译代码。下面是 GOT 反汇编的结果:

Disassembly of section …
Run Code Online (Sandbox Code Playgroud)

linker compilation stm32 cortex-m stm32f4

4
推荐指数
1
解决办法
2294
查看次数

STM32 的 DMA 到闪存

我使用的是 stm32f40x 微控制器 (UC),我必须使用其内部闪存来存储一些数据。写操作,如你所知,非常慢,占用UC很长时间。所以我想到了 DMA,这里是问题:

是否可以使用DMA将数据从SRAM传输到FLASH?

感谢您的时间。

c embedded flash-memory dma stm32f4

4
推荐指数
2
解决办法
2908
查看次数

在RTOS环境中基于ARM Cortex M4的STM32F4控制器构建OpenSSL库

我正在研究在STM32F407微控制器(基于ARM Cortex M4)上开发支持openSSL-FIPS的嵌入式蓝牙应用的可行性.该应用程序不能在Linux,Windows或andriod等通用操作系统上运行,但它可以在CMSIS-RTX RTOS上运行.我在Windows中使用Keil作为开发环境,内置armc编译器(armcc)进行编译.

在我的分析过程中,我找到了OpenSSL wiki,它解释了如何构建和安装openSSL库:编译和安装.在页面中虽然有一个用于ARM平台编译的部分,但没有关于如何进行编译的描述.

我还讨论了关于在ARM中交叉编译openSSL的stackoverflow中的一些讨论.但所有这些讨论都基于ARM + Linux,而且没有一个是在RTOS上.

我在使用ARM编译时也经历了以下链接

但这里指定的编译器是GCC.

  1. 是否有可用于上述平台的库?

  2. 是否可以使用RTOS将openSSL移植到ARM Cortex M4平台?更具体的是可以使用CMSIS RTX将其移植到STM32F407吗?

  3. 如果有可能,我应该从哪里开始,它有多复杂?

  4. 如果我在GCC编译器中编译openSSL库并在armc编译的应用程序中使用它会工作吗?(我有一种感觉,它不会)

  5. 我可以在嵌入式软件中使用哪些其他SSL库?(我听说WolfSSL可能是一个选择)

openssl arm keil cmsis stm32f4

3
推荐指数
1
解决办法
2669
查看次数

stm32F4 pwm输入捕获的高频信号约.2MHz的?

我想测量PWM信号的频率.为此,我使用STM-F401RE及其Timer_Input_Capture函数.

问题是:

  • 输入信号具有相当高的频率(约2MHz),
  • STM-F401RE控制器只有80MHz时钟

因此,当使用中断程序计算输入信号的上升沿数时,它会错过许多上升沿(取决于输入信号的频率).当使用示波器并切换I/O引脚时,我发现它只能在频率低于400kHz时捕获所有上升沿.

问题是:如何克服这个问题?还是有另一种方法来测量高频输入pwm信号?

谢谢

stm32 stm32f4discovery stm32f4

3
推荐指数
1
解决办法
5339
查看次数

STM32F4计时器-计算周期和预分频,并产生1 ms延迟

我使用STM32F407VGT6CubeMX
因此,我从通用计时器开始,但始终陷于预分频和周期值。

基本上我想每隔n(其中n = 1,2,3 ..)ms 生成一个计时器中断并执行一些任务。
公式中有很多变化,可以计算周期和预分摊的值

公式的某些版本是:

TIMupdateFreq(HZ)=时钟/(((PSC-1)*(Period-1))
更新事件= TIM clk /(((PSC + 1)*(ARR + 1)*(RCR + 1))
预分频器=((( (时钟速度)/((周期)/(1 /频率)))+ 0.5)-1)

因此,我的核心时钟运行在,168 MHz但我可以看到定时器连接到APB1 Bus,它正在运行84 MHz

我尝试了一个代码,该代码会产生1 ms的延迟(作者说),在使用该值进行预分频和周期后,我生成了一个代码,该代码也会产生1ms的延迟(直觉-无作用域)。

该代码使用的预分度值为41999,期限为1999。

因此,
PSC-41999
ARR-1999将
其应用于第二个公式

Update Event = TIM clk/((PSC+1)*(ARR+1)*(RCR+1))

Update Event = 84000000/(42000*2000) = 1 (这是1毫秒的延迟吗?)

行,所以我现在想了解如何PSC = 41999Period = 1999选择?它是否纯粹基于假设,如我使用的任何公式中我都必须假设一个变量。如果我想说1.5或2.3或4.9之类的精确计时,如何计算预分频和周期?

编辑

而且,当我使用PSC=41999 and Period =999更新事件值为2时。

Update Event = 84000000/(42000*1000) = …

microcontroller timer stm32 stm32f4 cubemx

3
推荐指数
3
解决办法
9009
查看次数

DMA 模式下 UART 接收数据失败

我正在尝试从 NUCLEO F446RE stm32 板上的电脑接收 8 个字节。传输至电脑即可。问题是,我无法使用 DMA 接收数据。我看到了一个具有几乎相同代码的示例,并且它对这个人有用。如果我使用中断模式(只需将 HAL_UART_Receive_DMA 更改为 HAL_UART_Receive_IT,它确实可以工作并且正在调用 RX Complete 回调。

这是完整的 main.c。DMA 处于循环模式。

main.c
Run Code Online (Sandbox Code Playgroud)

https://pastebin.com/1W4BCjxB

stm32 stm32f4 nucleo cubemx stm32cubeide

3
推荐指数
1
解决办法
6519
查看次数

为什么需要内存别名?

我对 ST Microelectronics 的这种架构设计感到困惑。以STM32F407VG为例。程序加载到闪存中的地址 0x08000000。该地址映射到地址 0x00000000,因为复位后处理器首先查看 0x00000000。为什么不让闪存首地址为 0x00000000。内存别名的优点是什么?

在此处输入图片说明

arm processor cpu-architecture stm32 stm32f4

3
推荐指数
1
解决办法
540
查看次数

STM32 USB CDC Rx 中断

我已经在STM32-F446re(Nucleo)上实现了USB CDC (VCP)。我正在使用int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)in 循环来接收数据。但是很多数据也被发送过来,因此我想要基于接收中断。

谁能帮我了解如何设置 USB CDC Rx 中断?

embedded stm32 stm32f4discovery stm32f4 nucleo

3
推荐指数
1
解决办法
8584
查看次数