CC1310生成PWM波

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CC1310生成PWM波相关的知识,希望对你有一定的参考价值。

工作中因为时间紧迫,我不得不抛开TI提供的TI-RTOS、sdk和xdctools等工具,采用ucos + 库函数的方式去开发。最开始一头扎进去,碰见的就PWM的生成。

PWM方面,TI自带封装好了PWM函数进行pwm的生成。

假如:我的需求是PWM的周期是2s,占空比50%,MCU主频是48MHz。于是我直接设置

params.periodUnits = PWM_PERIOD_US;

params.periodValue = pwmPeriod;

params.dutyUnits = PWM_DUTY_US;//PWM_DUTY_US;

params.dutyValue = 0;

但是问题来了,pwmPeriod的值最大不过340000,再往大设置,PWM_Open()就会返回NULL。我也尝试了对GPTimerA0进行分频,也不起任何作用。

 

后来用库函数开发,直接抛弃了drivers提供的驱动,使用driverlib。

在程序开始初始化时,对定时器进行分频。

PRCMGPTimerClockDivisionSet(PRCM_CLOCK_DIV_16);

以上函数将定时器时钟源主频从48MHz分为3MHz,之后好操作。

先贴程序

void GPTimerA0Prescaler(uint32_t frequence)

{     

  uint32_t ValuePWMDivFactor ;     

 uint32_t ValueLoadSetLower ;     

  uint32_t ValueLoadSetHigher ;     

 uint32_t ValueLoadMatchLower ;     

 uint32_t ValueLoadMatchHigher ;     

 uint32_t ValueTemp ;     

 IOCPortConfigureSet(LED_GREEN,IOC_PORT_MCU_PORT_EVENT0,IOC_IOMODE_NORMAL   | IOC_IOPULL_UP|IOC_STRENGTH_MAX | IOC_INT_DISABLE);     

 GPIO_setOutputEnableDio(LED_GREEN,GPIO_OUTPUT_ENABLE);     

 GPIO_writeDio(LED_GREEN,0);

  TimerDisable(GPT0_BASE, TIMER_A);

  TimerConfigure(GPT0_BASE, TIMER_CFG_SPLIT_PAIR|TIMER_CFG_A_PWM);     

 TimerLevelControl(GPT0_BASE, TIMER_A, 0);          

 TimerPrescaleSet(GPT0_BASE, TIMER_A, 1) ;     

 TimerPrescaleMatchSet(GPT0_BASE, TIMER_A, 1);

 ValuePWMDivFactor = frequence;     

 ValueTemp = ValuePWMDivFactor - 1 ;     

 ValueLoadSetLower = ValueTemp & 0xFFFF ;     

 ValueLoadSetHigher = ValueTemp & 0xFFFF0000 ;     

 ValueLoadSetHigher = ValueLoadSetHigher >> 16 ;

 ValueTemp = ((ValuePWMDivFactor)/2) - 1 ; ;     

ValueLoadMatchLower = ValueTemp & 0xFFFF ;     

ValueLoadMatchHigher = ValueTemp & 0xFFFF0000 ;     

ValueLoadMatchHigher = ValueLoadMatchHigher >> 16 ;

TimerPrescaleSet(GPT0_BASE, TIMER_A, ValueLoadSetHigher);     

TimerPrescaleMatchSet(GPT0_BASE, TIMER_A, ValueLoadMatchHigher) ;          

TimerLoadSet(GPT0_BASE, TIMER_A, ValueLoadSetLower);     

TimerMatchSet(GPT0_BASE, TIMER_A,ValueLoadMatchLower);

TimerEnable(GPT0_BASE, TIMER_A);

}

这是一个让LED闪烁的函数,PWM控制LED,频率可以自己设置。

 

 IOCPortConfigureSet(LED_GREEN,IOC_PORT_MCU_PORT_EVENT0, IOC_IOMODE_NORMAL   | IOC_IOPULL_UP | IOC_STRENGTH_MAX | IOC_INT_DISABLE);     

 GPIO_setOutputEnableDio(LED_GREEN,GPIO_OUTPUT_ENABLE);     

 GPIO_writeDio(LED_GREEN,0);

