【问题标题】:STM32L4 and accelerometer programSTM32L4和加速度计程序
【发布时间】:2022-01-22 20:59:37
【问题描述】:

我正在尝试为 MEMS 加速度计的服务制作程序。 我正在使用操纵杆端口 E 的三个引脚(joy_left、joy_right、joy_down)来改变轴 x、y 和 z。 该程序的最终目标是显示 4 位数字 7段显示器:

  • 第一个数字代表轴 (x, y, z) 中的一个,使用范围从 1 到 3 的数字
  • 倒数第二个数字必须代表其轴的加速度计值的三位数字

我在 main.c 中的代码:

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "kamami_l496_mems.h"

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);

/* USER CODE BEGIN PFP */
void switchInit(void);
void baseTransistInit(void);
void segmentsInit();
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
  __HAL_RCC_GPIOG_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOE_CLK_ENABLE();
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */
  HAL_PWREx_EnableVddIO2();
  switchInit();
  baseTransistInit();
  segmentsInit();
  mems_init(MEMS_ACC_DATARATE_10HZ, MEMS_ACC_FULLSCALE_2G);

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */
  SysTick_Config(SystemCoreClock / 1000); // SysTick_Handler() called within 1ms

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
  RCC_OscInitStruct.MSIState = RCC_MSI_ON;
  RCC_OscInitStruct.MSICalibrationValue = 0;
  RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */



void switchInit(void)
{
    GPIO_InitTypeDef Joys;
    Joys.Mode = GPIO_MODE_INPUT;
    Joys.Pin = GPIO_PIN_1 /* JOY_LEFT */ | GPIO_PIN_0 /* JOY_RIGHT */ | GPIO_PIN_3 /* JOY_DOWN*/;
    Joys.Pull = GPIO_PULLUP;
    Joys.Speed = GPIO_SPEED_LOW;
    Joys.Alternate = 0;
    HAL_GPIO_Init(GPIOE, &Joys);
}

void baseTransistInit(void)
{
    GPIO_InitTypeDef Transistors;
    Transistors.Mode = GPIO_MODE_OUTPUT_PP;
    Transistors.Pin = GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5;
    Transistors.Pull = GPIO_NOPULL;
    Transistors.Speed = GPIO_SPEED_LOW;
    Transistors.Alternate = 0;
    HAL_GPIO_Init(GPIOB, &Transistors);
}

void segmentsInit()
{
    GPIO_InitTypeDef Segments;
    Segments.Mode = GPIO_MODE_OUTPUT_PP;
    Segments.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_9;
    Segments.Pull = GPIO_NOPULL;
    Segments.Speed = GPIO_SPEED_LOW;
    Segments.Alternate = 0;
    HAL_GPIO_Init(GPIOG, &Segments);
}
/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

我正在尝试使用 SysTick 中断,因此我将在此处显示文件“stm32l4xx_it.c”中的代码:

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    stm32l4xx_it.c
  * @brief   Interrupt Service Routines.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32l4xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include "kamami_l496_mems.h"
#include  <string.h>
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */

