硬汉嵌入式论坛

 找回密码
 立即注册
查看: 200|回复: 3
收起左侧

[有问必答] 程序进入hardfault出错

[复制链接]

3

主题

5

回帖

14

积分

新手上路

积分
14
发表于 7 天前 | 显示全部楼层 |阅读模式
单片机STM32G474RBT6(相关硬件未到,先烧录在STM32G474VE6开发板上测试,手册都同一个,这样应该没问题吧) ,  调试发现程序一开始调试就会会进入hardfault Handler。此外还发现:在 if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) == 0U)中,uwTickFreq正常时是1,但现在是很大的值(uwTickFreq    uint32_t    4294967295(0xffffffff)), (1000U / uwTickFreq)约为0,SystemCoreClock /0也会触发hardfault Handler。
/**
  * @brief This function configures the source of the time base:
  *        The time source is configured to have 1ms time base with a dedicated
  *        Tick interrupt priority.
  * @note This function is called  automatically at the beginning of program after
  *       reset by HAL_Init() or at any time when clock is reconfigured  by HAL_RCC_ClockConfig().
  * @note In the default implementation, SysTick timer is the source of time base.
  *       It is used to generate interrupts at regular time intervals.
  *       Care must be taken if HAL_Delay() is called from a peripheral ISR process,
  *       The SysTick interrupt must have higher priority (numerically lower)
  *       than the peripheral interrupt. Otherwise the caller ISR process will be blocked.
  *       The function is declared as __weak  to be overwritten  in case of other
  *       implementation  in user file.
  * @param TickPriority: Tick interrupt priority.
  * @retval HAL status
  */
__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
  HAL_StatusTypeDef  status = HAL_OK;

  if (uwTickFreq != 0U)
  {
    /* Configure the SysTick to have interrupt in 1ms time basis*/
    if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) == 0U)
    {
      /* Configure the SysTick IRQ priority */
      if (TickPriority < (1UL << __NVIC_PRIO_BITS))
      {
        HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U);
        uwTickPrio = TickPriority;
      }
      else
      {
        status = HAL_ERROR;
      }
    }
    else
    {
      status = HAL_ERROR;
    }
  }
  else
  {
    status = HAL_ERROR;
  }

  /* Return function status */
  return status;
}

测试发现如果注释掉这段代码就正常了:
/*******************************************************************************
* @brief sub slove, obation angle based on gary code section and arctan
*
* @param pGE - graycode encdoer struct pointer
*
* @return
*******************************************************************************/
void Encoder_Solve_Subdivide(struct graycode_encoder* pGE)
{
        float temp_angle = 0;
        float X_synth;
        float Y_synth;
        float X_rot;
        float Y_rot;
        //用于解算
    X_synth = pGE->channel_val_outer[3] + pGE->channel_val_outer[4] * (sqrt(3) / 2) + pGE->channel_val_outer[5] * (0.5) + pGE->channel_val_outer[1] * (0.5) + pGE->channel_val_outer[2] * (sqrt(3) / 2);  //系数:1 cosd(30) cosd(60) sind(30) sind(60)
    Y_synth = pGE->channel_val_outer[0] + pGE->channel_val_outer[1] * (sqrt(3) / 2) + pGE->channel_val_outer[2] * (0.5) - pGE->channel_val_outer[4] * (0.5) - pGE->channel_val_outer[5] * (sqrt(3) / 2);  //系数:1 cosd(30) cosd(60) -sind(30) -sind(60)
    X_rot = X_synth * cos(rotation_angle[pGE->rough_section]) + Y_synth * sin(rotation_angle[pGE->rough_section]);
    Y_rot = Y_synth * cos(rotation_angle[pGE->rough_section]) - X_synth * sin(rotation_angle[pGE->rough_section]);

    temp_angle = atan2f(Y_rot, X_rot);
    temp_angle = rad2deg(temp_angle);

    if(pGE->Cali_flag == 0)
    {
            temp_angle = pow(temp_angle, 5) * pGE->cali_factor[pGE->rough_section][0] + pow(temp_angle, 4) * pGE->cali_factor[pGE->rough_section][1] + pow(temp_angle, 3) * pGE->cali_factor[pGE->rough_section][2] + pow(temp_angle, 2) * pGE->cali_factor[pGE->rough_section][3]+ pow(temp_angle, 1) * pGE->cali_factor[pGE->rough_section][4]+ pGE->cali_factor[pGE->rough_section][5];
    }

        pGE->Absolute_Angle = temp_angle;  //解算出绝对角度
        pGE->angle = AdjustAngleZeroPoint(pGE->Set_CurrentPositionAngle_0, pGE->Absolute_Angle);  //调整零度位置
}



对应对应结构体:
struct channel_parameter_inner
{
    float offset_inner;            //内圈偏移值
    float gain_inner;                //内圈增益
};

struct channel_parameter_outer
{
    float offset_outer;                //外圈偏移值
    float gain_outer;                //外圈增益
};  
struct graycode_encoder
{
    struct channel_parameter_inner chan_param_inner[6];  
    struct channel_parameter_outer chan_param_outer[6];  

    float channel_val_inner[6];        
    float channel_val_outer[6];        

    float cali_factor[168][6];   

    int32_t adc_val[12];         

    uint16_t rough_section;               

    float angle;                          
    float Absolute_Angle;               
    float Set_CurrentPositionAngle_0;   
    enum calibration_state  Cali_flag;
}__attribute__((aligned(4)));  // 强制4字节对齐   

有大佬遇到过类似问题么,求解惑









回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
119429
QQ
发表于 7 天前 | 显示全部楼层
前面楼主的描述没太懂,硬件还没到,当前是软件模拟测试的吗
回复

使用道具 举报

3

主题

5

回帖

14

积分

新手上路

积分
14
 楼主| 发表于 7 天前 | 显示全部楼层
eric2013 发表于 2025-11-14 13:34
前面楼主的描述没太懂,硬件还没到,当前是软件模拟测试的吗

在STM32CUBEIDE上选的芯片是STM32G474RBT6,程序按该芯片写的,最后程序烧录在了STM32G474VET6开发板上,然后对程序功能进行测试;补充:SystemCoreClock:4 字节0xFF;
uwTickPrio:4 字节0xFF;
uwTickFreq:4 字节0xFF。像是被连续覆盖,可能有数组越界
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
119429
QQ
发表于 7 天前 | 显示全部楼层
xigua580 发表于 2025-11-14 15:07
在STM32CUBEIDE上选的芯片是STM32G474RBT6,程序按该芯片写的,最后程序烧录在了STM32G474VET6开发板上, ...

按说是可以的,注意晶振HSE_VALUE设置和你现在测试的板子是否一致就行。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-11-21 20:53 , Processed in 0.040236 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表