你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

stm32h7 定时器输出比较模式+dma,生成脉冲异常

[复制链接]
n1249624160 提问时间:2026-3-6 17:43 / 未解决

测试程序生成3个脉冲。第一次生成脉冲正常,第二次异常(少一个脉冲,脉宽也不对),第三次又正常。波形如下:

正常波形.png

异常波形.png

程序如下:

uint32_t count = 0; void HAL_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma) { // 检查是否为 TIM5 的 DMA if (hdma == &hdma_tim5_ch4) {

while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) && count++ < 10000);
HAL_TIM_OC_Stop(&htim5, TIM_CHANNEL_4);
HAL_DMA_Abort(&hdma_tim5_ch4);
if(count >= 10000)
count = 0;

} else if (hdma == &hdma_tim23_ch1) { HAL_TIM_PWM_Stop(&htim23, TIM_CHANNEL_1); } }

uint32_t pulseBuff[100] = { 200,600,1200,2000,3000,4200 }; //200--1US,400--2US,600--3US,800--4US //uint32_t pulseBuff[100] = { // 200,1000,1800,2600 //}; void Test_TIM5_FixedPulses(uint32_t pulse_count, uint32_t freq_hz) { uint32_t timer_clk = HAL_RCC_GetPCLK1Freq() 2; uint32_t arr = (timer_clk / (2 freq_hz)) - 1; if (arr < 2) arr = 2;

// // 停止任何正在进行的传输 HAL_TIM_OC_Stop(&htim5, TIM_CHANNEL_4); HAL_DMA_Abort(&hdma_tim5_ch4);

// 填充缓冲区 0 htim5.Instance->CNT = 0; // uint32_t temp = htim5.Instance->CNT; // for (uint32_t i = 0; i < pulse_count; i++) { // temp += i % 2 ? arr 2 : arr; // pulseBuff[2 i] = temp; // temp += i % 2 ? arr 2 : arr; // pulseBuff[2 i + 1] = temp;

// }

__HAL_TIM_ENABLE_DMA(&htim5, TIM_DMA_CC4);

__HAL_TIM_CLEAR_FLAG(&htim5, TIM_FLAG_UPDATE | TIM_FLAG_CC4); // 清中断标志

htim5.Instance->CNT = 0; htim5.Instance->CCR4 = pulseBuff[0]; for(volatile int i=0; i<100; i++){} // 确保 CCR4 写入完成 HAL_DMA_Start_IT(&hdma_tim5_ch4, (uint32_t) &pulseBuff[1], (uint32_t) &htim5.Instance->CCR4, pulse_count * 2-1); // TIM_CCxChannelCmd(htim5.Instance, TIM_CHANNEL_4, TIM_CCx_ENABLE); // __HAL_TIM_ENABLE(&htim5);

// HAL_TIM_GenerateEvent(&htim5, TIM_EVENTSOURCE_CC4);

__HAL_TIM_CLEAR_FLAG(&htim5, TIM_FLAG_CC4); // __HAL_TIM_CLEAR_FLAG(&htim5, TIM_FLAG_UPDATE);

HAL_TIM_OC_Start(&htim5, TIM_CHANNEL_4); }

int main(void) {

/ USER CODE BEGIN 1 /

/ USER CODE END 1 /

/ MPU Configuration--------------------------------------------------------/ // MPU_Config();

/ Enable the CPU Cache /

/ Enable I-Cache---------------------------------------------------------/ // SCB_EnableICache();

/ 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_UART9_Init(); MX_TIM5_Init(); MX_TIM23_Init(); / USER CODE BEGIN 2 /

/ USER CODE END 2 /

/ Infinite loop / / USER CODE BEGIN WHILE / while (1) { if(HAL_GetTick()%1000 == 0) { HAL_GPIO_WritePin(GPIOA, SYS_LED1_Pin, GPIO_PIN_SET); } else if(HAL_GetTick()%1000 == 500) { HAL_GPIO_WritePin(GPIOA, SYS_LED1_Pin, GPIO_PIN_RESET); } if(receiveFlag) { receiveFlag = 0; HAL_UART_Transmit(&huart9, receiveBuff, 1, 0xffff);

    static uint8_t flag = 0;

    if(flag == 0)
    {
        flag = 1;
    Test_TIM5_FixedPulses(3, 5000);
    }
    else
    {
        flag = 0;
        Test_TIM5_FixedPulses(3, 50000);
    }
}
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

} / USER CODE END 3 / }