/* USER CODE END TD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define SEG_A 0
#define SEG_B 1
#define SEG_C 2
#define SEG_D 3
#define SEG_E 4
#define SEG_F 5
#define SEG_G 6
#define SEG_DP 9
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
int buttonMs = 0;
int buttonDelay = 500;
const uint16_t  tableOfSegments[] =  {
        1 << SEG_A | 1 << SEG_B | 1 << SEG_C | 1 << SEG_D | 1 << SEG_E | 1 << SEG_F,              // DIGIT 0
        1 << SEG_B | 1 << SEG_C,                                                                  // DIGIT 1
        1 << SEG_A | 1 << SEG_B | 1 << SEG_E | 1 << SEG_D | 1 << SEG_G,                           // DIGIT 2
        1 << SEG_A | 1 << SEG_B | 1 << SEG_C | 1 << SEG_D | 1 << SEG_G,                           // DIGIT 3
        1 << SEG_B | 1 << SEG_C | 1 << SEG_G | 1 << SEG_F,                                        // DIGIT 4
        1 << SEG_A | 1 << SEG_F | 1 << SEG_G | 1 << SEG_C | 1 << SEG_D,                           // DIGIT 5
        1 << SEG_A | 1 << SEG_F | 1 << SEG_G | 1 << SEG_C | 1 << SEG_D | 1 << SEG_E,              // DIGIT 6
        1 << SEG_A | 1 << SEG_B | 1 << SEG_C,                                                     // DIGIT 7
        1 << SEG_A | 1 << SEG_B | 1 << SEG_C | 1 << SEG_D | 1 << SEG_E | 1 << SEG_F | 1 << SEG_G, // DIGIT 8
        1 << SEG_A | 1 << SEG_B | 1 << SEG_C | 1 << SEG_D | 1 << SEG_F | 1 << SEG_G,              // DIGIT 9

};
int showX = 1;
int showY = 0;
int showZ = 0;

float x, y, z;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */

void inputHandling();
void makeDigitFromFloatValue(int pos, float input, int * digitToSet);
void showDigit(const char * digitName);
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
struct mems_xyz_res acc; // structure for accelerometr results
/* USER CODE END 0 */

/* External variables --------------------------------------------------------*/

/* USER CODE BEGIN EV */

/* USER CODE END EV */

/******************************************************************************/
/*           Cortex-M4 Processor Interruption and Exception Handlers          */
/******************************************************************************/
/**
  * @brief This function handles Non maskable interrupt.
  */
void NMI_Handler(void)
{
  /* USER CODE BEGIN NonMaskableInt_IRQn 0 */

  /* USER CODE END NonMaskableInt_IRQn 0 */
  /* USER CODE BEGIN NonMaskableInt_IRQn 1 */
  while (1)
  {
  }
  /* USER CODE END NonMaskableInt_IRQn 1 */
}

/**
  * @brief This function handles Hard fault interrupt.
  */
void HardFault_Handler(void)
{
  /* USER CODE BEGIN HardFault_IRQn 0 */

  /* USER CODE END HardFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_HardFault_IRQn 0 */
    /* USER CODE END W1_HardFault_IRQn 0 */
  }
}

/**
  * @brief This function handles Memory management fault.
  */
void MemManage_Handler(void)
{
  /* USER CODE BEGIN MemoryManagement_IRQn 0 */

  /* USER CODE END MemoryManagement_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
    /* USER CODE END W1_MemoryManagement_IRQn 0 */
  }
}

/**
  * @brief This function handles Prefetch fault, memory access fault.
  */
void BusFault_Handler(void)
{
  /* USER CODE BEGIN BusFault_IRQn 0 */

  /* USER CODE END BusFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_BusFault_IRQn 0 */
    /* USER CODE END W1_BusFault_IRQn 0 */
  }
}

/**
  * @brief This function handles Undefined instruction or illegal state.
  */
void UsageFault_Handler(void)
{
  /* USER CODE BEGIN UsageFault_IRQn 0 */

  /* USER CODE END UsageFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_UsageFault_IRQn 0 */
    /* USER CODE END W1_UsageFault_IRQn 0 */
  }
}

/**
  * @brief This function handles System service call via SWI instruction.
  */
void SVC_Handler(void)
{
  /* USER CODE BEGIN SVCall_IRQn 0 */

  /* USER CODE END SVCall_IRQn 0 */
  /* USER CODE BEGIN SVCall_IRQn 1 */

  /* USER CODE END SVCall_IRQn 1 */
}

/**
  * @brief This function handles Debug monitor.
  */
void DebugMon_Handler(void)
{
  /* USER CODE BEGIN DebugMonitor_IRQn 0 */

  /* USER CODE END DebugMonitor_IRQn 0 */
  /* USER CODE BEGIN DebugMonitor_IRQn 1 */

  /* USER CODE END DebugMonitor_IRQn 1 */
}

