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

STM32F030 PWM延迟严重,求指点迷津

[复制链接]
konway 提问时间:2017-4-25 16:47 /
本帖最后由 konway 于 2017-4-25 16:49 编辑

用STM32F030的TIM3做38K红外发射
要实现的功能很简单,
要发射高电平1,就把PWM口的pwm置为低电平;
要发低电平0,就在PWM口发送38K的方波。

现在碰到个问题
停止PWM后,想隔2ms再发送pwm,时间就会延迟5.6ms才发送。
只要设的时间小于5.6ms,低电平的时间就会是5.6ms。

今天发现把TIM3->CCR3=0;
改为
TIM3->CCR3=1;
时间间隔就是对的,可是这不能用啊。

求正确的解决办法。
附代码。

//TM3初始化:这部分由CUBE MX生成,实测为38KHz
  1. static void MX_TIM3_Init(void)
  2. {

  3.   TIM_ClockConfigTypeDef sClockSourceConfig;
  4.   TIM_MasterConfigTypeDef sMasterConfig;
  5.   TIM_OC_InitTypeDef sConfigOC;

  6.   htim3.Instance = TIM3;
  7.   htim3.Init.Prescaler = 0;
  8.   htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  9.   htim3.Init.Period = 209;
  10.   htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  11.   htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  12.   if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
  13.   {
  14.     Error_Handler();
  15.   }

  16.   sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  17.   if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
  18.   {
  19.     Error_Handler();
  20.   }

  21.   if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
  22.   {
  23.     Error_Handler();
  24.   }

  25.   sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  26.   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  27.   if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  28.   {
  29.     Error_Handler();
  30.   }

  31.   sConfigOC.OCMode = TIM_OCMODE_PWM1;
  32.   sConfigOC.Pulse = 0;
  33.   sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  34.   sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;
  35.   if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
  36.   {
  37.     Error_Handler();
  38.   }

  39.   HAL_TIM_MspPostInit(&htim3);

  40. }


复制代码
//开关PWM波形
  1. IR_send_Count_time=40;//4ms 低电平
  2. TIM3->CCR3=70;//IR发低电平
  3. while(IR_send_Count_time);//<span style="font-size: 13.63636302948px; line-height: 19.0909080505371px;">IR_send_Count_time在定时器中断里减,每100us减1</span>

  4. IR_send_Count_time=40;//4ms 高电平
  5. TIM3->CCR3=0;//IR发低电平
  6. while(IR_send_Count_time);

  7. IR_send_Count_time=40;//4ms 低电平
  8. TIM3->CCR3=70;//IR发低电平
  9. while(IR_send_Count_time);

  10. IR_send_Count_time=40;//4ms 高电平
  11. TIM3->CCR3=0;//IR发低电平
  12. while(IR_send_Count_time);
复制代码


收藏 1 评论20 发布时间:2017-4-25 16:47

举报

20个回答
奏奏奏 回答时间:2017-4-25 17:00:15
//开关PWM波形 这段代码你是用寄存器操作来实现的
建议你用HAL库的函数来实现
sfd123-302670 回答时间:2017-4-25 17:04:54
奏奏奏 发表于 2017-4-25 17:00
//开关PWM波形 这段代码你是用寄存器操作来实现的
建议你用HAL库的函数来实现 ...

不是用寄存器更加直接吗?
konway 回答时间:2017-4-25 17:11:09
奏奏奏 发表于 2017-4-25 17:00
//开关PWM波形 这段代码你是用寄存器操作来实现的
建议你用HAL库的函数来实现 ...

请教,是用哪个函数来实现呢?
我用过这两个,是不行的,关闭PWM后低电平电压漂移,而且也一样没有解决延迟问题
HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel);
HAL_TIM_PWM_Stop(TIM_HandleTypeDef *htim, uint32_t Channel);
奏奏奏 回答时间:2017-4-25 19:34:41
那么我觉得可能是硬件设计问题,建议先查看电路
konway 回答时间:2017-4-26 08:02:36
奏奏奏 发表于 2017-4-25 19:34
那么我觉得可能是硬件设计问题,建议先查看电路

應該不是。
如果是電路的問題,那TIM3->CCR3設爲1應該也會有延遲。
LIUBEIHUA 回答时间:2017-4-26 10:49:39
/**
  * 函数功能: 通用定时器初始化并配置通道PWM输出
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明: 无
  */
