标签: stm32

从USB Virtual Com Port设备检测打开的PC COM端口

我正在使用带有STM32_USB-FS-Device_Lib_V3.2.1 USB库的STM32F105微控制器,并根据我们的目的调整了VCP示例(与RTOS和串行API集成).

问题是如果连接了USB电缆,但是Windows主机上没有打开端口,几分钟后设备会永久重新进入USB ISR,直到端口打开然后一切正常开始工作.

我已经检测了中断处理程序并且可以看到当故障发生时,ISR处理程序退出然后立即重新进入.发生这种情况是因为在退出中断时,OTG_FS_GINTSTS中的IEPINT标志不清楚.此时OTG_FS_DAINT包含0x00000002(IEPINT1设置),而DIEPINT1包含0x00000080(TXFE).调用清除TXFE的OTGD_FS_Handle_InEP_ISR()中的行,但该位不清除或立即重新置位.当主机上的COM端口重新打开时,中断结束时OTG_FS_GINTSTS和OTG_FS_DAINT的状态始终为零,并且以正常速率发生进一步的中断.请注意,只有在输出数据但主机没有打开端口时才会出现此问题.如果端口打开或没有输出数据,系统将无限期运行.我相信输出的数据越多,问题就越早出现,但目前这是轶事.

VCP代码有一个状态变量,它接受以下枚举值:

  UNCONNECTED,
  ATTACHED,
  POWERED,
  SUSPENDED,
  ADDRESSED,
  CONFIGURED
Run Code Online (Sandbox Code Playgroud)

我们使用CONFIGURED状态来确定是否将数据放入驱动程序缓冲区以进行发送.但是,当连接电缆而不是主机打开端口并连接应用程序时,将设置CONFIGURED状态.我看到当Windows打开端口时,会出现一连串的中断,所以似乎在这个事件上发生了一些通信; 我想知道是否有可能检测主机是否打开了端口.

我或许需要两件事之一:

  1. 防止USB代码在第一个实例中卡在ISR中
  2. 确定主机是否从设备端打开端口,并且仅在打开时推送数据以进行发送.

embedded usb device cdc stm32

5
推荐指数
1
解决办法
9379
查看次数

USART与STM32f1xx通信

我尝试实现USART通信.所以我将我的STM32f1的RX连接到他的TX.我也为这个沟通写了一个程序.此代码由以下组件组成:

  1. RCC配置
  2. GPIO配置
  3. USART配置
  4. 发送和接收字符串
  5. 发送的字符串和接收的字符串之间的比较
  6. 测试通信是否成功=> LED4亮,否则LED3亮

问题是在所有情况下LED3都会亮起.这意味着数据传输失败.

使用我的IDE(IAR的Embedded Workbench),我编译了这个程序代码:

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "stm32_eval.h"


/* Private typedef -----------------------------------------------------------*/
typedef enum { FAILED = 0, PASSED = !FAILED} TestStatus;

/* Private define ------------------------------------------------------------*/
#define USARTy                   USART1
#define USARTy_GPIO              GPIOA /* PORT name*/
#define USARTy_CLK               RCC_APB2Periph_USART1
#define USARTy_GPIO_CLK          RCC_APB2Periph_GPIOA
#define USARTy_RxPin             GPIO_Pin_10/* pin Rx name*/ 
#define USARTy_TxPin             GPIO_Pin_9 /* pin Tx name*/

#define USARTz                   USART2
#define USARTz_GPIO              GPIOA/* PORT name*/
#define USARTz_CLK               RCC_APB1Periph_USART2
#define USARTz_GPIO_CLK          RCC_APB2Periph_GPIOA
#define USARTz_RxPin …
Run Code Online (Sandbox Code Playgroud)

c stm32

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

嵌入式C++ 11代码 - 我需要volatile吗?