void MX_TIM5_Init(void) {

/ USER CODE BEGIN TIM5_Init 0 /

/ USER CODE END TIM5_Init 0 /

TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0};

/ USER CODE BEGIN TIM5_Init 1 /

/ USER CODE END TIM5_Init 1 / htim5.Instance = TIM5; htim5.Init.Prescaler = 0; htim5.Init.CounterMode = TIM_COUNTERMODE_UP; htim5.Init.Period = 0xFFFFFFFF; htim5.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim5.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_OC_Init(&htim5) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim5, &sMasterConfig) != HAL_OK) { Error_Handler(); } sConfigOC.OCMode = TIM_OCMODE_TOGGLE; sConfigOC.Pulse = 0; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_OC_ConfigChannel(&htim5, &sConfigOC, TIM_CHANNEL_4) != HAL_OK) { Error_Handler(); }

HAL_TIM_MspPostInit(&htim5);

/ USER CODE BEGIN TIM5_Init 2 / extern void HAL_DMA_XferCpltCallback(DMA_HandleTypeDef hdma); HAL_DMA_RegisterCallback(&hdma_tim5_ch4, HAL_DMA_XFER_CPLT_CB_ID, HAL_DMA_XferCpltCallback); / USER CODE END TIM5_Init 2 */ }

void HAL_TIM_OC_MspInit(TIM_HandleTypeDef* tim_ocHandle) {

if(tim_ocHandle->Instance==TIM5) { / USER CODE BEGIN TIM5_MspInit 0 /

/* USER CODE END TIM5_MspInit 0 */
/* TIM5 clock enable */
__HAL_RCC_TIM5_CLK_ENABLE();

/* TIM5 DMA Init */
/* TIM5_CH4 Init */
hdma_tim5_ch4.Instance = DMA1_Stream0;
hdma_tim5_ch4.Init.Request = DMA_REQUEST_TIM5_CH4;
hdma_tim5_ch4.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_tim5_ch4.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tim5_ch4.Init.MemInc = DMA_MINC_ENABLE;
hdma_tim5_ch4.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_tim5_ch4.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_tim5_ch4.Init.Mode = DMA_NORMAL;
hdma_tim5_ch4.Init.Priority = DMA_PRIORITY_VERY_HIGH;
hdma_tim5_ch4.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_tim5_ch4) != HAL_OK)
{
    Error_Handler();
}

__HAL_LINKDMA(tim_ocHandle,hdma[TIM_DMA_ID_CC4],hdma_tim5_ch4);

/* TIM5 interrupt Init */
HAL_NVIC_SetPriority(TIM5_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM5_IRQn);
/* USER CODE BEGIN TIM5_MspInit 1 */

/* USER CODE END TIM5_MspInit 1 */

} }

void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle) {

GPIO_InitTypeDef GPIO_InitStruct = {0}; if(timHandle->Instance==TIM5) { / USER CODE BEGIN TIM5_MspPostInit 0 /

/* USER CODE END TIM5_MspPostInit 0 */
__HAL_RCC_GPIOA_CLK_ENABLE();
/**TIM5 GPIO Configuration
PA3     ------> TIM5_CH4
*/
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN; //GPIO_PULLUP;//GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; //GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM5;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

/* USER CODE BEGIN TIM5_MspPostInit 1 */

/* USER CODE END TIM5_MspPostInit 1 */

} else if(timHandle->Instance==TIM23) { / USER CODE BEGIN TIM23_MspPostInit 0 /

/* USER CODE END TIM23_MspPostInit 0 */

__HAL_RCC_GPIOF_CLK_ENABLE();
/**TIM23 GPIO Configuration
PF0     ------> TIM23_CH1
*/
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF13_TIM23;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

/* USER CODE BEGIN TIM23_MspPostInit 1 */

/* USER CODE END TIM23_MspPostInit 1 */

} }

收藏 评论4 发布时间:2026-3-6 17:43

举报

4个回答
n1249624160 回答时间:昨天 17:58

