日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

STM32学习及开发笔记八:采用主从计时器实现精确脉冲输出

發(fā)布時(shí)間:2024/7/23 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32学习及开发笔记八:采用主从计时器实现精确脉冲输出 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

脈沖信號(hào)用于設(shè)備控制是非常常見的,但在一些情況下,我們希望精確的控制脈沖的數(shù)量以實(shí)現(xiàn)對(duì)運(yùn)動(dòng)的精確控制。實(shí)現(xiàn)的方式也許有多種多樣,但使用計(jì)時(shí)器來實(shí)現(xiàn)此類操作是人們比較容易想到的。

1、原理概述

我們知道在STM32平臺(tái)上,使用計(jì)時(shí)器來實(shí)現(xiàn)PWM操作是非常常見的用法。使用的是單一計(jì)時(shí)器,事實(shí)上通過主從兩個(gè)計(jì)時(shí)器配合我們也可通過生成PWM波的方式精確控制輸出脈沖的數(shù)量。接下來我們就來簡(jiǎn)單了解一下使用主從計(jì)時(shí)器實(shí)現(xiàn)精確數(shù)量脈沖輸出的原理。

對(duì)于STM32平臺(tái)一般都有TIM1和TIM8兩個(gè)高級(jí)定時(shí)器和TIM2、TIM3、TIM、TIM5等幾個(gè)通用定時(shí)器。STM32的這些定時(shí)器可以通過另外一個(gè)定時(shí)器的某一個(gè)條件被觸發(fā)而啟動(dòng)。這里所謂某一個(gè)條件可以是定時(shí)到時(shí)、定時(shí)器超時(shí)、比較成功等各種條件。這種通過一個(gè)定時(shí)器觸發(fā)另一個(gè)定時(shí)器的工作方式稱為定時(shí)器的同步,發(fā)出觸發(fā)信號(hào)的定時(shí)器工作于主模式,接受觸發(fā)信號(hào)而啟動(dòng)的定時(shí)器工作于從模式。這些個(gè)計(jì)時(shí)器都可用作從計(jì)時(shí)器,但作為主計(jì)時(shí)器則是對(duì)應(yīng)不同的觸發(fā)源,它們的主從關(guān)系必須遵循設(shè)定不可隨意配置。具體的配置關(guān)系如下:

當(dāng)然要實(shí)現(xiàn)精確控制脈沖輸出,就需要按照上述列表中的要求實(shí)現(xiàn)主從計(jì)時(shí)器的配置。對(duì)于主計(jì)時(shí)器來說,要將輸出配置為PWM輸出,并將觸發(fā)輸出的主從模式啟用。而對(duì)于從計(jì)時(shí)器來說,需要啟用從模式,并設(shè)為門控方式,觸發(fā)源則根據(jù)上述表中的描述來選擇。

可是為什么主從計(jì)時(shí)器就能實(shí)現(xiàn)精確數(shù)量的脈沖輸出呢?我們借助下面的簡(jiǎn)單圖示來說明這個(gè)問題。

首先按前面所述的主從計(jì)時(shí)器要求配置好主從計(jì)時(shí)器,這是最基本的要求。主計(jì)時(shí)器負(fù)責(zé)設(shè)置脈沖輸出的頻率以及輸出脈沖,從計(jì)數(shù)器所控制輸出的脈沖數(shù)。具體過程是這樣的,主進(jìn)程啟動(dòng)主從計(jì)時(shí)器,從計(jì)時(shí)器通過主計(jì)時(shí)器輸出的觸發(fā)信號(hào)開始脈沖計(jì)數(shù),當(dāng)達(dá)到指定的計(jì)數(shù)值后,產(chǎn)生中斷停止主計(jì)時(shí)器輸出,直到主進(jìn)程再次開啟這一過程。

2、系統(tǒng)設(shè)計(jì)

我們已經(jīng)了解了通過主從計(jì)時(shí)器實(shí)現(xiàn)精確數(shù)量脈沖輸出的基本原理。那究竟如何實(shí)際做呢?接下來我們就設(shè)計(jì)一個(gè)簡(jiǎn)單的系統(tǒng)實(shí)現(xiàn)它。

在這一系統(tǒng)中,我是使用STM32F407作為實(shí)現(xiàn)平臺(tái),以TIM1作為主計(jì)時(shí)器,TIM4作為從計(jì)時(shí)器,同時(shí)輸出四路脈沖信號(hào)。四路的頻率是相同的,但每一路的輸出數(shù)量是可以設(shè)定的。具體的操作結(jié)構(gòu)如下圖所示:

主進(jìn)程輪詢控制計(jì)時(shí)器TIM1和TIM4工作,而TIM1主計(jì)時(shí)器給TIM4從計(jì)時(shí)器輸出觸發(fā)信號(hào),而從計(jì)時(shí)器到達(dá)指定脈沖數(shù)后輸出中斷信號(hào)控制TIM1的輸出通道停止。我們?nèi)藶橐?guī)定TIM4的通道1、2、3、4與TIM1的輸出通道1、2、3、4相對(duì)應(yīng)。

