标签: stm32

Cortex-M3初始化

我写了(IMO)几乎最简单的ARM应用程序,它没有工作:)什么可能是错的?错过了什么?

闪存写入和CPU复位后,寄存器中有垃圾.

请善待,如果你知道,请告诉我在STM32F1上运行最简单的应用程序需要做些什么.

也许是某人可以列举在申请开始前必须做的事情,即.

  1. 初始化堆栈(有必要吗?)
  2. 设置一些东西
  3. 设置别的东西.

应用程序:

@Directives
    .thumb                  @.code 16
    .syntax unified

.section .text
    .org 0                  @ Alters location of pointer - in this case set to zero

vectors:                    @ Define basic vectors for specific capabilities
    .word _start + 1        @ Set - start address and increment pointer
    .word _nmi_handler + 1  @ Below all other vectors will be declared:
    .word _hard_fault + 1
    .word _memory_fault + 1
    .word _bus_fault + 1
    .word _usage_fault + 1

_start:
    mov …
Run Code Online (Sandbox Code Playgroud)

assembly cortex-m3 stm32

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

I2C从机 - 时钟延长

你们知道如何为I2C奴隶启用时钟延长吗?

将此函数I2C_StretchClockCmd(I2C2, ENABLE)放入I2C初始化是否足够?

时钟拉伸如何正常工作?

stm32 i2c

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

stm32 SPI + DMA

我尝试使用DMA通道使用SPI发送数据.当我在没有DMA的情况下发送一切都没问题,但是用DMA确实是错误的.当我调试我的程序时,SPI DR寄存器始终为0.我想使用dma循环模式一直发送我的数组.有我的代码GPIO INIT:

GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(SPI_PERIPH_CLOCK, ENABLE);
RCC_AHBPeriphClockCmd(GPIO_PERIPH_CLOCK, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

GPIO_PinAFConfig(GPIOB, AF_PIN_SOURCE, GPIO_AF);

GPIO_InitStructure.GPIO_Pin = GPIO_PIN_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOB, &GPIO_InitStructure);
Run Code Online (Sandbox Code Playgroud)

SPI INIT

SPI_I2S_DeInit(SPI1);

SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);

SPI_Cmd(SPI1, ENABLE);
Run Code Online (Sandbox Code Playgroud)

DMA INIT:

    DMA_InitTypeDef dma;
    DMA_DeInit(DMA1_Channel1);
    DMA_StructInit(&dma);

    dma.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR;
    dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    dma.DMA_PeripheralDataSize …
Run Code Online (Sandbox Code Playgroud)

c embedded spi stm32 dma

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

暂停调试器时STM32冻结周边

调试器可以在到达断点或用户暂停代码执行时停止在Cortex中执行代码。但是,当皮质停止在暂停状态下执行代码时,调试器是否冻结其他外围变量,如DMA,UART和TIMERS?

debugging gdb arm stm32

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

stm32l4 RTC HAL无法正常工作

我在带有FreeRTOS的stm32L476上的RTC上有一个奇怪的行为。

它仅在RUN模式下第一次读取,RTC正在工作,因为从运行到运行,它保存了内部寄存器的值并且一直在上升。

另外,如果我在583行的stm32l4xx_hal_rtc.c处放置断点时进行调试,则:

tmpreg = (uint32_t)(hrtc->Instance->TR & RTC_TR_RESERVED_MASK);    
*breakpoint* sTime->Hours = (uint8_t)((tmpreg & (RTC_TR_HT | RTC_TR_HU)) >> 16);
Run Code Online (Sandbox Code Playgroud)

我可以看到tmpreg和TR寄存器如何更新,然后单击跳转到下一个断点时,显示的内容也相同。

那么,为什么在正常运行时它不起作用?

初始化代码(生成多维数据集MX):

void MX_RTC_Init(void)
{
  RTC_TimeTypeDef sTime;
  RTC_DateTypeDef sDate;

    /**Initialize RTC Only 
    */
  hrtc.Instance = RTC;
  hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
  hrtc.Init.AsynchPrediv = 127;
  hrtc.Init.SynchPrediv = 255;
  hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
  hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
  hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  if (HAL_RTC_Init(&hrtc) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Initialize RTC and set the Time and Date 
    */
  if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0) != 0x32F2){
  sTime.Hours = 0; …
Run Code Online (Sandbox Code Playgroud)

c hal stm32 freertos real-time-clock

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

STM32 SPI慢速计算

我正在使用STM32F4及其SPI与本教程中的74HC595进行通信。区别在于初学者,为简单起见,我使用非DMA版本。我使用STMCubeMX配置SPI和GPIO

问题是:我没有获得锁存器PIN,我将其设置为PA8以在传输期间足够快地切换。

在此处输入图片说明

我正在使用的代码:

        spiTxBuf[0] = 0b00000010;

        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);


        HAL_SPI_Transmit(&hspi1, spiTxBuf, 1, HAL_MAX_DELAY);
//        while(HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);

        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);

        HAL_Delay(1);
Run Code Online (Sandbox Code Playgroud)

