1 背景
最近有接觸到通過(guò)可控硅的方式來(lái)控制交流風(fēng)機(jī)或者電烙鐵功率,STM32的定時(shí)器輸出比較模式,剛好可以滿足這種需求,借此機(jī)會(huì)總結(jié)一下定時(shí)器的幾種輸出模式。
2 STM32的定時(shí)器比較輸出
STM32的定時(shí)器比較輸出一共有8種,記錄一下初始化方法和邏輯分析儀的波形。
在官網(wǎng)搜索對(duì)應(yīng)的型號(hào)找到用戶手冊(cè),比如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和計(jì)數(shù)器TIMx_CNT之間的比較對(duì)輸出沒(méi)有影響
2.1.2 TIM_OCMODE_ACTIVE
001: Set channel 1 to active level on match。
匹配時(shí)將輸出為有效電平,當(dāng)TIMx_CNT=TIMx_CCR1時(shí)強(qiáng)制輸出為高電平
2.1.3 TIM_OCMODE_INACTIVE
010: Set channel 1 to inactive level on match。
匹配時(shí)將輸出為無(wú)效電平,當(dāng)TIMx_CNT=TIMx_CCR1時(shí)強(qiáng)制輸出為高低電平
2.1.4 TIM_OCMODE_TOGGLE
011: 當(dāng)TIMx_CNT=TIMx_CCR1時(shí)電平翻轉(zhuǎn)。
2.1.5 TIM_OCMODE_FORCED_INACTIVE
100: Force inactive level,強(qiáng)制輸出為低電平(無(wú)效電平)
2.1.6 TIM_OCMODE_FORCED_ACTIVE
101: Force active level,強(qiáng)制輸出為高電平(有效電平)
2.1.7 TIM_OCMODE_PWM1 2.1.8 TIM_OCMODE_PWM2 3 實(shí)測(cè)波形 3.1 TIM_OCMODE_TIMING 3.1.2 波形 極性是低電平時(shí),一直保持高電平 3.2 TIM_OCMODE_ACTIVE 3.2.2 波形 極性是高電平時(shí),會(huì)先輸出脈寬為計(jì)數(shù)周期的低電平,當(dāng)TIMx_CNT=TIMx_CCR2后輸出一直為高電平(有效電平) 3.3 TIM_OCMODE_INACTIVE 3.3.2 波形 極性是高電平時(shí),一直輸出為低電平(無(wú)效電平) 3.4 TIM_OCMODE_TOGGLE 3.4.2 波形 極性是高電平時(shí),會(huì)先輸出一個(gè)脈寬為半個(gè)計(jì)數(shù)周期的低電平,然后一直不停地翻轉(zhuǎn)出一個(gè)脈寬為一個(gè)計(jì)數(shù)周期的電平 3.5 TIM_OCMODE_PWM1 3.5.2 波形 極性是高電平時(shí),當(dāng)TIMx_CNT 3.6 TIM_OCMODE_PWM2 3.6.2 波形 極性是高電平時(shí),當(dāng)TIMx_CNT 3.7 TIM_OCMODE_FORCED_ACTIVE 3.7.2 波形 極性是高電平時(shí),一直輸出為高電平(有效電平)。 3.8 TIM_OCMODE_FORCED_INACTIVE 3.8.2 波形 極性是高電平時(shí),一直輸出為低電平(無(wú)效電平)。 4 應(yīng)用場(chǎng)景 4.2 使用按鍵來(lái)模擬過(guò)零信號(hào),平時(shí)輸出為高電平(無(wú)效電平),當(dāng)按鍵按下時(shí),強(qiáng)制輸出為低電平,并且脈寬為207.5*360/415=180ms,然后輸出持續(xù)為高電平(無(wú)效電平) 4.3 實(shí)測(cè)波形 5 總結(jié)
110: PWM mode 1
當(dāng)TIMx_CNT
111: PWM mode 2
當(dāng)TIMx_CNT
在上電時(shí)默認(rèn)會(huì)有個(gè)100ms的高電平,作為一個(gè)直觀的起始信號(hào),
預(yù)分頻設(shè)置為(72000000/2000)-1,最大計(jì)數(shù)為415-1,則周期是(1*415/2000)=(0.207)s
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);
}
極性是高電平時(shí),上電后100ms后一直保持低電平
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);
}
極性是低電平時(shí),會(huì)先輸出脈寬為計(jì)數(shù)周期的高電平,當(dāng)TIMx_CNT=TIMx_CCR2后輸出一直為低電平(有效電平)
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);
}
極性是低電平時(shí),當(dāng)TIMx_CNT=TIMx_CCR2時(shí)會(huì)出現(xiàn)一個(gè)低電平,但持續(xù)時(shí)間很短,然后一直輸出一個(gè)高電平(無(wú)效電平)
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);
}
極性是低電平時(shí),會(huì)先輸出一個(gè)脈寬為半個(gè)計(jì)數(shù)周期的高電平,然后一直不停地翻轉(zhuǎn)出一個(gè)脈寬為一個(gè)計(jì)數(shù)周期的電平
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);
}
極性是低電平時(shí),當(dāng)TIMx_CNT
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);
}
極性是低電平時(shí),當(dāng)TIMx_CNT
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);
}
極性是低電平時(shí),一直輸出為低電平(有效電平)。
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);
}
極性是低電平時(shí),一直輸出為高電平(無(wú)效電平)。
假設(shè)可控硅是低電平導(dǎo)通,我們需要在初始化時(shí)輸出為高電平,在過(guò)零時(shí)輸出一個(gè)低電平,電平的時(shí)間可控。
4.1 初始化定時(shí)器為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);
}
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;
}
在工作中需要學(xué)習(xí)很多新的東西,這就難免會(huì)有困惑,當(dāng)我們束手無(wú)策的時(shí)候,我們可以借助一些工具,例如邏輯分析儀、示波器來(lái)看看數(shù)據(jù)到底是什么樣的,所有的算法都是基于數(shù)據(jù)來(lái)寫的,以實(shí)際數(shù)據(jù)為導(dǎo)向,結(jié)合理論與實(shí)踐,只有這樣我們才能真正的學(xué)到新的東西。
-
STM32
+關(guān)注
關(guān)注
2266文章
10876瀏覽量
354930 -
輸出
+關(guān)注
關(guān)注
0文章
92瀏覽量
21815 -
定時(shí)器
+關(guān)注
關(guān)注
23文章
3241瀏覽量
114517 -
波形
+關(guān)注
關(guān)注
3文章
378瀏覽量
31511 -
高電平
+關(guān)注
關(guān)注
6文章
147瀏覽量
21341
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論