3、代碼實(shí)現(xiàn)

我們已經(jīng)說明了使用主從計(jì)時(shí)器實(shí)現(xiàn)精確輸出脈沖數(shù)的原理,也設(shè)計(jì)了我們的我們想要實(shí)現(xiàn)的系統(tǒng)結(jié)構(gòu),接下來我們實(shí)現(xiàn)這一系統(tǒng)。

3.1、主計(jì)時(shí)器的配置

首先我們來看一看主計(jì)時(shí)器的配置,具體代碼如下:

/*TIM1初始化配置*/ static void TIM1_Init_Configuration(uint32_t period) {TIM_MasterConfigTypeDef sMasterConfig = {0};TIM_OC_InitTypeDef sConfigOC = {0};TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};htim1.Instance = TIM1;htim1.Init.Prescaler = 1;htim1.Init.CounterMode = TIM_COUNTERMODE_UP;htim1.Init.Period = (period-1);htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;htim1.Init.RepetitionCounter = 0;if (HAL_TIM_PWM_Init(&htim1) != HAL_OK){Error_Handler();}sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK){Error_Handler();}sConfigOC.OCMode = TIM_OCMODE_PWM1;sConfigOC.Pulse = (period/2);sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK){Error_Handler();}if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK){Error_Handler();}if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3) != HAL_OK){Error_Handler();}if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_4) != HAL_OK){Error_Handler();}sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;sBreakDeadTimeConfig.DeadTime = 0;sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK){Error_Handler();}HAL_TIM_MspPostInit(&htim1); }

3.2、從計(jì)時(shí)器的配置

接著我們?cè)賮砜匆豢磸挠?jì)時(shí)器的配置,具體代碼如下:

/*TIM4初始化配置*/ static void TIM4_Init_Configuration(void) {TIM_ClockConfigTypeDef sClockSourceConfig = {0};TIM_SlaveConfigTypeDef sSlaveConfig = {0};TIM_MasterConfigTypeDef sMasterConfig = {0};htim4.Instance = TIM4;htim4.Init.Prescaler = 0;htim4.Init.CounterMode = TIM_COUNTERMODE_UP;htim4.Init.Period = 0xFFFF;htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;if (HAL_TIM_Base_Init(&htim4) != HAL_OK){Error_Handler();}sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK){Error_Handler();}sSlaveConfig.SlaveMode = TIM_SLAVEMODE_GATED;sSlaveConfig.InputTrigger = TIM_TS_ITR0;if (HAL_TIM_SlaveConfigSynchronization(&htim4, &sSlaveConfig) != HAL_OK){Error_Handler();}sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK){Error_Handler();} }

3.3、主輪詢函數(shù)實(shí)現(xiàn)

主輪詢函數(shù)控制著主從計(jì)時(shí)器的啟動(dòng),是實(shí)現(xiàn)脈沖輸出的控制者,包括設(shè)置脈沖數(shù)并開啟從計(jì)數(shù)器的計(jì)數(shù)和中斷以及啟動(dòng)主計(jì)時(shí)器的輸出。具體代碼如下:

