项目需求产生8个1mhz的pwm的脉冲;
尝试方法一:pwm_init 初始化PWM,然后用CPUdelay尝试在开关PWM中间延迟,但是此方法在开关PWM时不太稳定,会产生一个比较宽的脉冲;
方法二:GPTtime定时器,时间到后取反电平,但是此方法需要定时产生0.5us的定时,好像CC2640R2f不支持;
方法三:直接使用CPUdelay,然后取反电平,但是我尝试就算直接取反电平PWM也才200多k,所以定时器的应该也同样不行;
—》问题:请问什么方式产生定量的PWM比较合适,PWM_init后在用新的IO进行捕获吗?
Kevin Qiu1:
可以看下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(¶ms);*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, ¶ms);*if(pwmHandle == NULL) {*Log_error0("Failed to open PWM");*Task_exit();*}*PWM_start(pwmHandle);*@endcode
yekun kun:
回复 Kevin Qiu1:
你好,我需要产生8个1mhz的脉冲,pwm我已经产生了,但是让他形成8个呢
Kevin Qiu1:
回复 yekun kun:
配置需要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);
yekun kun:
回复 Kevin Qiu1:
这不是直接产生PWM波吗,不能控制产生8个脉冲,我的意思是比如平时低电平,按键按下,产生8个脉冲后又是低电平 ,脉冲频率1MHZ,不是产生8个通道PWM被
Kevin Qiu1:
回复 yekun kun:
精确控制脉冲的个数实现起来有点困难,可以尝试用定时器溢出中断计数,每产生一个脉冲,计数器+1
yekun kun:
回复 Kevin Qiu1:
我直接控制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);
效果
Kevin Qiu1:
回复 yekun kun:
试试我上面说的方法,利用定时器计数,产生8个脉冲后停止。这个定时器相当于从定时器,只负责计数,另一个用来产生PWM脉冲。
yekun kun:
回复 Kevin Qiu1:
你的意思的在开一个定时器,触发条件是PWM波定时器溢出?是的话有没有相关定时器的例程或者资料,刚接触这款芯片
Kevin Qiu1:
回复 yekun kun:
是的,定时器请看:C:\ti\simplelink_cc2640r2_sdk_4_20_00_04\source\ti\drivers\timer
yekun kun:
回复 Kevin Qiu1:
你好,在你所给的例程中讲述的比较简单,未涉及定时器的触发方式配置?
下面的例程的代码:
#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);
}