void GENERAL_TIMx_Init(void)
{
        TIM_ClockConfigTypeDef sClockSourceConfig;
        TIM_MasterConfigTypeDef sMasterConfig;
        TIM_OC_InitTypeDef sConfigOC;
  
        htimx.Instance = GENERAL_TIMx;
        htimx.Init.Prescaler = GENERAL_TIM_PRESCALER;
        htimx.Init.CounterMode = TIM_COUNTERMODE_UP;
        htimx.Init.Period = GENERAL_TIM_PERIOD;
        htimx.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;
        HAL_TIM_Base_Init(&htimx);

        sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
        HAL_TIM_ConfigClockSource(&htimx, &sClockSourceConfig);

        sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
        sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
        HAL_TIMEx_MasterConfigSynchronization(&htimx, &sMasterConfig);
  
        sConfigOC.OCMode = TIM_OCMODE_PWM1;
        sConfigOC.Pulse = GENERAL_TIM_CH1_PULSE;
        sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
        sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
        HAL_TIM_PWM_ConfigChannel(&htimx, &sConfigOC, TIM_CHANNEL_2);

        HAL_TIM_MspPostInit(&htimx);
}

void user_pwm_setvalue(uint16_t value)
{
    TIM_OC_InitTypeDef sConfigOC;
  
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = value;
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
    HAL_TIM_PWM_ConfigChannel(&htimx, &sConfigOC, TIM_CHANNEL_2);
    HAL_TIM_PWM_Start(&htimx, TIM_CHANNEL_2);  
}

void Bit0_Encode_SignalGenerate(void)
{
        user_pwm_setvalue(316);
        HAL_Delay(56);
        user_pwm_setvalue(0);
        HAL_Delay(56);
}

void Bit1_Encode_SignalGenerate(void)
{
        user_pwm_setvalue(316);
        HAL_Delay(56);
        user_pwm_setvalue(0);
        HAL_Delay(168);
}

void Head_Encode_SignalGenerate(void)
{
        user_pwm_setvalue(316);
        HAL_Delay(900);
        user_pwm_setvalue(0);
        HAL_Delay(45);
}

void End_Encode_SignalGenerate(void)
{
        user_pwm_setvalue(316);
        HAL_Delay(56);
        user_pwm_setvalue(0);
        HAL_Delay(56);
        user_pwm_setvalue(316);
        HAL_Delay(56);
        user_pwm_setvalue(0);
}

void Usercode_Encode_SignalGenerate(uint8_t * dat)
{
        uint8_t usercode[3];
        uint8_t i, j;
        usercode[0]=dat[0];
        usercode[1]=dat[1];
        usercode[2]=dat[2];
        for(j=0; j<3; j++)
        {
                for(i=0; i<8; i++)
                {
                        if(usercode[j]&0x80)
                                Bit1_Encode_SignalGenerate();
                        else
                                Bit0_Encode_SignalGenerate();
                        usercode[j]=usercode[j]<<1;
                }
        }
}

void Controlcode_Encode_SignalGenerate(uint8_t * dat)
{
        uint8_t i, j;
        for(j=0; j<2; j++)
        {
                for(i=0; i<8; i++)
                {
                        if(dat[j]&0x80)
                                Bit1_Encode_SignalGenerate();
                        else
                                Bit0_Encode_SignalGenerate();
                        dat[j]=dat[j]<<1;
                }
        }
}
LIUBEIHUA 回答时间:2017-4-26 10:53:10
#define GENERAL_TIMx                        TIM3
#define GENERAL_TIM_RCC_CLK_ENABLE()        __HAL_RCC_TIM3_CLK_ENABLE()
#define GENERAL_TIM_RCC_CLK_DISABLE()       __HAL_RCC_TIM3_CLK_DISABLE()
#define GENERAL_TIM_GPIO_RCC_CLK_ENABLE()   {__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();}
#define GENERAL_TIM_CH1_PORT                GPIOA
#define GENERAL_TIM_CH1_PIN                 GPIO_PIN_6
#define GENERAL_TIM_CH2_PORT                GPIOA
#define GENERAL_TIM_CH2_PIN                 GPIO_PIN_7
#define GENERAL_TIM_CH3_PORT                GPIOB
#define GENERAL_TIM_CH3_PIN                 GPIO_PIN_0
#define GENERAL_TIM_CH4_PORT                GPIOB
#define GENERAL_TIM_CH4_PIN                 GPIO_PIN_1
#define GENERAL_TIM_CH1_AF                  GPIO_AF1_TIM3
LIUBEIHUA 回答时间:2017-4-26 14:29:52
时钟与定时器配置

定时器配置

定时器配置

时钟配置

时钟配置

remoter.rar

下载

1.17 KB, 下载次数: 6, 下载积分: ST金币 -1

konway 回答时间:2017-4-26 15:48:45
LIUBEIHUA 发表于 2017-4-26 14:29
时钟与定时器配置

用你给的函数做PWM赋值
结果还是一样的

试着改系统时钟为48M(原来是8M,为了省电),也还是没用。

void user_pwm_setvalue(uint16_t value)
{
    TIM_OC_InitTypeDef sConfigOC;
  
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = value;
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
    HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_3);
    HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);  
}
123下一页

所属标签

相似问题

官网相关资源

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