uint32_t count = 0; void HAL_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma) { // 检查是否为 TIM5 的 DMA if (hdma == &hdma_tim5_ch4) {

while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) && count++ < 10000);
HAL_TIM_OC_Stop(&htim5, TIM_CHANNEL_4);
HAL_DMA_Abort(&hdma_tim5_ch4);
if(count >= 10000)
count = 0;

} else if (hdma == &hdma_tim23_ch1) { HAL_TIM_PWM_Stop(&htim23, TIM_CHANNEL_1); } }

uint32_t pulseBuff[100] = { 200,600,1200,2000,3000,4200 }; //200--1US,400--2US,600--3US,800--4US //uint32_t pulseBuff[100] = { // 200,1000,1800,2600 //}; void Test_TIM5_FixedPulses(uint32_t pulse_count, uint32_t freq_hz) { uint32_t timer_clk = HAL_RCC_GetPCLK1Freq() 2; uint32_t arr = (timer_clk / (2 freq_hz)) - 1; if (arr < 2) arr = 2;

// // 停止任何正在进行的传输 HAL_TIM_OC_Stop(&htim5, TIM_CHANNEL_4); HAL_DMA_Abort(&hdma_tim5_ch4);

// 填充缓冲区 0 htim5.Instance->CNT = 0; // uint32_t temp = htim5.Instance->CNT; // for (uint32_t i = 0; i < pulse_count; i++) { // temp += i % 2 ? arr 2 : arr; // pulseBuff[2 i] = temp; // temp += i % 2 ? arr 2 : arr; // pulseBuff[2 i + 1] = temp;

// }

__HAL_TIM_ENABLE_DMA(&htim5, TIM_DMA_CC4);

__HAL_TIM_CLEAR_FLAG(&htim5, TIM_FLAG_UPDATE | TIM_FLAG_CC4); // 清中断标志

htim5.Instance->CNT = 0; htim5.Instance->CCR4 = pulseBuff[0]; for(volatile int i=0; i<100; i++){} // 确保 CCR4 写入完成 HAL_DMA_Start_IT(&hdma_tim5_ch4, (uint32_t) &pulseBuff[1], (uint32_t) &htim5.Instance->CCR4, pulse_count * 2-1); // TIM_CCxChannelCmd(htim5.Instance, TIM_CHANNEL_4, TIM_CCx_ENABLE); // __HAL_TIM_ENABLE(&htim5);

// HAL_TIM_GenerateEvent(&htim5, TIM_EVENTSOURCE_CC4);

__HAL_TIM_CLEAR_FLAG(&htim5, TIM_FLAG_CC4); // __HAL_TIM_CLEAR_FLAG(&htim5, TIM_FLAG_UPDATE);

HAL_TIM_OC_Start(&htim5, TIM_CHANNEL_4); }

n1249624160 回答时间:昨天 17:59
uint32_t count = 0;
void HAL_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma) {
    // 检查是否为 TIM5 的 DMA
    if (hdma == &hdma_tim5_ch4) {

        while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) && count++ < 10000);
        HAL_TIM_OC_Stop(&htim5, TIM_CHANNEL_4);
        HAL_DMA_Abort(&hdma_tim5_ch4);
                if(count >= 10000)
                count = 0;
    }
    else if (hdma == &hdma_tim23_ch1) {
        HAL_TIM_PWM_Stop(&htim23, TIM_CHANNEL_1);
        }
}


