This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2640R2F 产生定量的PWM波形?

Other Parts Discussed in Thread: CC2640R2F

项目需求产生8个1mhz的pwm的脉冲;

尝试方法一:pwm_init 初始化PWM,然后用CPUdelay尝试在开关PWM中间延迟,但是此方法在开关PWM时不太稳定,会产生一个比较宽的脉冲;

方法二:GPTtime定时器,时间到后取反电平,但是此方法需要定时产生0.5us的定时,好像CC2640R2f不支持;

方法三:直接使用CPUdelay,然后取反电平,但是我尝试就算直接取反电平PWM也才200多k,所以定时器的应该也同样不行;

---》问题:请问什么方式产生定量的PWM比较合适,PWM_init后在用新的IO进行捕获吗?

  • 可以看下CC2640R2f的PWM模式,C:\ti\simplelink_cc2640r2_sdk_4_20_00_04\source\ti\drivers\pwm

    下面的例子是产生一个8Mhz的PWM信号

    # Limitations #
     *  - The PWM output can currently not be synchronized with other PWM outputs
     *  - The PWM driver does not support updating duty and period using DMA.
     *  - Changes to the timer period are applied immediately, which can cause
     *    pulses to be too long or short unless period changes are applied close
     *    to a timeout. Does not apply to duty cycle, which is applied on timeout.
     *  # PWM usage #
     *
     *  ## Basic PWM output ##
     *  The below example will output a 8MHz PWM signal with 50% duty cycle.
     *  @code
     *  PWM_Handle pwmHandle;
     *  PWM_Params params;
     *
     *  PWM_Params_init(&params);
     *  params.idleLevel      = PWM_IDLE_LOW;
     *  params.periodUnits    = PWM_PERIOD_HZ;
     *  params.periodValue    = 8e6;
     *  params.dutyUnits      = PWM_DUTY_FRACTION;
     *  params.dutyValue      = PWM_DUTY_FRACTION_MAX / 2;
     *
     *  pwmHandle = PWM_open(Board_PWM0, &params);
     *  if(pwmHandle == NULL) {
     *    Log_error0("Failed to open PWM");
     *    Task_exit();
     *  }
     *  PWM_start(pwmHandle);
     *  @endcode

  • 你好,我需要产生8个1mhz的脉冲,pwm我已经产生了,但是让他形成8个呢

  • 配置需要GPIO输出引脚,按照需要输出配置定时器,看下C:\ti\simplelink_cc2640r2_sdk_4_20_00_04\source\ti\drivers\pwm下的驱动

    类似这样

     PWM_init();
        PWM_Params_init(&g_pwm_params);
        g_pwm_params.periodUnits = PWM_PERIOD_US;
        g_pwm_params.periodValue= 10000;
        g_pwm_params.dutyUnits = PWM_DUTY_US;
        g_pwm_params.dutyValue = 0;
    
        g_rled_pwm_handle = PWM_open(CC2640R2_LAUNCHXL_PWM0, &g_pwm_params);
        g_gled_pwm_handle = PWM_open(CC2640R2_LAUNCHXL_PWM1, &g_pwm_params);
        g_bled_pwm_handle = PWM_open(CC2640R2_LAUNCHXL_PWM2, &g_pwm_params);
    
        PWM_start(g_rled_pwm_handle);
        PWM_start(g_gled_pwm_handle);
        PWM_start(g_bled_pwm_handle); 

  • 这不是直接产生PWM波吗,不能控制产生8个脉冲,我的意思是比如平时低电平,按键按下,产生8个脉冲后又是低电平 ,脉冲频率1MHZ,不是产生8个通道PWM被
  • 精确控制脉冲的个数实现起来有点困难,可以尝试用定时器溢出中断计数,每产生一个脉冲,计数器+1
  • 我直接控制GPIO口反转达不到1mhz,速度最快只有200多久K,中间都没加延迟;

    我这边不需要太精确,但是波形必须1mhz的,大致需要7-9个脉冲,而在PWM的方式产生脉冲,我用延迟控制脉冲输出,但是在实现   PWM_stop(pwm);和 PWM_start(pwm); 有一段过度阶段;

    /****初始化****/

    PWM_Handle pwm;
    PWM_Params pwmParams;
    void Pwm_Init(void)
    {
       
     
         // Initialize the PWM driver.
         PWM_init();
     
         // Initialize the PWM parameters
         PWM_Params_init(&pwmParams);
         pwmParams.idleLevel = PWM_IDLE_HIGH;      // Output low when PWM is not running
         pwmParams.periodUnits = PWM_PERIOD_HZ;   // Period is in Hz
         pwmParams.periodValue = 1e6;             // 1MHz
         pwmParams.dutyUnits = PWM_DUTY_FRACTION; // Duty is in fractional percentage
         pwmParams.dutyValue = 0;                 // 0% initial duty cycle
     
         // Open the PWM instance
         pwm = PWM_open(Board_PWM0, &pwmParams);
     
         if (pwm == NULL) {
             // PWM_open() failed
             while (1);
         }
      PWM_setDuty(pwm,
      PWM_DUTY_FRACTION_MAX / 3);       // set duty cycle to 50%
    }
    /***应用***/

      PWM_start(pwm);
      CPUdelay(30);
      PWM_stop(pwm);

    效果

  • 试试我上面说的方法,利用定时器计数,产生8个脉冲后停止。这个定时器相当于从定时器,只负责计数,另一个用来产生PWM脉冲。

  • 你的意思的在开一个定时器,触发条件是PWM波定时器溢出?是的话有没有相关定时器的例程或者资料,刚接触这款芯片
  • 是的,定时器请看:C:\ti\simplelink_cc2640r2_sdk_4_20_00_04\source\ti\drivers\timer
  • 你好,在你所给的例程中讲述的比较简单,未涉及定时器的触发方式配置?

    下面的例程的代码:

    #include <stdbool.h>
    #include <stddef.h>
    #include <stdint.h>

    #include <ti/drivers/Timer.h>
    #include <ti/drivers/dpl/HwiP.h>

    extern const Timer_Config Timer_config[];
    extern const uint_least8_t Timer_count;

    /* Default Parameters */
    static const Timer_Params defaultParams = {
        .timerMode     = Timer_ONESHOT_BLOCKING,
        .periodUnits   = Timer_PERIOD_COUNTS,
        .timerCallback = NULL,
        .period        = (uint16_t) ~0
    };

    static bool isInitialized = false;

    /*
     *  ======== Timer_control ========
     */
    int_fast16_t Timer_control(Timer_Handle handle, uint_fast16_t cmd, void *arg)
    {
        return handle->fxnTablePtr->controlFxn(handle, cmd, arg);
    }

    /*
     *  ======== Timer_close ========
     */
    void Timer_close(Timer_Handle handle)
    {
        handle->fxnTablePtr->closeFxn(handle);
    }

    /*
     *  ======== Timer_getCount ========
     */
    uint32_t Timer_getCount(Timer_Handle handle)
    {
        return handle->fxnTablePtr->getCountFxn(handle);
    }

    /*
     *  ======== Timer_init ========
     */
    void Timer_init(void)
    {
        uint_least8_t i;
        uint_fast32_t key;

        key = HwiP_disable();

        if (!isInitialized) {
            isInitialized = (bool) true;

            /* Call each driver's init function */
            for (i = 0; i < Timer_count; i++) {
                Timer_config[i].fxnTablePtr->initFxn((Timer_Handle) &(Timer_config[i]));
            }
        }

        HwiP_restore(key);
    }

    /*
     *  ======== Timer_open ========
     */
    Timer_Handle Timer_open(uint_least8_t index, Timer_Params *params)
    {
        Timer_Handle handle = NULL;

        /* Verify driver index and state */
        if (isInitialized && (index < Timer_count)) {
            /* If parameters are NULL use defaults */
            if (params == NULL) {
                params = (Timer_Params *) &defaultParams;
            }

            /* Get handle for this driver instance */
            handle = (Timer_Handle) &(Timer_config[index]);
            handle = handle->fxnTablePtr->openFxn(handle, params);
        }

        return (handle);
    }

    /*
     *  ======== Timer_Params_init ========
     */
    void Timer_Params_init(Timer_Params *params)
    {
        *params = defaultParams;
    }

    /*
     *  ======== Timer_start ========
     */
    int32_t Timer_start(Timer_Handle handle)
    {
        return handle->fxnTablePtr->startFxn(handle);
    }

    /*
     *  ======== Timer_stop ========
     */
    void Timer_stop(Timer_Handle handle)
    {
        handle->fxnTablePtr->stopFxn(handle);
    }