/**
  * @brief This function handles Pendable request for system service.
  */
void PendSV_Handler(void)
{
  /* USER CODE BEGIN PendSV_IRQn 0 */

  /* USER CODE END PendSV_IRQn 0 */
  /* USER CODE BEGIN PendSV_IRQn 1 */

  /* USER CODE END PendSV_IRQn 1 */
}

/**
  * @brief This function handles System tick timer.
  */
void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */
  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */
  static int miliSec = 0;
  inputHandling();
  int digitOf4Sec = miliSec % 4;
  switch(digitOf4Sec)
  {
      case 0:
          showDigit("axis");
          break;
      case 1: // digit 2
          showDigit("first");
          break;
      case 2: // digit 3
          showDigit("second");
          break;
      case 3: // digit 4
          showDigit("third");
          break;
  }
  if(miliSec != 0)
  {
      if(miliSec / 1000 == 4)
          miliSec = 0;
      if(miliSec % 1000 == 0)
      {

          x = acc.x * 2.0f / MEMS_ACC_MAXVAL;
          y = acc.y * 2.0f / MEMS_ACC_MAXVAL;
          z = acc.z * 2.0f / MEMS_ACC_MAXVAL;
      }
  }
  mems_acc_read_xyz(&acc);
  miliSec++;

  /* USER CODE END SysTick_IRQn 1 */
}

/******************************************************************************/
/* STM32L4xx Peripheral Interrupt Handlers                                    */
/* Add here the Interrupt Handlers for the used peripherals.                  */
/* For the available peripheral interrupt handler names,                      */
/* please refer to the startup file (startup_stm32l4xx.s).                    */
/******************************************************************************/

/* USER CODE BEGIN 1 */
void inputHandling()
{
    buttonMs++;
    if(buttonMs < buttonDelay)
        return;
    if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_0) == GPIO_PIN_RESET) //      JOY RIGHT, Y
    {
        showX = 0;
        showY = 1;
        showZ = 0;
    }
    else if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_1) == GPIO_PIN_RESET) // JOY LEFT,  X
    {
        showX = 1;
        showY = 0;
        showZ = 0;
    }
    else if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_2) == GPIO_PIN_RESET) // JOY DOWN,  Z
    {
        showX = 0;
        showY = 0;
        showZ = 1;
    }
    if(buttonMs == buttonDelay)
        buttonMs = 0;

}

void makeDigitFromFloatValue(int pos, float input, int * digitToSet)
{
    if(input < 0)
    {
        input *= -1;
    }

    int number = input * 100;
    if(input < 10)
    {
        if(pos == 1)
            *digitToSet = 0;
        else if(pos == 2)
            *digitToSet = 0;
        else
            *digitToSet = number % 10;
    }
    else if(input < 100)
    {
        if(pos == 1)
            *digitToSet = 0;
        else if(pos == 2)
        {
            number /= 10;
            *digitToSet = number % 10;
        }
        else
            *digitToSet = number % 10;
    }

}

void showDigit(const char * digitName)
{
    HAL_GPIO_WritePin(GPIOG, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_9, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5, GPIO_PIN_RESET);
    if(strcmp(digitName, "axis") == 0)
    {
        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);
        if(showX)
        {
            HAL_GPIO_WritePin(GPIOG, tableOfSegments[1], GPIO_PIN_SET);
        }
        else if(showY)
        {
            HAL_GPIO_WritePin(GPIOG, tableOfSegments[2], GPIO_PIN_SET);
        }
        else if(showZ)
        {
            HAL_GPIO_WritePin(GPIOG, tableOfSegments[3], GPIO_PIN_SET);
        }
        return;
    }
    int digitToShow;
    if(strcmp(digitName, "first") == 0)
    {
        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);
        makeDigitFromFloatValue(1, x, &digitToShow);
    }
    else if(strcmp(digitName, "second") == 0)
    {
        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);
        makeDigitFromFloatValue(2, x, &digitToShow);
    }
    else if(strcmp(digitName, "third") == 0)
    {
        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
        makeDigitFromFloatValue(3, x, &digitToShow);
    }
    HAL_GPIO_WritePin(GPIOG, tableOfSegments[digitToShow], GPIO_PIN_SET);
}