带Cortex M3 MCU的嵌入式设备(STM32F1).它有嵌入式闪存(64K).MCU固件可以在运行时重新编程闪存扇区; 这是由闪存控制器(FMC)寄存器完成的(所以它不像a = b那么容易).FMC获取缓冲区指针并将数据刻录到某个闪存扇区.

我想将最后一个闪存扇区用于设备配置参数.参数存储在带有数组的压缩结构中,并包含一些自定义类.

可以在运行时更改参数(复制到RAM,使用FMC更改并回显到闪存).

所以有一些问题:

  1. FMC硬件改变参数struct的状态(按位).C++编译器不知道它是否被更改. 这是否意味着我应该将所有struct成员声明为volatile? 我想是的.

  2. 应该在编译时静态初始化Struct(默认参数).Struct应该是POD(TriviallyCopyable并具有标准布局).请记住,那里有一些自定义类,所以我记住这些类也应该是POD.但是有一些问题: cppreference.com

    唯一可复制的类型是标量类型,平凡的可复制类,以及此类类型/类的数组(可能是const限定的, 但不是volatile限定的).

这意味着我不能让我的班级POD和易变? 那么我该如何解决这个问题呢?

在参数struct中只能使用标量类型,但它可能会导致配置处理周围的代码更加干净......

PS 它甚至没有易失性,但我担心有一天,一些聪明的LTO编译器会看到静态初始化,不会改变(通过C++)struct并优化对底层内存地址的一些访问.这意味着不会应用新编程的参数,因为它们是由编译器内联的.

编辑:可以在不使用volatile的情况下解决问题.它似乎更正确.

您需要在单独的转换单元(.cpp文件)中定义config struct变量,并且不要初始化变量以避免在LTO期间替换值.如果不使用LTO - 一切正常,因为优化是一次在一个转换单元中完成的,因此不应优化具有静态存储持续时间和在专用转换单元中定义的外部链接的变量.只有LTO可以抛弃它或者在不发出内存提取的情况下进行值替换.特别是在将变量定义为const时.我认为如果不使用LTO,初始化变量是可以的.

c++ embedded arm stm32 c++11

5
推荐指数
1
解决办法
713
查看次数

STM32L0的自动波特率检测

我不能让自动波特率检测工作STM32L0.我正在使用硬件抽象层(HAL).

我的初始化代码是:

/* USART1 init function */
void MX_USART1_UART_Init(void)
{

  huart1.Instance = USART1;
  huart1.Init.BaudRate = 300;
  huart1.Init.WordLength = UART_WORDLENGTH_9B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_EVEN;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  huart1.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_AUTOBAUDRATE_INIT;
  huart1.AdvancedInit.AutoBaudRateEnable = UART_ADVFEATURE_AUTOBAUDRATE_ENABLE;
  huart1.AdvancedInit.AutoBaudRateMode = UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT;
  HAL_UART_Init(&huart1);


}
Run Code Online (Sandbox Code Playgroud)

我通过UART1发送的字节是:

        0   1   2   3   4   5   6   7   8   
000x    68  0B  0B  68  53  FD  52  FF  FF  .. etc.

0x68 = 0b01101000
0x0B = 0b00001011
0xFD = …
Run Code Online (Sandbox Code Playgroud)

c embedded stm32 baud-rate stm32ldiscovery

5
推荐指数
1
解决办法
2005
查看次数

如何在STM32上启动和停止计时器?

我有一个大问题.我不知道如何用按钮停止计时器并用另一个按钮重新启动计时器.

这是我到目前为止的代码:


此代码是启动计时器的按钮的中断处理程序.我认为通过启用到目前为止工作的计时器是可能的.

void EXTI0_1_IRQHandler(void)
{
    if ((EXTI->PR & EXTI_PR_PR1) == EXTI_PR_PR1)  /* Check line 1 has triggered the IT */
    {
        EXTI->PR = EXTI_PR_PR1; /* Clear the pending bit */
        NVIC_EnableIRQ(TIM7_IRQn);

    }
}
Run Code Online (Sandbox Code Playgroud)

