脉冲宽度调制(PWM)是英文 Pulse WidthModulation 的缩写,是利用微控制器的数字输出,来对模拟电路进行控制的一种非常有效的技术。使用高分辨率计数器产生一个方波,方波的占空比被调制成一个模拟信号的编码。
cc3200的例程PWM是呼吸灯,通过调节方波的占空比改变灯泡的亮度,从而实现呼吸灯的效果,下面是主函数:
void main()
{
int iLoopCnt;
BoardInit();
PinMuxConfig();
//
// Initialize the PWMs used for driving the LEDs
//
InitPWMModules();
while(1)
{
for(iLoopCnt = 0; iLoopCnt < 255; iLoopCnt++)
{
UpdateDutyCycle(TIMERA2_BASE, TIMER_B, iLoopCnt);
UpdateDutyCycle(TIMERA3_BASE, TIMER_B, iLoopCnt);
UpdateDutyCycle(TIMERA3_BASE, TIMER_A, iLoopCnt);
MAP_UtilsDelay(800000);//延时子程序(短暂延时)
}
}
}
在主函数中需要使用到的主要函数有:PinMuxConfig(void){ }该函数是用来配置PWM引脚的
void
PinMuxConfig(void)
{
MAP_PRCMPeripheralClkEnable(PRCM_TIMERA2, PRCM_RUN_MODE_CLK);
//设置时钟
MAP_PinTypeTimer(PIN_64, PIN_MODE_3);
//设置引脚以及工作模式(在工作模式是3时只能对外输出)
}
具体参考表格如下所示:
主函数中的 InitPWMModules( );是初始化PWM的,函数内的主要函数是SetupTimerPWMMode(unsigned long ulBase, unsigned long ulTimer,unsigned long ulConfig, unsigned char ucInvert)
void SetupTimerPWMMode(unsigned long ulBase, unsigned long ulTimer,
unsigned long ulConfig, unsigned char ucInvert)
{
//
// Set GPT - Configured Timer in PWM mode.
//
MAP_TimerConfigure(ulBase,ulConfig);// 配置定时器工作在 PWM 模式
MAP_TimerPrescaleSet(ulBase,ulTimer,0);// 设置预分频值
//
// Inverting the timer output if required
//
MAP_TimerControlLevel(ulBase,ulTimer,ucInvert);// 配置 PWM 输出的电平值
//
// Load value set to ~0.5 ms time period
//
MAP_TimerLoadSet(ulBase,ulTimer,TIMER_INTERVAL_RELOAD);//配置 PWM 周期
//
// Match value set so as to output level 0
//
MAP_TimerMatchSet(ulBase,ulTimer,TIMER_INTERVAL_RELOAD);// 配置匹配值,即占空比(当定时器计数到此值时,输出某一电平)
}
在上段代码内可以通过调节预分频的值将时钟等等整个周期进行调整,因为要控制舵机,能驱动舵机需要每20毫秒(ms)看到一个脉冲,而脉冲长度将决定电机转动的距离。例程中的周期达不到20ms所以要调整预分频来控制周期时间(最后能驱动舵机了,但关于里面的运算我理解的还不是很清楚)分频系数只有16位定时器才能设置,当使用32位的定时器时,设置为0。要调整整个时间周期,调整预分频,要调整占空比调整TIMER_INTERVAL_RELOAD。
主函数中的iLoopCnt是循环调节的步长,要确定需要输出pwm的周期。比如说0.5ms,据此确定定时器装载的初始值。(0.5*10的-3次方)/(1/80M) = 40000,如果考虑输出占空比可调,首先需要考虑需要输出多少级可调?比如说100级可调,意思就是LED的亮度有100个等级。那么40000/100 = 400,这个就是每次调节的步长。
最后,放一张整个的功能流程图,祝福大家玩的开心哦~