/*實(shí)現(xiàn)通訊數(shù)據(jù)的處理*/void HgraDataProcess(void) {TIM_SET_CAPTUREPOLARITY(&htim1,TIM_CHANNEL_1,TIM_ICPOLARITY_RISING);? // 捕獲比較1中斷使能TIM_SET_CAPTUREPOLARITY(&htim1,TIM_CHANNEL_2,TIM_ICPOLARITY_RISING);? // 捕獲比較2中斷使能TIM_SET_CAPTUREPOLARITY(&htim1,TIM_CHANNEL_3,TIM_ICPOLARITY_RISING);? // 捕獲比較3中斷使能TIM_SET_CAPTUREPOLARITY(&htim1,TIM_CHANNEL_4,TIM_ICPOLARITY_RISING);? // 捕獲比較4中斷使能__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,6400);??? ?// 輸入通道1的捕獲比較值CCR1__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_2,6400);???? // 輸入通道2的捕獲比較值CCR2__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_3,6400);???? // 輸入通道3的捕獲比較值CCR3__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_4,6400);???? // 輸入通道4的捕獲比較值CCR4HAL_TIM_OC_Start_IT(&htim4,TIM_CHANNEL_1);??? //開啟定時(shí)器4通道1的輸入捕獲中斷HAL_TIM_OC_Start_IT(&htim4,TIM_CHANNEL_2);??? //開啟定時(shí)器4通道2的輸入捕獲中斷HAL_TIM_OC_Start_IT(&htim4,TIM_CHANNEL_3);??? //開啟定時(shí)器4通道3的輸入捕獲中斷HAL_TIM_OC_Start_IT(&htim4,TIM_CHANNEL_4);??? //開啟定時(shí)器4通道4的輸入捕獲中斷HAL_TIM_PWM_Start_IT(&htim1, TIM_CHANNEL_1);? //開啟定時(shí)器1通道1的PWM輸出中斷????????HAL_TIM_PWM_Start_IT(&htim1, TIM_CHANNEL_2);? //開啟定時(shí)器1通道2的PWM輸出中斷HAL_TIM_PWM_Start_IT(&htim1, TIM_CHANNEL_3);? //開啟定時(shí)器1通道3的PWM輸出中斷HAL_TIM_PWM_Start_IT(&htim1, TIM_CHANNEL_4);? //開啟定時(shí)器1通道4的PWM輸出中斷 }

3.4、中斷處理函數(shù)的實(shí)現(xiàn)

從計(jì)時(shí)器產(chǎn)生中斷后,會(huì)根據(jù)不同的中斷調(diào)用不同的中斷處理函數(shù),這些回調(diào)函數(shù)是需要我們實(shí)現(xiàn)的,在這里要實(shí)現(xiàn)主計(jì)時(shí)器PWM輸出的停止以及中斷標(biāo)志的復(fù)位等處理。具體實(shí)現(xiàn)代碼如下:

/*PWM中斷輪詢回調(diào)函數(shù)*/ static void TIM1_PWM_PulseFinished(TIM_HandleTypeDef *htim) {if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1) != RESET)???????????????????????? //判斷是否生成中斷標(biāo)志位SR{if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC1) !=RESET)????????????? //定時(shí)器中斷使能是否開啟{__HAL_TIM_CLEAR_FLAG(&htim4, TIM_FLAG_CC1);????????????????? ?//清除中斷標(biāo)志位SRif(HAL_TIM_PWM_Stop_IT(&htim1, TIM_CHANNEL_1)==HAL_OK)???????? //關(guān)閉定時(shí)器1的通道1的PWM輸出{HAL_TIM_OC_Stop_IT(&htim4,TIM_CHANNEL_1) ;?????????????????? //關(guān)閉定時(shí)器4的通道1的輸入中斷捕獲flagStop[0] = 1;????????????????????????????????? ??????????????//關(guān)閉標(biāo)志置1}}}????????????????????????????????????????????????????????????????????????? //下面的通道2同理如此if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2) != RESET){if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC2) !=RESET){__HAL_TIM_CLEAR_FLAG(&htim4, TIM_FLAG_CC2);?????????????????????? //清除標(biāo)志位if(HAL_TIM_PWM_Stop_IT(&htim1, TIM_CHANNEL_2)==HAL_OK){????aHAL_TIM_OC_Stop_IT(&htim4,TIM_CHANNEL_2) ;???flagStop[1] = 1;???????????}}}if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC3) != RESET){if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC3) !=RESET){__HAL_TIM_CLEAR_FLAG(&htim4, TIM_FLAG_CC3);?????????????????????? //清除標(biāo)志位if(HAL_TIM_PWM_Stop_IT(&htim1, TIM_CHANNEL_3)==HAL_OK){????HAL_TIM_OC_Stop_IT(&htim4,TIM_CHANNEL_3) ;???flagStop[2] = 1;???????????}}}if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC4) != RESET){if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC4) !=RESET){__HAL_TIM_CLEAR_FLAG(&htim4, TIM_FLAG_CC4);?????????????????????? //清除標(biāo)志位if(HAL_TIM_PWM_Stop_IT(&htim1, TIM_CHANNEL_4)==HAL_OK){????HAL_TIM_OC_Stop_IT(&htim4,TIM_CHANNEL_4) ;???flagStop[3] = 1; ???????????}}}if((flagStop[0]== 1)&&(flagStop[1] == 1)&&(flagStop[2] == 1)&&(flagStop[3] == 1)){flagStop[0]= 0;flagStop[1]= 0;flagStop[2]= 0;flagStop[3]= 0;__HAL_TIM_SET_COUNTER(&htim4,0);} }

4、小結(jié)

我們?cè)O(shè)計(jì)了一個(gè)四路輸出的脈沖輸出,每一路的輸出數(shù)量可以精確單獨(dú)控制,在輸出的頻率相對(duì)較低而且數(shù)量不大的情況下我們驗(yàn)證是沒有問題的。當(dāng)然在數(shù)量特別多時(shí),是否有偏差我們沒有測(cè)試。而在我們使用的平臺(tái),時(shí)鐘為168MHz,根據(jù)我們的簡(jiǎn)單測(cè)試在輸出8MHz的脈沖時(shí)還是比較精確的,不過這已經(jīng)完全滿足一般的應(yīng)用需求。

其實(shí)從STM32的手冊(cè)我可以知道,輸出指定脈沖數(shù)的方法有多種,但使用主從計(jì)時(shí)器方式是比較好的一種。這種方式雖然多用了一個(gè)定時(shí)器,但因?yàn)椴恍枰l繁中斷大大減少了CPU的處理資源。

歡迎關(guān)注:

總結(jié)

以上是生活随笔為你收集整理的STM32学习及开发笔记八:采用主从计时器实现精确脉冲输出的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。