这三个函数是LED口初始化。

第一句是配置挂上IOC_PORT_MCU_PORT_EVENT0,普通模式,上拉,最大驱动力,禁止中断;第二句设置输出使能;第三句是输出低电平。

 

接下来是初始化定时器

TimerDisable(GPT0_BASE, TIMER_A); 

  TimerConfigure(GPT0_BASE, TIMER_CFG_SPLIT_PAIR|TIMER_CFG_A_PWM);     

 TimerLevelControl(GPT0_BASE, TIMER_A, 0);          

 TimerPrescaleSet(GPT0_BASE, TIMER_A, 1) ;     

 TimerPrescaleMatchSet(GPT0_BASE, TIMER_A, 1);

首先禁止定时器A模块,配置GPT0_BASE为两个半宽度定时器和定时器A的PWM模式;其次设置定时器A高电平有效;最后设置定时器A的分频值和分频匹配值为1。

 

第三是将设置的频率分为高字节和低字节两部分,匹配值设置为频率的一半,即50%的方波,也分成高字节和低字节两部分。

ValuePWMDivFactor = frequence;     

 ValueTemp = ValuePWMDivFactor - 1 ;     

 ValueLoadSetLower = ValueTemp & 0xFFFF ;     

 ValueLoadSetHigher = ValueTemp & 0xFFFF0000 ;     

 ValueLoadSetHigher = ValueLoadSetHigher >> 16 ;

 ValueTemp = ((ValuePWMDivFactor)/2) - 1 ;

ValueLoadMatchLower = ValueTemp & 0xFFFF ;     

ValueLoadMatchHigher = ValueTemp & 0xFFFF0000 ;     

ValueLoadMatchHigher = ValueLoadMatchHigher >> 16 ;

 

第四就是要把这些值输入到定时器里去。

TimerPrescaleSet(GPT0_BASE, TIMER_A, ValueLoadSetHigher);     

TimerPrescaleMatchSet(GPT0_BASE, TIMER_A, ValueLoadMatchHigher) ;          

TimerLoadSet(GPT0_BASE, TIMER_A, ValueLoadSetLower);     

TimerMatchSet(GPT0_BASE, TIMER_A,ValueLoadMatchLower);

TimerEnable(GPT0_BASE, TIMER_A);

将高字节的频率值放入定时器分频,将匹配值高字节放入分频匹配设置函数,将低字节的频率值设为定时器载入值,将匹配值低字节设置为定时器匹配载入值。

最后使能定时器。

 

如果想设置两个IO口相位差为180度的PWM波,则需要先配置一下第二个口

例如     IOCPortConfigureSet(LED_BLUE,IOC_PORT_MCU_PORT_EVENT2,IOC_IOMODE_NORMAL | IOC_IOPULL_UP | IOC_STRENGTH_MAX | IOC_INT_DISABLE);
            GPIO_setOutputEnableDio(LED_BLUE,GPIO_OUTPUT_ENABLE);
            GPIO_writeDio(LED_BLUE,0);

区别在于挂上的事件为IOC_PORT_MCU_PORT_EVENT2,为什么不是IOC_PORT_MCU_PORT_EVENT1,是因为IOC_PORT_MCU_PORT_EVENT1对应的是TIMER_B。

然后加上

TimerDisable(GPT1_BASE, TIMER_A);

TimerConfigure(GPT1_BASE, TIMER_CFG_SPLIT_PAIR|TIMER_CFG_A_PWM);
TimerLevelControl(GPT1_BASE, TIMER_A, 1);

区别在于TimerLevelControl(GPT1_BASE, TIMER_A, 0),要求低电平有效。

其余的按照GPT1_BASE配置之后的定时器设置,就可以实现两个PWM波相位差180度。

以上是关于CC1310生成PWM波的主要内容,如果未能解决你的问题,请参考以下文章

10-20k方波三角波生成器 50-100kPWM方波

10-20k方波三角波生成器 50-100kPWM方波

10-20k方波三角波生成器 50-100kPWM方波

STM32F103 使用TIM3产生四路PWM

三相方波逆变电路pwm死区时间

STM32 输出pwm方波在线等