STM32
直播中

张艳

7年用户 1611经验值
私信 关注
[问答]

STM32F407RC使用Tim1的ch1用来发送PWM遇到的疑问求解

各位大佬好。
刚接触单片机,现在需要实现以下逻辑:
1.发送12个周期为500ns的脉冲(高电平200ns,低电平300ns),每隔4us发送一次,共计三次(36个脉冲,每12个脉冲之间间隔4us)
2.在第一步每段12个脉冲发送的上升沿时,读取GPIO口数据,共计12个bit,三次共计36个bit。
时序图如下:

我现在处理方式如下:
开发环境:STM32F407RC,CubeMx,IAR
使用tim1的ch1用来发送PWM(周期为500ns),同时使用Tim1来驱动DMA来读取Dout的数据,然后使用从定时器Tim3来计12次数,12次到达后进入中断,停止发送PWM和DMA,等候4us后继续,以此做三次。
问题:
周期为500ns的情况下,无法保证每次都是12次停止,9次,10次,14次等,会乱掉,周期调到us级没有问题。
如果关掉DMA,只发送PWM的话,是可以按照12次计数停止。
小弟第一次做单片机,怀疑是使用库HAL库函数对定时器有一定的影响?还是整个开发方向都是错误的。以上,希望各位大佬解惑~

回帖(2)

袁伟

2024-4-1 15:29:59
通过寄存器配置主从time完美解决这个问题。
举报

李波

2024-4-1 16:55:11
您可以按照以下步骤来实现您的逻辑:

1. 使用CubeMx配置Tim1的PWM输出,设置周期为500ns。将Tim1的ch1连接到目标GPIO口。

2. 配置Tim1的DMA请求,在DMA中设置外设地址为GPIO的数据寄存器地址,内存地址设置为您定义的一个全局变量数组。

3. 初始化Tim3,将其设置为计数模式,使其连续计数到12。

4. 在Tim3的中断处理函数中,停止Tim1的计数和DMA传输,并设置一个延时函数(使用SysTick或者其他方法)来等待4us。

5. 等待延时结束后,重新启动Tim1的计数和DMA传输,继续发送PWM和读取GPIO口的数据。

6. 重复3到5步骤,直到发送完三次。

下面是一个简化的代码示例,其中具体的配置和初始化函数需要根据您的具体环境进行修改:

```c
#include "stm32f4xx_hal.h"

// 全局变量数组,用于存储读取到的GPIO口数据
uint32_t data[36];

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    static uint8_t count = 0;

    if (htim->Instance == TIM3)
    {
        count++;

        if (count == 13) // 到达12次后停止计数
        {
            HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);
            HAL_TIM_DMA_Stop(&htim1, TIM_CHANNEL_1);
            
            // 停止后等待4us
            HAL_Delay(4);
            
            // 继续发送PWM和读取GPIO口数据
            HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
            HAL_TIM_DMA_Start(&htim1, TIM_CHANNEL_1, data, sizeof(data));
            
            count = 0; // 重置计数
        }
    }
}

int main(void)
{
    // 初始化各个外设
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_TIM1_Init();
    MX_TIM3_Init();
    MX_DMA_Init();

    // 启动PWM输出和DMA传输
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
    HAL_TIM_DMA_Start(&htim1, TIM_CHANNEL_1, data, sizeof(data));

    // 启动Tim3
    HAL_TIM_Base_Start_IT(&htim3);

    while (1)
    {
    }
}
```

请注意,这只是一个示例代码,具体的配置和初始化函数会因为您的环境不同而有所不同。您可能还需要正确配置GPIO口的输入模式,以确保正确读取数据。此外,您还可以根据具体情况进行错误处理和其他必要的操作。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分