STM32F107VCT6开发板学习问题笔记
demi 在 提交
demi 在 提交
一、配置定时器为PWM产生
二、配置时钟树
三、定时器配置
四、配置完生成程序后,主程序里还要进行启动PWM就可以了
MX_TIM3_Init(); HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);//启动。置1 CCER的输出使能位bit4 HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);//CCER的bit0
然后可以改变占空比了。
**特别注意:**占空比不能大于自动重载寄存器ARR的值,不然输出的都是高电平。这个问题整了一天。
五、程序分析
/* TIM3 init function */
static void MX_TIM3_Init(void)
{
TIM_MasterConfigTypeDef sMasterConfig; TIM_OC_InitTypeDef sConfigOC; //------------------实际是调用TIM_Base_SetConfig配置定时器,上一篇分析过-- htim3.Instance = TIM3; htim3.Init.Prescaler = 71; htim3.Init.CounterMode = TIM_COUNTERMODE_UP; htim3.Init.Period = 99; htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_PWM_Init(&htim3) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } //---------------------这个是默认的,不管------------------------------- sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } //----------------配置输出比较部分-- 上图5部分------------------------------- sConfigOC.OCMode = TIM_OCMODE_PWM1;//输出模式PWM1 sConfigOC.Pulse = 80;//占空比 sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;//高电平极性 sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } //---------------------------------------------------------------------------------- sConfigOC.Pulse = 50; if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } HAL_TIM_MspPostInit(&htim3);//初始化引脚IO }
初始化PWM通道HAL_TIM_PWM_ConfigChannel------>调用
case TIM_CHANNEL_1: { assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); /* Configure the Channel 1 in PWM mode */ TIM_OC1_SetConfig(htim->Instance, sConfig); /* Set the Preload enable bit for channel1 */ htim->Instance->CCMR1 |= TIM_CCMR1_OC1PE;//比较模式寄存器CCMR1的bit3位OC1PE置1,写入到CCR1的值在事件更新时,才会传到影子寄存器。清0则写入CCR1的值会马上起作用 /* Configure the Output Fast mode */ htim->Instance->CCMR1 &= ~TIM_CCMR1_OC1FE;//配置CCMR1的bit2位,输出比较快速使能 htim->Instance->CCMR1 |= sConfig->OCFastMode; } break; //-------------------------------------------------------------------------------- void TIM_OC1_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config) { uint32_t tmpccmrx = 0U; uint32_t tmpccer = 0U; uint32_t tmpcr2 = 0U; /* Disable the Channel 1: Reset the CC1E Bit */ TIMx->CCER &= ~TIM_CCER_CC1E;//关通道 CCER bit0清0 /* 读出三个寄存器的值 */ tmpccer = TIMx->CCER; tmpcr2 = TIMx->CR2; tmpccmrx = TIMx->CCMR1; /* Reset the Output Compare Mode Bits */ tmpccmrx &= ~TIM_CCMR1_OC1M;//复位CCMR1的bit6:4 tmpccmrx &= ~TIM_CCMR1_CC1S;//复制CCMR1的bit1:0 /* Select the Output Compare Mode */ tmpccmrx |= OC_Config->OCMode;//配置OC1M为 110 PWM1模式 /* Reset the Output Polarity level */ tmpccer &= ~TIM_CCER_CC1P;//配置输出极性 CCER的 CC1P位 tmpccer |= OC_Config->OCPolarity; if(IS_TIM_CCXN_INSTANCE(TIMx, TIM_CHANNEL_1))//如果是定时器1的123通道,还要设置互补输出 { assert_param(IS_TIM_OCN_POLARITY(OC_Config->OCNPolarity)); /* Reset the Output N Polarity level */ tmpccer &= ~TIM_CCER_CC1NP; /* Set the Output N Polarity */ tmpccer |= OC_Config->OCNPolarity; /* Reset the Output N State */ tmpccer &= ~TIM_CCER_CC1NE; } if(IS_TIM_BREAK_INSTANCE(TIMx))//如果是定时器1,还要设置CR2的bit8 bit9 死区控制 { /* Check parameters */ assert_param(IS_TIM_OCNIDLE_STATE(OC_Config->OCNIdleState)); assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState)); /* Reset the Output Compare and Output Compare N IDLE State */ tmpcr2 &= ~TIM_CR2_OIS1; tmpcr2 &= ~TIM_CR2_OIS1N; /* Set the Output Idle state */ tmpcr2 |= OC_Config->OCIdleState; /* Set the Output N Idle state */ tmpcr2 |= OC_Config->OCNIdleState; } /* 把设置好的值写入这4个寄存器 */ TIMx->CR2 = tmpcr2; TIMx->CCMR1 = tmpccmrx; TIMx->CCR1 = OC_Config->Pulse;//占空比 TIMx->CCER = tmpccer; }
流程图如下:
需要改变占空比的,直接调用
__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,dutycycle);
改变寄存器CCR1,改变的值是立即生效还是下一个周期生效取决于CCMR1的OC1PE位
while (1) { while(dutycycle<100) { dutycycle+=10; __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,dutycycle); HAL_Delay(1); } while(dutycycle) { dutycycle-=10; __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,dutycycle); HAL_Delay(1); } }
版权声明:本文为CSDN博主 - D.luffy 的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/liangbin414/article/details/88707340