1 背景
最近有接觸到通過可控硅的方式來控制交流風機或者電烙鐵功率,STM32的定時器輸出比較模式,剛好可以滿足這種需求,借此機會總結(jié)一下定時器的幾種輸出模式。
2 STM32的定時器比較輸出
STM32的定時器比較輸出一共有8種,記錄一下初始化方法和邏輯分析儀的波形。
在官網(wǎng)搜索對應的型號找到用戶手冊,比如STM32F103ZET6
找到比較模式相關(guān)配置的描述
TIMx capture/compare mode register 1 (TIMx_CCMR1)
Address offset: 0x18 Reset value: 0x0000
The channels can be used in input (capture mode) or in output (compare mode). The
direction of a channel is defined by configuring the corresponding CCxS bits. All the other
bits of this register have a different function in input and in output mode. For a given bit,
OCxx describes its function when the channel is configured in output, ICxx describes it
function when the channel is configured in input. Take care that the same bit can have a
different meaning for the input stage and for the output stage。
2.1 OCxM 輸出匹配模式
OC1M用于配置通道1,通道2則在OC2M上
2.1.1 TIM_OCMODE_TIMING
000:Frozen凍結(jié)模式
TIMx_CCR1和計數(shù)器TIMx_CNT之間的比較對輸出沒有影響
2.1.2 TIM_OCMODE_ACTIVE
001: Set channel 1 to active level on match。
匹配時將輸出為有效電平,當TIMx_CNT=TIMx_CCR1時強制輸出為高電平
2.1.3 TIM_OCMODE_INACTIVE
010: Set channel 1 to inactive level on match。
匹配時將輸出為無效電平,當TIMx_CNT=TIMx_CCR1時強制輸出為高低電平
2.1.4 TIM_OCMODE_TOGGLE
011: 當TIMx_CNT=TIMx_CCR1時電平翻轉(zhuǎn)。
2.1.5 TIM_OCMODE_FORCED_INACTIVE
100: Force inactive level,強制輸出為低電平(無效電平)
2.1.6 TIM_OCMODE_FORCED_ACTIVE
101: Force active level,強制輸出為高電平(有效電平)
2.1.7 TIM_OCMODE_PWM1
110: PWM mode 1
當TIMx_CNT
2.1.8 TIM_OCMODE_PWM2
111: PWM mode 2
當TIMx_CNT
3 實測波形
在上電時默認會有個100ms的高電平,作為一個直觀的起始信號,
預分頻設(shè)置為(72000000/2000)-1,最大計數(shù)為415-1,則周期是(1*415/2000)=(0.207)s
3.1 TIM_OCMODE_TIMING
3.1.1初始化代碼
void TIM1_PWM_Init(u16 arr,u16 psc)
{
htim2.Instance = TIM2;
htim2.Init.Prescaler = psc;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = arr;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
htim2.Init.RepetitionCounter = 0;
HAL_TIM_OC_Init(&htim2);
sConfigOC.OCMode = TIM_OCMODE_TIMING;;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2);
TIM_CCxChannelCmd(TIM2, TIM_CHANNEL_2, TIM_CCx_ENABLE);//
HAL_TIM_Base_Start_IT(&htim2);
}
3.1.2 波形
極性是高電平時,上電后100ms后一直保持低電平
極性是低電平時,一直保持高電平
3.2 TIM_OCMODE_ACTIVE
3.2.1初始化代碼
void TIM1_PWM_Init(u16 arr,u16 psc)
{
htim2.Instance = TIM2;
htim2.Init.Prescaler = psc;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = arr;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
htim2.Init.RepetitionCounter = 0;
HAL_TIM_OC_Init(&htim2);
sConfigOC.OCMode = TIM_OCMODE_ACTIVE;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2);
TIM_CCxChannelCmd(TIM2, TIM_CHANNEL_2, TIM_CCx_ENABLE);//
HAL_TIM_Base_Start_IT(&htim2);
}
3.2.2 波形
極性是低電平時,會先輸出脈寬為計數(shù)周期的高電平,當TIMx_CNT=TIMx_CCR2后輸出一直為低電平(有效電平)
極性是高電平時,會先輸出脈寬為計數(shù)周期的低電平,當TIMx_CNT=TIMx_CCR2后輸出一直為高電平(有效電平)
3.3 TIM_OCMODE_INACTIVE
3.3.1初始化代碼
void TIM1_PWM_Init(u16 arr,u16 psc)
{
htim2.Instance = TIM2;
htim2.Init.Prescaler = psc;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = arr;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
htim2.Init.RepetitionCounter = 0;
HAL_TIM_OC_Init(&htim2);
sConfigOC.OCMode = TIM_OCMODE_INACTIVE;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2);
TIM_CCxChannelCmd(TIM2, TIM_CHANNEL_2, TIM_CCx_ENABLE);//
HAL_TIM_Base_Start_IT(&htim2);
}
3.3.2 波形
極性是低電平時,當TIMx_CNT=TIMx_CCR2時會出現(xiàn)一個低電平,但持續(xù)時間很短,然后一直輸出一個高電平(無效電平)
極性是高電平時,一直輸出為低電平(無效電平)
3.4 TIM_OCMODE_TOGGLE
3.4.1初始化代碼
void TIM1_PWM_Init(u16 arr,u16 psc)
{
htim2.Instance = TIM2;
htim2.Init.Prescaler = psc;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = arr;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
htim2.Init.RepetitionCounter = 0;
HAL_TIM_OC_Init(&htim2);
sConfigOC.OCMode = TIM_OCMODE_TOGGLE;
sConfigOC.Pulse = arr/2;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2);
TIM_CCxChannelCmd(TIM2, TIM_CHANNEL_2, TIM_CCx_ENABLE);//
HAL_TIM_Base_Start_IT(&htim2);
}
3.4.2 波形
極性是低電平時,會先輸出一個脈寬為半個計數(shù)周期的高電平,然后一直不停地翻轉(zhuǎn)出一個脈寬為一個計數(shù)周期的電平
極性是高電平時,會先輸出一個脈寬為半個計數(shù)周期的低電平,然后一直不停地翻轉(zhuǎn)出一個脈寬為一個計數(shù)周期的電平
3.5 TIM_OCMODE_PWM1
3.5.1初始化代碼
void TIM1_PWM_Init(u16 arr,u16 psc)
{
htim2.Instance = TIM2;
htim2.Init.Prescaler = psc;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = arr;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
htim2.Init.RepetitionCounter = 0;
HAL_TIM_OC_Init(&htim2);
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = arr*2/3;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2);
TIM_CCxChannelCmd(TIM2, TIM_CHANNEL_2, TIM_CCx_ENABLE);//
HAL_TIM_Base_Start_IT(&htim2);
}
3.5.2 波形
極性是低電平時,當TIMx_CNT
極性是高電平時,當TIMx_CNT
3.6 TIM_OCMODE_PWM2
3.6.1初始化代碼
void TIM1_PWM_Init(u16 arr,u16 psc)
{
htim2.Instance = TIM2;
htim2.Init.Prescaler = psc;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = arr;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
htim2.Init.RepetitionCounter = 0;
HAL_TIM_OC_Init(&htim2);
sConfigOC.OCMode = TIM_OCMODE_PWM2;
sConfigOC.Pulse = arr*2/3;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2);
TIM_CCxChannelCmd(TIM2, TIM_CHANNEL_2, TIM_CCx_ENABLE);//
HAL_TIM_Base_Start_IT(&htim2);
}
3.6.2 波形
極性是低電平時,當TIMx_CNT
極性是高電平時,當TIMx_CNT
3.7 TIM_OCMODE_FORCED_ACTIVE
3.7.1初始化代碼
void TIM1_PWM_Init(u16 arr,u16 psc)
{
htim2.Instance = TIM2;
htim2.Init.Prescaler = psc;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = arr;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
htim2.Init.RepetitionCounter = 0;
HAL_TIM_OC_Init(&htim2);
sConfigOC.OCMode = TIM_OCMODE_FORCED_ACTIVE;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2);
TIM_CCxChannelCmd(TIM2, TIM_CHANNEL_2, TIM_CCx_ENABLE);//
HAL_TIM_Base_Start_IT(&htim2);
}
3.7.2 波形
極性是低電平時,一直輸出為低電平(有效電平)。
極性是高電平時,一直輸出為高電平(有效電平)。
3.8 TIM_OCMODE_FORCED_INACTIVE
3.8.1初始化代碼
void TIM1_PWM_Init(u16 arr,u16 psc)
{
htim2.Instance = TIM2;
htim2.Init.Prescaler = psc;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = arr;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
htim2.Init.RepetitionCounter = 0;
HAL_TIM_OC_Init(&htim2);
sConfigOC.OCMode = TIM_OCMODE_FORCED_INACTIVE;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2);
TIM_CCxChannelCmd(TIM2, TIM_CHANNEL_2, TIM_CCx_ENABLE);//
HAL_TIM_Base_Start_IT(&htim2);
}
3.8.2 波形
極性是低電平時,一直輸出為高電平(無效電平)。
極性是高電平時,一直輸出為低電平(無效電平)。
4 應用場景
假設(shè)可控硅是低電平導通,我們需要在初始化時輸出為高電平,在過零時輸出一個低電平,電平的時間可控。
4.1 初始化定時器為TIM_OCMODE_INACTIVE模式
void TIM1_PWM_Init(u16 arr,u16 psc)
{
htim2.Instance = TIM2;
htim2.Init.Prescaler = psc;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = arr;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
htim2.Init.RepetitionCounter = 0;
HAL_TIM_OC_Init(&htim2);
sConfigOC.OCMode = TIM_OCMODE_INACTIVE;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2);
TIM_CCxChannelCmd(TIM2, TIM_CHANNEL_2, TIM_CCx_ENABLE);//
HAL_TIM_Base_Start_IT(&htim2);
}
4.2 使用按鍵來模擬過零信號,平時輸出為高電平(無效電平),當按鍵按下時,強制輸出為低電平,并且脈寬為207.5*360/415=180ms,然后輸出持續(xù)為高電平(無效電平)
key = KEY_Scan(0);
if(key == KEY0_PRES)
{
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_SET);
TIM2- >CCMR1 = (TIM_OCMODE_FORCED_ACTIVE< 8);
TIM2- >CNT=0;
TIM2- >CCR2 = (90*4-1);
TIM2- >CCMR1 = (TIM_OCMODE_INACTIVE< 8);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_RESET);
LED0 =!LED0;
}
4.3 實測波形
-
可控硅
+關(guān)注
關(guān)注
43文章
959瀏覽量
71856 -
比較器
+關(guān)注
關(guān)注
14文章
1651瀏覽量
107217 -
預分頻器
+關(guān)注
關(guān)注
0文章
18瀏覽量
8135 -
STM32F103ZET6
+關(guān)注
關(guān)注
9文章
67瀏覽量
21128 -
stm32定時器
+關(guān)注
關(guān)注
0文章
13瀏覽量
2294
發(fā)布評論請先 登錄
相關(guān)推薦
評論