野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 15471|回复: 5

利用stm32捕获航模接收机PWM波问题求助

[复制链接]
发表于 2017-3-8 16:25:54 | 显示全部楼层 |阅读模式
程序目的:在定时器1捕获到PWM波之后,利用普通定时器输出PWM波;
解决方法:将普通定时器初始化函数写入中断函数。
存在问题:在输出较大平率的PWM波时,用定时器8捕获频率和占空比正常,当频率设置为100时占空比正常,频率不正常。
同时,如果将普通定时器初始化函数写在主函数,也就是中断函数外不存在上述问题。
为什么不写在主函数:因为想要调用中断函数捕获到的参数 IC1Value1和 IC2Value1 ,如果在中断函数中定义这两个变量然后利用exten关键字导出到主函数发现虽然编译器不报错,但是参数值异常,并不是中断函数所捕获到的值。
最终实现目标:捕获航模接收机的PWM波然后以相同的频率和占空比输出给飞控。如果有前辈做过,希望可以指点一下。一直调不出理想的效果。

中断函数源码:模仿高级定时器1对高级定时器8进行了宏定义
#define            ADVANCE1_TIM                   TIM1
#define            ADVANCE8_TIM                   TIM8
......

void ADVANCE1_TIM_IRQHandler(void)
{
  TIM_ClearITPendingBit(ADVANCE1_TIM, TIM_IT_CC1);
  IC1Value1 = TIM_GetCapture1(ADVANCE1_TIM);
  IC2Value1 = TIM_GetCapture2(ADVANCE1_TIM);
       
        if (IC1Value1 != 0)
  {
    DutyCycle1 = (float)((IC2Value1+1) * 100) / (IC1Value1+1);
    Frequency1 = (72000000/(ADVANCE_TIM_PSC+1))/(float)(IC1Value1+1);
               
  }
  else
  {
    DutyCycle1 = 0;
    Frequency1 = 0;
  }
        GENERAL_TIM_Init((10000-1),5000);
//普通定时器初始化函数改为带参函数,参数为TIM_Period和TIM_Pulse的值。
}
void ADVANCE8_TIM_IRQHandler(void)
{

  TIM_ClearITPendingBit(ADVANCE8_TIM, TIM_IT_CC1);

  IC1Value8 = TIM_GetCapture1(ADVANCE8_TIM);
  IC2Value8 = TIM_GetCapture2(ADVANCE8_TIM);
        if (IC1Value8 != 0)
  {
                //TIM_Cmd(ADVANCE1_TIM, ENABLE);
    DutyCycle8 = (float)((IC2Value8+1) * 100) / (IC1Value8+1);

    Frequency8 = (72000000/(ADVANCE_TIM_PSC+1))/(float)(IC1Value8+1);
  }
  else
  {
    DutyCycle8 = 0;
    Frequency8 = 0;
  }
}



回复

使用道具 举报

发表于 2017-3-8 18:36:16 | 显示全部楼层
IC1Value1和 IC2Value1 加上 __IO 前缀修饰
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-3-8 19:21:41 | 显示全部楼层
flyleaf 发表于 2017-3-8 18:36
IC1Value1和 IC2Value1 加上 __IO 前缀修饰

试了一下,在stm32f10x_it.cl里面定义是加上了—IO前缀修饰,但是还是无法正常调用。具体调用方法为:
在主函数中写
GENERAL_TIM_Init(IC1Value1,IC2Value1);
具体执行结果为定时器8无法捕获到普通定时器产生的PWM波。另外为了编译器不报错,IC1Value1,IC2Value1参数在主函数中的说明为
extern __IO uint32_t IC2Value1;
extern __IO uint32_t IC1Value1;
stm32f10x_it.cl里面定义为
__IO uint32_t IC2Value1 = 0;
__IO uint32_t IC1Value1 = 0;
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-3-9 10:39:20 来自手机 | 显示全部楼层
哇,前辈们帮忙看一看呗
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-3-9 21:01:27 | 显示全部楼层
问题基本得到了解决,把主函数改为
int main(void)
{
        USART_Config();
       
        ADVANCE1_TIM_Init();
        ADVANCE8_TIM_Init();       
        while(1)
  {
                GENERAL_TIM_Init(IC1Value1,(IC2Value1+1));
    Delay(0xFFFF);               
  }
加入延时的作用:试验中不加延时,当输出频率较低时无法正常准确输出。
现在还存在的问题:由于加入了延时,导致输出的 PWM波无法及时根据输入PWM波的改变而及时改变。存在延迟.延时是否会导致实际飞行器对舵量变化有延迟待以后实验证明。如果前辈们有什么好的改进方法,可以提出来。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-3-9 23:23:06 | 显示全部楼层
最新解决方法,将延迟函数参数设置为捕获到的参数IC1Value1。
效果目前来看还是比较理想的
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-24 20:36 , Processed in 0.045820 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表