以STM32F103C8T6使用TIM1的CH1,CH4同時輸出兩路PWM為例:
| 引腳 | 定時器 | 通道 |
| PA8 | TIM1 | CH1 |
| PA11 | TIM1 | CH4 |
步驟:
GPIO_InitTypeDef GPIO_InitStruct; //GPIO初始化結構體
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; //定時器初始化結構體
TIM_OCInitTypeDef TIM_OCInitStruct; //定時器通道初始化結構體
1.開啟時鐘:同時打開GPIOA,TIM1,復用時鐘,
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1 | RCC_APB2Periph_AFIO,ENABLE);//開啟時鐘
2. 初始化GPIOA:
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP; // 初始化GPIO--PA8、PA11為復用推挽輸出
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_8 | GPIO_Pin_11;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct); //GPIO初始化
3.初始化定時器:
TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct); //用其默認值填充每個TIM_TimeBaseInitStruct成員
TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1; //分頻因子
TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up; //向上計數模式
TIM_TimeBaseInitStruct.TIM_Period=Per; //自動重裝載值
TIM_TimeBaseInitStruct.TIM_Prescaler=Psc; //預分頻值
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStruct); //完成定時器初始化
4.初始化定時器通道:
TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1; //初始化輸出比較
TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High;
TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;
TIM_OCInitStruct.TIM_Pulse=0;
TIM_OC1Init(TIM1,&TIM_OCInitStruct); //定時器通道1初始化
TIM_OC4Init(TIM1,&TIM_OCInitStruct); //定時器通道4初始化
TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);// OC1預裝載暫存器使能//CH1 TIM1
TIM_OC4PreloadConfig(TIM1,TIM_OCPreload_Enable);// OC4預裝載暫存器使能//CH4 TIM1
5.完成初始化:
TIM_ARRPreloadConfig(TIM1,ENABLE); //允許或禁止在定時器作業時向ARR(自動重裝載值)的緩沖器中寫入新值,以便在更新事件發生時載入覆寫以前的值,此處為允許
TIM_CtrlPWMOutputs(TIM1,ENABLE);// 高級定時器專屬!!!(通用定時器不用此函式)--MOE主輸出使能 //高級定時器TIM1:必須有這個函式才能輸出PWM: TIM_CtrlPWMOutputs(TIM1,ENABLE);
TIM_Cmd(TIM1,ENABLE); //定時器使能
完整的PWM初始化函式:
/**********************************************************
** 函式名:PWM_Init_TIM1
** 功能描述: 定時器初始化函式
** 入口引數:預分頻值,自動重裝載值
** 輸入引數: Psc(預分頻值),Arr(自動重裝載值)
** 輸出引數: 無
***********************************************************/
void PWM_Init_TIM1(u16 Psc,u16 Arr)
{
GPIO_InitTypeDef GPIO_InitStruct; //GPIO初始化
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; //定時器初始化
TIM_OCInitTypeDef TIM_OCInitStruct; //定時器通道初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1 | RCC_APB2Periph_AFIO,ENABLE);//開啟時鐘
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP; // 初始化GPIO--PA8、PA11為復用推挽輸出
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_8 | GPIO_Pin_11;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct); //GPIO初始化
TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct); //用其默認值填充每個TIM_TimeBaseInitStruct成員
TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1; //分頻因子
TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up; //向上計數模式
TIM_TimeBaseInitStruct.TIM_Period=Arr; //自動重裝載值
TIM_TimeBaseInitStruct.TIM_Prescaler=Psc; //預分頻值
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStruct); //完成定時器初始化
TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1; // 初始化輸出比較
TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High;
TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;
TIM_OCInitStruct.TIM_Pulse=0;
TIM_OC1Init(TIM1,&TIM_OCInitStruct);//定時器通道1初始化
TIM_OC4Init(TIM1,&TIM_OCInitStruct);//定時器通道4初始化
TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);// OC1預裝載暫存器使能//CH1 TIM1
TIM_OC4PreloadConfig(TIM1,TIM_OCPreload_Enable);// OC4預裝載暫存器使能//CH4 TIM1
TIM_ARRPreloadConfig(TIM1,ENABLE); //允許或禁止在定時器作業時向ARR(自動重裝載值)的緩沖器中寫入新值,以便在更新事件發生時載入覆寫以前的值,此處為允許
TIM_CtrlPWMOutputs(TIM1,ENABLE); //高級定時器專屬!!!--MOE主輸出使能 //高級定時器TIM1:必須有這個函式才能輸出PWM: TIM_CtrlPWMOutputs(TIM1,ENABL);
TIM_Cmd(TIM1,ENABLE); //定時器使能
//TIM_SetCompare1(TIM1,500);//設定TIMx捕獲比較1暫存器值 此處為TIM1通道1
//TIM_SetCompare4(TIM1,500);//設定TIMx捕獲比較4暫存器值 此處為TIM1通道4
}
修改輸出PWM的頻率和占空比
1.頻率:
PWM的頻率 = 時鐘頻率 / (自動重裝載值 + 1) * (預分頻值 + 1)
STM32F103C8T6最大時鐘頻率為72MHZ = 72 000 000 HZ
通過修改Psc和Arr可以輸出不同頻率的PWM輸出
PWM_Init_TIM1(0,7199); // PWM頻率 f = 72000000/(7199+1)*(0+1) = 10KHZ
// PWM周期 T = 1/f = 1/10000 = 0.0001S = 0.1ms
2.占空比:
使用函式
TIM_SetComparex(TIM_TypeDef* TIMx, uint16_t Comparex)
/**
* @brief Sets the TIMx Capture Compare1 Register value
* @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral.
* @param Compare1: specifies the Capture Compare1 register new value.
* @retval None
*/
void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1)
{
/* Check the parameters */
assert_param(IS_TIM_LIST8_PERIPH(TIMx));
/* Set the Capture Compare1 Register value */
TIMx->CCR1 = Compare1;
}
Compare1(CH1)是用于與TIMx比較的數,相當于用TIMx的一個周期的時間減去這個Compare1,使得TIMx的周期從后面開始的Compare1的時間為TIMx的前部分時間的反向,即若前部分時間為高電平,則Compare1段所在時間為低電平,若前部分時間為低電平,則Compare1段所在時間為高電平,(可通過配置PWM模式及CCER修改,參考正點原子PWM輸出實驗)

圖片源自正點原子
PWM占空比 = CCRx/ARR 或 PWM占空比 =( ARR-CCRx)/ARR
PWM_Init_TIM1(0,7199); // PWM頻率 f = 72000000/(7199+1)*(0+1) = 10KHZ
// PWM周期 T = 1/f = 1/10000 = 0.0001S = 0.1ms
TIM_SetCompare1(TIM1,3599);//設定TIMx捕獲比較1暫存器值 此處為TIM1通道1 占空比為50%
TIM_SetCompare4(TIM1,3599);//設定TIMx捕獲比較4暫存器值 此處為TIM1通道4 占空比為50%
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/344376.html
標籤:其他