uint32_t pulseBuff[100] = {
        200,600,1200,2000,3000,4200
};        //200--1US,400--2US,600--3US,800--4US
//uint32_t pulseBuff[100] = {
//        200,1000,1800,2600
//};
void Test_TIM5_FixedPulses(uint32_t pulse_count, uint32_t freq_hz) {
    uint32_t timer_clk = HAL_RCC_GetPCLK1Freq() * 2;
    uint32_t arr = (timer_clk / (2 * freq_hz)) - 1;
    if (arr < 2)     arr = 2;

    //        // 停止任何正在进行的传输
    HAL_TIM_OC_Stop(&htim5, TIM_CHANNEL_4);
    HAL_DMA_Abort(&hdma_tim5_ch4);

    // 填充缓冲区 0
    htim5.Instance->CNT = 0;
       
//    uint32_t temp = htim5.Instance->CNT;
//    for (uint32_t i = 0; i < pulse_count; i++) {
//        temp += i % 2 ? arr * 2 : arr;
//        pulseBuff[2 * i] = temp;
//        temp += i % 2 ? arr * 2 : arr;
//        pulseBuff[2 * i + 1] = temp;

//    }
       
    __HAL_TIM_ENABLE_DMA(&htim5, TIM_DMA_CC4);
       
         __HAL_TIM_CLEAR_FLAG(&htim5, TIM_FLAG_UPDATE | TIM_FLAG_CC4); // 清中断标志
       
        htim5.Instance->CNT = 0;
        htim5.Instance->CCR4 = pulseBuff[0];
        for(volatile int i=0; i<100; i++){}  // 确保 CCR4 写入完成
    HAL_DMA_Start_IT(&hdma_tim5_ch4, (uint32_t) &pulseBuff[1],
                     (uint32_t) &htim5.Instance->CCR4, pulse_count * 2-1);

//    TIM_CCxChannelCmd(htim5.Instance, TIM_CHANNEL_4, TIM_CCx_ENABLE);
//    __HAL_TIM_ENABLE(&htim5);

//    HAL_TIM_GenerateEvent(&htim5, TIM_EVENTSOURCE_CC4);
       
    __HAL_TIM_CLEAR_FLAG(&htim5, TIM_FLAG_CC4);
       
//    __HAL_TIM_CLEAR_FLAG(&htim5, TIM_FLAG_UPDATE);

    HAL_TIM_OC_Start(&htim5, TIM_CHANNEL_4);

}

n1249624160 回答时间:昨天 18:00
int main(void)
{

    /* USER CODE BEGIN 1 */

    /* USER CODE END 1 */

    /* MPU Configuration--------------------------------------------------------*/
//  MPU_Config();

    /* Enable the CPU Cache */

    /* Enable I-Cache---------------------------------------------------------*/
//  SCB_EnableICache();

    /* 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_UART9_Init();
    MX_TIM5_Init();
    MX_TIM23_Init();
    /* USER CODE BEGIN 2 */

    /* USER CODE END 2 */

    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    while (1)
    {
        if(HAL_GetTick()%1000 == 0)
        {
            HAL_GPIO_WritePin(GPIOA, SYS_LED1_Pin, GPIO_PIN_SET);
        }
        else if(HAL_GetTick()%1000 == 500)
        {
            HAL_GPIO_WritePin(GPIOA, SYS_LED1_Pin, GPIO_PIN_RESET);
        }
        if(receiveFlag)
        {
            receiveFlag = 0;
            HAL_UART_Transmit(&huart9, receiveBuff,
                              1, 0xffff);

                        static uint8_t flag = 0;
                       
                        if(flag == 0)
                        {
                                flag = 1;
            Test_TIM5_FixedPulses(3, 5000);
                        }
                        else
                        {
                                flag = 0;
                                Test_TIM5_FixedPulses(3, 50000);
                        }
        }
        /* USER CODE END WHILE */

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

n1249624160 回答时间:昨天 18:01
void MX_TIM5_Init(void)
{

    /* USER CODE BEGIN TIM5_Init 0 */

    /* USER CODE END TIM5_Init 0 */

    TIM_MasterConfigTypeDef sMasterConfig = {0};
    TIM_OC_InitTypeDef sConfigOC = {0};

    /* USER CODE BEGIN TIM5_Init 1 */

    /* USER CODE END TIM5_Init 1 */
    htim5.Instance = TIM5;
    htim5.Init.Prescaler = 0;
    htim5.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim5.Init.Period = 0xFFFFFFFF;
    htim5.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim5.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
    if (HAL_TIM_OC_Init(&htim5) != HAL_OK)
    {
        Error_Handler();
    }
    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    if (HAL_TIMEx_MasterConfigSynchronization(&htim5, &sMasterConfig) != HAL_OK)
    {
        Error_Handler();
    }
    sConfigOC.OCMode = TIM_OCMODE_TOGGLE;
    sConfigOC.Pulse = 0;
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
    if (HAL_TIM_OC_ConfigChannel(&htim5, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
    {
        Error_Handler();
    }

    HAL_TIM_MspPostInit(&htim5);
       
        /* USER CODE BEGIN TIM5_Init 2 */
    extern void HAL_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma);
    HAL_DMA_RegisterCallback(&hdma_tim5_ch4, HAL_DMA_XFER_CPLT_CB_ID,
                             HAL_DMA_XferCpltCallback);
    /* USER CODE END TIM5_Init 2 */

}

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版