• 已解决 73482 个问题
  • 已帮助 5993 位优秀工程师

向高手请教一个单片机算法问题

lilei 2016-11-22 浏览量:598

各位大侠,诚心请教一个问题:
   用单片机的I/O口怎实现检测出外部输入到该I/O口的PWM方波的占空比,PWM方波用来控制三相直流电机调速的,根据输入的PWM方波占空比的大小响应的改变电机的速度。在网上看到其他人也有提到此问题,输入到带AD功能的I/O口能实现,个人觉得这个应该不能实现,求一个比较好使的算法!
0 0 收起

我来回答

上传资料:
选择文件 文件大小不超过15M(格式支持:doc、ppt、xls、pdf、zip、rar、txt)
最佳答案
  • 其实就是使用Timer的捕获模式,能够判断出外部输入信号的高低电平时间,然后自己再去处理。

    一段参考程序:


    GPIO_InitTypeDef GPIO_InitStructure;  
      NVIC_InitTypeDef NVIC_InitStructure;  
      
      /* TIM2 clock enable */  
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);  
      
      /* GPIOB clock enable */  
      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);  
        
      /* TIM2 chennel2 configuration : PA.01 */  
      GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_1;  
      GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;  
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
      GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;  
      GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP ;  
      GPIO_Init(GPIOA, &GPIO_InitStructure);  
        
      /* Connect TIM pin to AF1 */  
      GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_1);  
      
      /* Enable the TIM2 global Interrupt */  
      NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
      NVIC_Init(&NVIC_InitStructure);  
          
        TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;  
      TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;  
      TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;  
      TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;  
      TIM_ICInitStructure.TIM_ICFilter = 0x0;  
      
      TIM_PWMIConfig(TIM2, &TIM_ICInitStructure);  
      
      /* Select the TIM2 Input Trigger: TI2FP2 */  
      TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);  
      
      /* Select the slave Mode: Reset Mode */  
      TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);  
      TIM_SelectMasterSlaveMode(TIM2,TIM_MasterSlaveMode_Enable);  
      
      /* TIM enable counter */  
      TIM_Cmd(TIM2, ENABLE);  
      
      /* Enable the CC2 Interrupt Request */  
       TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);  



    void TIM2_IRQHandler(void)  
    {  
      RCC_GetClocksFreq(&RCC_Clocks);  
      
      /* Clear TIM2 Capture compare interrupt pending bit */  
      TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);  
      
      /* Get the Input Capture value */  
      IC2Value = TIM_GetCapture2(TIM2);  
      
      if (IC2Value != 0)  
      {  
        /* Duty cycle computation */  
        DutyCycle = (TIM_GetCapture1(TIM2) * 100) / IC2Value;  
      
        /* Frequency computation  
           TIM2 counter clock = (RCC_Clocks.HCLK_Frequency)/2 */  
      
        Frequency = RCC_Clocks.HCLK_Frequency / IC2Value;  
      }  
      else  
      {  
        DutyCycle = 0;  
        Frequency = 0;  
      }  
    }  

    • 发布于 2016-11-22
    • 举报
    • 评论 0
    • 0
    • 0

其他答案 数量:4
  • 你好,STC官方是有这么一个例程的:


    /************* 功能说明 **************

    使用PCA0从P3.5输出8位的PWM, 输出的PWM经过RC滤波成直流电压送P1.5做ADC并用数码管显示出来.

    串口1配置为115200bps, 8,n, 1, 切换到P3.0 P3.1, 下载后就可以直接测试. 主时钟为22.1184MHZ, 通过串口1设置占空比.

    串口命令使用ASCII码的数字,比如: 10,就是设置占空比为10/256, 100: 就是设置占空比为100/256。

    可以设置的值为0~256, 0为连续低电平, 256为连续高电平.

    左边4位数码管显示PWM的占空比值,右边4位数码管显示ADC值。

    ******************************************/


    直接可以参考这个例程来实现你想要的功能:

    http://cf03.ickimg.com/bbsfiles/201611/4726574b7129160961b7c93d996ebe89.rar

    • 发布于2016-11-22
    • 举报
    • 评论 0
    • 1
    • 0

  • 高速定时器去检测 PWM脉宽宽度  然后根据检测到的宽度值 一个计数值  调节电机速度即可
    • 发布于2016-11-22
    • 举报
    • 评论 0
    • 0
    • 0

  • ADC是最穩最快的方法,也較易Debug


    純軟作法,有兩種

    1. Polling方式,就一直監聽查詢該I/O口然後當值變化(上升/下降)時候停止計數,將值指派給變數

    2. 用中斷方式(也稱ISR),配合定時器,每次上升/下降沿時候就計算兩時刻定時器的差值並指派給變數


    以上希望對您有用


    • 发布于2016-11-22
    • 举报
    • 评论 0
    • 0
    • 0

  • 你这个好像是和变频器一样,可以接受PWM调制,检测PWM方波其实很简单,但是你怎么改变三项电机的转数是关键,单片机本身不好实现控制三项电机,如果是你想用单片机控制电机的转数,那么你肯定要有一个驱动电路的,还需要反馈实际的转数,你可以查一下变频器是怎么接收PWM来控制电机频率的,不过不带反馈,要想精确控制,就需要反馈,可以用计数器当反馈,这样可以按占空比求得实际需要的转数,然后根据反馈来改变实际的转数了!
    • 发布于2016-11-22
    • 举报
    • 评论 0
    • 0
    • 0

相关问题

问题达人换一批

向高手请教一个单片机算法问题