使用
pData
函数时无法理解HAL_IM_IC_START_DMA
值的含义
我正在开始使用STM32F103C8T6。当我使用定时器2的输入捕捉来通过确定两个上升沿之间的时间来测量定时器1的频率时。我无法理解“pData”的数值含义。起初我认为是定时器上升沿时刻的计数器数值,但事实并非如此。定时器2的自动重载最大值只是
65535
(大约2^16
),但实时表情中显示的数字是最大2^32
。所以我不明白如何计算它的频率。这是我工作的主要代码部分
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define numval 100
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim1;
TIM_HandleTypeDef htim2;
DMA_HandleTypeDef hdma_tim2_ch1;
DMA_HandleTypeDef hdma_tim2_ch2_ch4;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_TIM1_Init(void);
static void MX_TIM2_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint32_t riseData[numval];
uint32_t fallData[numval];
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_TIM1_Init();
MX_TIM2_Init();
/* USER CODE BEGIN 2 */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, SET);
TIM1->CCR1 = 500;
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_IC_Start_DMA(&htim2, TIM_CHANNEL_2, riseData, numval);
HAL_TIM_IC_Start_DMA(&htim2, TIM_CHANNEL_2, fallData, numval);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_Delay(500);
HAL_TIM_IC_Start_DMA(&htim2, TIM_CHANNEL_2, riseData, numval);
HAL_TIM_IC_Start_DMA(&htim2, TIM_CHANNEL_2, fallData, numval);
}
/* USER CODE END 3 */
}
回答你的问题,pData是一个指向缓冲区的指针,它指定内存中数据将从TIM2传输的目标地址。
代码中的一个可能问题是调用 HAL_TIM_IC_Start_DMA 时它们之间没有任何同步。我想说,由于溢出,这些值大于 65535,因为 DMA 会覆盖数据。
要解决此问题,您可以在 While 循环中的调用之间使用以下函数。
/**
* @brief Polling for transfer complete.
* @param hdma pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA Channel.
* @param CompleteLevel Specifies the DMA level complete.
* @param Timeout Timeout duration.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout)
由于需要等待DMA传输完成,所以CompleteLevel的值可能是HAL_DMA_FULL_TRANSFER。
一个例子:
while (HAL_DMA_PollForTransfer(&hdma_tim2_ch2, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY) != HAL_OK);
这样,您可以确保 DMA 在开始下一个 DMA 调用之前完成传输。