/* USER CODE END 1 */

目前我遇到了以下问题:

  • 只有第一个数字显示负责轴。除此之外没有其他数字。用操纵杆改变轴也不起作用。 我猜是因为 SysTickHandler 中断函数中的一行:
mems_acc_read_xyz(&acc);

用户@atune 正确指出了这样一个事实,即获取加速值的数据需要超过 1 毫秒的时间,并且与每 1 毫秒调用一次的 SysTick 中断发生冲突。对于我正在执行的任务,我无法向 main() 函数的无限循环添加任何内容,因此我只需要使用中断来完成它。 我搬家了:

mems_acc_read_xyz(&acc);

到 if,其中 x、y 和 z 用加速值初始化:

      if(miliSec % 1000 == 0)
      {
          mems_acc_read_xyz(&acc);
          x = floorf((acc.x * 2.0f / MEMS_ACC_MAXVAL) * 100) / 100; //acc.x * 2.0f / MEMS_ACC_MAXVAL;
          y = floorf((acc.y * 2.0f / MEMS_ACC_MAXVAL) * 100) / 100; //acc.y * 2.0f / MEMS_ACC_MAXVAL;
          z = floorf((acc.z * 2.0f / MEMS_ACC_MAXVAL) * 100) / 100; //acc.z * 2.0f / MEMS_ACC_MAXVAL;
      }

现在显示轴的变化和加速值。但这些是正确的吗?当我移动板时,我得到每个轴的值,但仅从 0.00 到 0.09。我认为这里也有问题,最大范围应该更高?这个问题与我的功能有关吗makeDigitFromFloatValue(int pos, float input, int * digitToSet)?

提前感谢您的所有回答。

【问题讨论】:

  • 问一些简单的具体问题。不要要求我们为您调试、解释器件数据表或编写程序。你的问题太笼统了:uncertainty about getting correct acceleration values and showing it. Is my idea to do this correct or is it something I need to add / rebuild? Thank you in advance for all your answers投票结束

标签: c embedded accelerator


【解决方案1】:

首先,您应该仔细阅读您的代码并思考每一行的作用。或许首先考虑一下您希望代码做什么,并通过在代码中注释您的意图来记录它。

一目了然,在您的示例 stm32l4xx_it.c 中,首先是 SysTick_Handler:

static int miliSec = 0;

miliSec 是有符号整数,它可以变成负值。如果您决定让它一直递增直到溢出,请记住这一点。

您将 miliSec 除以 4 的余数转换为 digitOf4Sec。也就是说 digitOf4Sec 只能是 0、1、2 或 3。

digitOf4Sec = miliSec % 4;
// 0 % 4 = 0
// 1 % 4 = 1
// 2 % 4 = 2
// 3 % 4 = 3
// 4 % 4 = 0
// 5 % 4 = 1
// etc.

然后您使用 digitOf4Sec 并且仅在 digitOf4Sec 除以 4 为 0 时输入您的 switch-case。由于整数截断,它始终为 0。

