码迷,mamicode.com
首页 > 其他好文 > 详细

CC1310生成PWM波

时间:2017-08-31 22:25:21      阅读:1183      评论:0      收藏:0      [点我收藏+]

标签:iocp   输入   cal   时间   ocp   ioc   res   visio   eth   

工作中因为时间紧迫,我不得不抛开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波

标签:iocp   输入   cal   时间   ocp   ioc   res   visio   eth   

原文地址:http://www.cnblogs.com/yang1808/p/7460621.html

(1)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!