此代码是停止计时器的按钮的中断处理程序.这段代码不起作用,计时器保持打开状态.

void EXTI4_15_IRQHandler(void)
{
    if ((EXTI->PR & EXTI_PR_PR4) == EXTI_PR_PR4)  /* Check line 1 has triggered the IT */
    {
        EXTI->PR = EXTI_PR_PR4; /* Clear the pending bit */
        NVIC_DisableIRQ(TIM7_IRQn);
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有人有一些提示或知道它必须如何?

c timer stm32

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

STM32 HAL定时器中断未触发

我正在尝试使用中断从我的STM32F746ZG设备定期发送和串行字符串。大多数代码是由stm32cubemx自动生成的。我在每个中断处都设置了硬件断点(jlink),但在初始化时我只输入了一次周期运行功能。当我随机暂停调试器时,我看到计数器值在0到1000之间,正如预期的那样。所以我知道计数器每秒重置一次。内部时钟以16MHz运行。

我在嵌入式设备方面的经验仅限于BBB,Raspberry和Arduino。我尝试了不同的示例和教程,但此刻我已经不知道了。任何帮助或建议,不胜感激。

我的主要功能:

int main(void) {

    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_RTC_Init();
    MX_TIM1_Init();

    if (HAL_TIM_Base_Start(&htim1) != HAL_OK) {
        Error_Handler();
    }

    if (HAL_TIM_Base_Start_IT(&htim1) != HAL_OK) {
        Error_Handler();
    }

    while (1) {
        cnt = __HAL_TIM_GetCounter(&htim1);
    }
}
Run Code Online (Sandbox Code Playgroud)

TIM1初始化:

static void MX_TIM1_Init(void) {

    TIM_ClockConfigTypeDef sClockSourceConfig;
    TIM_MasterConfigTypeDef sMasterConfig;

    htim1.Instance = TIM1;
    htim1.Init.Prescaler = 16000;
    htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim1.Init.Period = 1000;
    htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim1.Init.RepetitionCounter = 0x0;
    if (HAL_TIM_Base_Init(&htim1) != HAL_OK) {
        Error_Handler();
    }

    sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
    if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) {
        Error_Handler();
    }

    sMasterConfig.MasterOutputTrigger = …
Run Code Online (Sandbox Code Playgroud)

hal timer interrupt stm32 interrupt-handling

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

STM32 HAL USART通过中断接收

我在通过USART接收数据时遇到了一些麻烦。我实际上想要实现的目标是,我可以通过USART接收一个没有特定长度(只有最大可能长度)的命令。因此,我使用中断例程来检查收到的每个字符,但是我仍然无法实现我想要的功能。每当我收到一个新字符时,都会调用该例程,但是由于某种原因HAL_UART_Receive_IT(&huart1,rx_data,buff_size_rx)不能实时升级,因此当我检查rx_data [pointer]时看不到接收到的字符,但是稍后它在rx_data缓冲区中。

到目前为止,我有:

int pointer =0;

...

void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
    if ( USART1->ISR & UART_IT_TXE) {

    }

    if ( USART1->ISR & UART_IT_RXNE) {
        HAL_UART_Receive_IT(&huart1,rx_data,buff_size_rx);
        if(rx_data[pointer]=='\0') {
              pointer=0;
              readCommand(rx_data);
              clearBuffer(rx_data,buff_size_rx);
        } else {
          pointer++;
          if(pointer>=buff_size_rx) {
              pointer=0;
          }
        }
    }
    /* USER CODE END USART1_IRQn 0 */
    HAL_UART_IRQHandler(&huart1);
    /* USER CODE BEGIN USART1_IRQn 1 */



  /* USER CODE END USART1_IRQn 1 */
}
Run Code Online (Sandbox Code Playgroud)

hal stm32

5
推荐指数
2
解决办法
3万
查看次数

如何使用多维数据集MX配置VS Code以构建和调试STM32项目-Windows 10

我是STM32编程领域的新手,并且已经尝试了很长时间了,一直在寻找合适的IDE。我知道其他所有的IDE,例如Keil和IAR,但就目前而言,购买它们只是为了学习而付出的成本对我来说已经太高了。

我已经开始使用VS Code进行越来越多的开发工作,尽管将其用于STM32开发将是一个很好的IDE。在过去的几天中,我在网上找到了许多示例,这些示例说明了如何配置IDE来构建STM32项目,但是它们似乎都缺少重要的信息,而这些信息正是我正确地编译项目所需的。相当令人沮丧

我想知道是否有人可以为我提供有关如何设置VS代码以与cubeMX和arm工具链一起使用的完整设置指南,或者您是否真的很喜欢,请给我一个示例项目,我可以用作基础学习。

仅提供一些背景信息,我知道如何使用cubeMX生成基础项目以及相关的makefile,并且还安装了最新的GNU-Tools-Arm-Embedded。

预先感谢您的帮助

stm32 visual-studio-code vscode-settings cubemx

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

如何写入STM32 Flash

我想从我的用户代码写入 STM32F407VGT 的闪存扇区 11 以存储一些数据。我用过stm32f4xx_hal_flash.c图书馆。我首先使用以下代码擦除扇区:

void Flash_Init(void)
{        
    FLASH_EraseInitTypeDef pEraseInit;

    pEraseInit.Banks = FLASH_BANK_1;
    pEraseInit.NbSectors = 1;
    pEraseInit.Sector = FLASH_SECTOR_10;
    pEraseInit.VoltageRange = FLASH_VOLTAGE_RANGE_3;
    pEraseInit.TypeErase = FLASH_TYPEERASE_SECTORS;

    if(HAL_FLASH_Unlock() == HAL_OK)
    {
        __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGSERR );
        HAL_FLASHEx_Erase(&pEraseInit,0);
        HAL_FLASH_Lock();
    }
}
Run Code Online (Sandbox Code Playgroud)

