![图片1.png 图片1.png](https://static.assets-stash.eet-china.com/forum/202502/14/173952195258713163232em4ymm5sysr91mu1.png)
![图片2.png 图片2.png](https://static.assets-stash.eet-china.com/forum/202502/14/173952196666585163246jiv8o7qvcccqdnbb.png)
这两个引脚最终可以通过电路连接到PD4和PC5上,而根据单片机的GPIO复用,
![图片3.png 图片3.png](https://static.assets-stash.eet-china.com/forum/202502/14/173952198218080163302jgee8fognzuyuuev.png)
在AF4方式下,PD4和PC5都可以作为定时器2的通道1输出。为了后面使用PWM驱动马达的测试以及作为显示提示,使用PC5显示当前PWM的占空比状况,我想同时使用PD4和PC5作为定时器2的PWM输出通道。为此在程序中按照下面的方式初始化GPIO:
/*IO初始化*/
void GPIO_Configuration(void) {
//初始化模拟IO PC4
GPIO_InitTypeDef GPIO_InitStructure;
// PD4 : 定时器控制PWM输出, AF4 模式下PD4为输出通道
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
// PD4 = TIM2 Channel 1*/
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_4);
// PC5 : LED : 定时器控制PWM输出, AF4 模式下PC5为输出通道
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
// PC5 = TIM2 Channel 1*/
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource5, GPIO_AF_4);
}
复制代码按照下面的方式设置定时器:
void TIM_Config(void) {
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TimerPeriod = (SystemCoreClock / 10000) - 1; //配置输出10KHZPWM
/* Compute CCR1 value to generate a duty cycle at 50% for channel 1 */
Channel1Pulse = (uint16_t)(((uint32_t) 1 * (TimerPeriod - 1)) / 10);
/* Time Base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = TimerPeriod;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
/* Channel 1 Configuration in PWM mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = Channel1Pulse;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
//TIM_SelectOnePulseMode(TIM2, TIM_OPMode_Single);
/* TIM2 counter enable */
TIM_Cmd(TIM2, ENABLE);
}
复制代码为了方便查看占空比是否发生了变化,在主程序中循环调整占空比从10%到90%。
int main(void) {
uint32_t zkb = 0;
uint32_t mode = 0;
RCC_Configuration();
GPIO_Configuration();
ADC_Configuration();
TIM_Config();
softWareDelay();
while (1) {
softWareDelay();
// 改变占空比:
if (mode == 0) {
zkb=(zkb+1)%10;
if (zkb == 9) {
mode = 1;
}
} else {
zkb=(zkb-1)%10;
if (zkb == 0) {
mode = 0;
}
}
TIM2->CCR1 = (uint16_t)((zkb * (TimerPeriod - 1)) / 10);
}
}
复制代码测试结果:
![demo_1.gif demo_1.gif](data/attachment/forum/202502/14/163439kpdgb7eylb1zylga.gif)
用逻辑分析仪捕获到的PWM输出针脚的PWM数据:
![图片4.png 图片4.png](https://static.assets-stash.eet-china.com/forum/202502/14/173952198386682163303d7x5bgvdz7z7dbsz.png)
最小的占空比处:
![图片5.png 图片5.png](https://static.assets-stash.eet-china.com/forum/202502/14/173952198468879163304tz7ahbfj8ejnfbok.png)
为10%不到,最大的占空比处:
![图片6.png 图片6.png](https://static.assets-stash.eet-china.com/forum/202502/14/173952198580678163305yamm4gtf4ee4b4mm.png)
不到90%,与程序代码基本上是匹配的。
用逻辑分析仪捕获到的FG输出针脚的PWM数据:
![图片7.png 图片7.png](https://static.assets-stash.eet-china.com/forum/202502/14/173952198689868163306r09l1kjj880b9j3o.png)
最小的占空比处:
![图片8.png 图片8.png](https://static.assets-stash.eet-china.com/forum/202502/14/173952198754758163307oour4c0upfv44f5p.png)
为10%不到,最大的占空比处:
![图片9.png 图片9.png](https://static.assets-stash.eet-china.com/forum/202502/14/173952198986552163309w77ocolxxcxlq8oc.png)
不到90%,与程序代码基本上也是匹配的。
本次测试证明,是可以同时使定时器的PWM输出通道输出给不同的GPIO口的。