// (digitOf4Sec CAN ONLY BE 0, 1, 2, or 3 like stated before)
// 0 / 4 = 0
// 1 / 4 = 0
// 2 / 4 = 0
// 3 / 4 = 0
if((digitOf4Sec / 4) == 0)
{
    switch(digitOf4Sec)
    {
        // digitOf4Sec is always 0
        case 0:
            showDigit("axis");
        ...

答案 1.) ...所以在您的 switch-case 中,除了 case 0 之外,您永远不能输入任何内容,因为 'digitOf4Sec / 4' 始终为 0。这是什么意思由 “只有第一个数字显示负责轴。除此之外没有其他数字。”?如果是,这就是你的答案。其他情况是不可能的。

最后你显然想每 4 秒清除一次计数器并每 1000 毫秒更新一次加速度值?

if(miliSec != 0)
{
    if(miliSec / 1000 == 4)
        miliSec = 0;
    if(miliSec % 1000 == 0)
    {
        // x-y-z acceleration value update code
    }
}

miliSec++;

我不明白 4 秒的部分,但我想它工作得很好。

关于加速度计值。我假设您正在使用带有 LSM303C 电子罗盘的 KAmeleon-STM32L4 套件。在 main.c 中,您将加速度计配置为 2G 满量程。加速度计具有 16 位值,因此范围为 -32768...32767,其中 -32767 为 -2G,0 为 0G,+32767 为 +2G。换句话说,1 LSB 是 (1/32767G) ~= 0.000061G。

关于你的转化代码

x = acc.x * 2.0f / 32678.0f;
y = acc.y * 2.0f / 32678.0f;
z = acc.z * 2.0f / 32678.0f;

答案 2.) 没关系,可能工作得很好,但你有一个错字。 32678 当然应该是 32768。此外,它可能更像 32767,但这不是一个大问题,只是杯水车薪。

将来您可能要考虑明确使用的值。什么是2.0,什么是32768.0,它们为什么会存在?如果您决定将满量程从 2G 更改为 4G/8G,或者您想测试不同的范围,您是否总是想手动更改幻数?

哦,(不-)答案 3。) 用操纵杆改变轴也不起作用。你需要考虑自己,这并不容易对您的代码进行推理,尤其是在没有使用过的硬件和全貌的情况下。您需要调试代码并仔细检查您在做什么。顺便说一句,实际上是操纵杆向下PE2。您正在阅读 PE3 上的内容吗?

其他cmets:

一)

void showDigit(const char * digitName)

为什么基于 c-string 的参数只有 4 个有效值?该字符串不是来自任何地方的纯文本。您可能应该改用枚举。

b) 在 inputHandling() 中,您应该始终在达到延迟时清除 buttonMs,而不仅仅是在操纵杆被按下某个方向时。

这就是我所得到的。缺少很多信息,仅通过视读很难调试您的程序。主要是因为不清楚正在发生什么以及您想要发生什么。

【讨论】:

  • 感谢您的回答。我已经在 SysTickHandler 函数中对其进行了更正(基本上我抛出了这个无用的 if,它是包装开关)。我还重写了 32768 值的除数值,并始终在它等于 buttonDelay 值时重置“buttonMs”变量。当我今天晚些时候起床时,我会更多地考虑操纵杆轴更改问题。
  • 我发现了为什么没有显示第二到第四位的数字。当我尝试读取轴 x、y 和 z 的值时,就会出现问题:``` mems_acc_read_xyz(&acc); ``` 在那一行之后,程序基本上是冻结的,只显示第一个数字。我认为问题出在 acc struct 变量中
  • 很难确定,因为mems_acc_read_xyz() 在此处不可见。尝试调试它。不过,关于功能的几点。您在 每 1ms 发生的 systick 中断中调用它。该函数通过 IIC/SPI 总线从加速度计读取数据。我很确定读取数据需要超过 1 毫秒,所以基本上你在中断上下文中阻塞了多个 systicks。无论如何,您应该将所有内容移出中断,并仅使用它来获取您想做的事情的时间。使用标志或其他东西。一般来说,中断处理程序应该尽可能快。
  • 哦,SysTick_Handler 可能是您程序中优先级最高的中断。这意味着当您在处理程序内部时,它会阻塞所有较低优先级的中断。如果您的mems_acc_read_xyz()(或其他任何东西)碰巧依赖于例如 IIC/SPI 中断来正常工作,那么它就没有成功的机会。无论如何,不​​要在中断中做任何额外的事情。将所有东西从 systick 处理程序中移开,只增加计数器和例如设置标志以在后台循环中触发定时操作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-20
相关资源
最近更新 更多