MM32F3273G8P火龙果开发板MindSDK开发教程21 - PWM的使用
1、简述
开发版的LED灯连接PA1脚,而PA1可以映射TIM2_CH2,所以我们用通用定时器2的TIM2_CH2输出PWM到PA1脚,通过更改PWM的占空比,来改变LED的亮度。
2、LED灯的初始化
将PA1设定为GPIO_PinMode_AF_PushPull,并开启映射。
void GPIO_PA1_Config(void)
{
/* gpio. */
GPIO_Init_Type gpio_init;
/* PA1 - TIM2_CH2_COMP. */
gpio_init.Pins = GPIO_PIN_1;
gpio_init.PinMode = GPIO_PinMode_AF_PushPull;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &gpio_init);
GPIO_PinAFConf(GPIOA, gpio_init.Pins, GPIO_AF_1);
}
3、Tim2的初始化
假定输出1KHZ的pwm波形,tim2的时钟频率为120000000,设定tim2 的prescaler = 120 -1,那么tim2 color = 120000000/(120+1) = 1000000,即StepFreqHz=1000000 。也就是1s钟需要计数1000000次,而0.001s需要计数1000次,所以period = 1000 -1。
TIM_PutChannelValue(TIM2, TIM_CHN_2, 500);/* Change duty cycle. */ 500 即period的一半,占空比=500/1000=50%,250即占空比=25%。
void TIM2_Config(void)
{
GPIO_PA1_Config();
/* Set the counter counting step. 1000HZ*/
TIM_Init_Type tim_init;
tim_init.ClockFreqHz = 120000000;
tim_init.StepFreqHz = 1000000;
tim_init.Period = 1000 - 1u;
tim_init.EnablePreloadPeriod = false;
tim_init.PeriodMode = TIM_PeriodMode_Continuous;
tim_init.CountMode = TIM_CountMode_Increasing;
TIM_Init(TIM2, &tim_init);
/* Set the PWM output channel. */
TIM_OutputCompareConf_Type tim_outcomp_conf;
tim_outcomp_conf.ChannelValue = 0u;
tim_outcomp_conf.EnableFastOutput = false;
tim_outcomp_conf.EnablePreLoadChannelValue = false; /* Disable preload, put data immediately. */
tim_outcomp_conf.RefOutMode = TIM_OutputCompareRefOut_FallingEdgeOnMatch;
tim_outcomp_conf.ClearRefOutOnExtTrigger = false;
tim_outcomp_conf.PinPolarity = TIM_PinPolarity_Rising;
TIM_EnableOutputCompare(TIM2, TIM_CHN_2, &tim_outcomp_conf);
/* Start the output compare. */
TIM_EnableOutputCompareSwitch(TIM2, true);
TIM_PutChannelValue(TIM2, TIM_CHN_2, 500);/* Change duty cycle. */
/* Start the counter. */
TIM_Start(TIM2);
}
4、Letter Shell命令添加
pwn on 开启pwm
pwm off 关闭pwm
pwm freq xx (xx为1-1000的数值)。设定pwm的占空比
int set_pwm(int argc,char *argv[])
{
if (argc == 2)
{
if (!strncmp(argv[1],"on",2))
{
TIM_Start(TIM2);
printf("PWM On\r\n");
}
else if(!strncmp(argv[1],"off",3))
{
TIM_Stop(TIM2);
LED_Off();
printf("PWM Off\r\n");
}
else
{
printf("error ,please use 'pwm freq xx(1-1000)' /pwm on /pwm off\r\n");
return -1;
}
}
else if (argc == 3)
{
if (!strncmp(argv[1],"freq",4))
{
uint16_t period = strtol(argv[2],NULL,10);
if (period > 0 && period < 1000)
{
printf("Pwm duty cycle changed \r\n");
TIM_Stop(TIM2);
LED_Off();
TIM_PutChannelValue(TIM2, TIM_CHN_2, period);/* Change duty cycle. */
TIM_Start(TIM2);
}
else
{
printf("error ,please use 'pwm freq xx(1-1000)' /pwm on /pwm off\r\n");
return -1;
}
}
else
{
printf("error ,please use 'pwm freq xx(1-1000)' /pwm on /pwm off\r\n");
return -1;
}
}
else
{
printf("error ,please use 'pwm freq xx(1-1000)' /pwm on /pwm off\r\n");
return -1;
}
return 0;
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), pwm, set_pwm, set_pwm);
5、现象
输入pwm freq 200 以及pwm freq 800的波形图如下:
6、代码
下载路径