我尝试过的事情:

  1. 将引脚PA8的最大输出速度设置为非常快 在此处输入图片说明

  2. 等待SPI完成(请参见上面的注释行)

  3. 如此处所示,将DMA用于SPI,这实际上使它变慢了。

我如何才能更快地切换?我应该在SPI完成后创建并中断并在那里设置锁存器吗?

embedded spi stm32

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

arm-none-eabi-gcc 生成的代码是否比 Keil uVision 慢

我有一个在 STM32f103C8 上运行的简单闪烁 LED 程序(没有初始化样板):

void soft_delay(void) {
    for (volatile uint32_t i=0; i<2000000; ++i) { }
}

  uint32_t iters = 0;
  while (1)
  {
    LL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    soft_delay();
    ++iters;
  }
Run Code Online (Sandbox Code Playgroud)

它是用Keil uVision v.5(默认编译器)和CLionusingarm-none-eabi-gcc编译器编译的。令人惊讶的是,arm-none-eabi-gcc 程序在发布模式 (-O2 -flto) 下运行速度慢 50%,在调试模式下运行速度慢 100%。

我怀疑有3个原因:

  • Keil过度优化(不太可能,因为代码很简单)

  • 由于错误的编译器标志,arm-none-eabi-gcc 优化不足(我使用 CLion Embedded 插件`CMakeLists.txt)

  • 初始化中的一个错误,导致芯片在使用arm-none-eabi-gcc时具有较低的时钟频率(待调查)

我还没有深入到优化和反汇编的丛林中,我希望有许多经验丰富的嵌入式开发人员已经遇到过这个问题并有答案。

更新1

通过尝试 Keil ArmCC 的不同优化级别,我了解了它如何影响生成的代码。它影响很大,尤其是执行时间。soft_delay()以下是每个优化级别的基准测试和函数反汇编(RAM 和 Flash 数量包括初始化代码)。

-O0:RAM:1032,闪存:1444,执行时间(20 次迭代):18.7 秒

soft_delay PROC
        PUSH     {r3,lr}
        MOVS     r0,#0
        STR      r0,[sp,#0]
        B        |L6.14|
|L6.8|
        LDR      r0,[sp,#0]
        ADDS …
Run Code Online (Sandbox Code Playgroud)

c gcc arm stm32

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

STM32 USB CDC 长包接收

我需要将数据从PC发送到我的STM32F3,所以我决定使用uC中的内置USB。但现在我有一个问题 - 我想一次向 stm32 发送大量数据 - 我的意思是 200-500 字节之类的数据。

当我从 PC 发送少于 64 个图表的 minicom 数据包时 - 一切都很好 - 回调 CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) 发生一次 - 它启用 UsbRxFlag,只是为了通知正在运行的程序有可用数据。

static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
  /* USER CODE BEGIN 6 */
  USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
  USBD_CDC_ReceivePacket(&hUsbDeviceFS);
  if( (Buf[0] == 'A') & (Buf[1] == 'T') ){
      GPIOB->BSRR = (uint32_t)RX_Led_Pin;
      UsbRxFlag = 1;
  }

  return (USBD_OK);
  /* USER CODE END 6 */
}
Run Code Online (Sandbox Code Playgroud)

但是当我尝试向 uC 发送更多数据(只是来自 minicom 的长文本)时,会发生一些奇怪的事情 - 有时 uC 根本没有反应 - 有时它不考虑某些数据。 …

c usbserial cdc stm32

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

stm32 NVIC_EnableIRQ() 裸机等效吗?

我正在使用蓝色药丸,并试图找出中断。我有一个中断处理程序:

void __attribute__ ((interrupt ("TIM4_IRQHandler"))) myhandler()
{
    puts("hi");
    TIM4->EGR |= TIM_EGR_UG; // send an update even to reset timer and apply settings
    TIM4->SR &= ~0x01; // clear UIF
    TIM4->DIER |= 0x01; // UIE
}
Run Code Online (Sandbox Code Playgroud)

我设置了定时器:

    RCC_APB1ENR |= RCC_APB1ENR_TIM4EN;
    TIM4->PSC=7999;
    TIM4->ARR=1000;
    TIM4->EGR |= TIM_EGR_UG; // send an update even to reset timer and apply settings
    TIM4->EGR |= (TIM_EGR_TG | TIM_EGR_UG);
    TIM4->DIER |= 0x01; // UIE enable interrupt
    TIM4->CR1 |= TIM_CR1_CEN;
   
Run Code Online (Sandbox Code Playgroud)

我的计时器似乎没有启动。但我认为我并没有真正启用它。我有没有??

我在很多示例代码命令中看到,例如:

NVIC_EnableIRQ(USART1_IRQn);
Run Code Online (Sandbox Code Playgroud)

NVIC_EnableIRQ() 到底发生了什么?

我用谷歌搜索过,但找不到与我的功能类似的实际裸机代码。

我似乎错过了关键的一步。

更新2020-09-23感谢本问题的回答者。技巧是在 NVIC_ISER 寄存器中设置中断号位。正如我在下面指出的,STM32F101xx …

interrupt bare-metal stm32

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

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
查看次数