程序在到达HAL_FLASHEx_Erase(&pEraseInit,0);函数时挂起。我的分散文件如下所示:

LR_IROM1 0x08000000 0x01000000  {    ; load region size_region
  ER_IROM1 0x08000000 0x01000000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00020000  {  ; RW data …
Run Code Online (Sandbox Code Playgroud)

stm32 flash-memory stm32f4discovery stm32f4 stm32-hal

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

如果不使用const,则在RAM中进行不必要的分配,尽管放置在Flash绝对地址中

我正在使用GCC。我在Flash中通过.ld链接器文件创建了一个SECTION,我在其中放置了一些数据(704字节),并带有指令__attribute__((section... Data似乎在Flash中,但是如果我const在声明数据时不使用关键字,则会在RAM中分配相同的空间。

如果我不使用constRAM,则不会使用-但我注意到增加了对Flash的使用,因为它被分配了两次!

链接器文件:

FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 14K
USER_DATA_FLASH (rx)      : ORIGIN = 0x8003800, LENGTH = 2K
}

SECTIONS
{ /* placing my named section at given address: */
  .my_block 0x8003800 :
 {
  KEEP(*(.UserDataSector)) 
 } > USER_DATA_FLASH
}
Run Code Online (Sandbox Code Playgroud)

数组声明具有初始化程序:

mytab_type  __attribute__((section (".UserDataSector "))) progr16[16]=
{ 
    { {LIST1,LIST2....
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我没有使用const。假设这progr16被强制放在闪存中,并且如果在调试过程中我使用内存浏览器检查的话,它看起来确实在那里。但它似乎也占用RAM

FLASH    RAM
text     data    bss   dec     
9268     772     1948  11988    
Run Code Online (Sandbox Code Playgroud)

如果我添加const关键字:

FLASH    RAM
text     data    bss …
Run Code Online (Sandbox Code Playgroud)

c attributes gcc const stm32

5
推荐指数
1
解决办法
125
查看次数