0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

STM32基礎(chǔ)知識(shí):定時(shí)器的定時(shí)計(jì)數(shù)功能

CHANBAEK ? 來(lái)源:上下求索電子er ? 作者:上下求索電子er ? 2023-10-24 15:26 ? 次閱讀

定時(shí)器定時(shí)計(jì)數(shù)功能

1 定時(shí)器概述

  • 定時(shí)器是對(duì)周期固定的脈沖信號(hào)進(jìn)行計(jì)數(shù),如MCU內(nèi)部的外設(shè)時(shí)鐘(APB)。
  • 計(jì)數(shù)器是對(duì)周期不確定的脈沖信號(hào)進(jìn)行計(jì)數(shù),如MCU的I/O引腳所引入的外部脈沖信號(hào)。
  • 定時(shí)器和計(jì)數(shù)器本質(zhì)上都是計(jì)數(shù)器,定時(shí)器是計(jì)數(shù)器的一種特例。

2 STM32定時(shí)器分類

圖片

對(duì)于STM32F103共存在6個(gè)外設(shè)定時(shí)器:高級(jí)定時(shí)器TIM1,通用定時(shí)器TIM2、TIM3、TIM4。

2.1 內(nèi)核定時(shí)器

  • 系統(tǒng)節(jié)拍定時(shí)器:Systick定時(shí)器是屬于內(nèi)核中的一個(gè)外設(shè),內(nèi)嵌在NVIC中。

2.2 外設(shè)定時(shí)器

  • 常規(guī)定時(shí)器> STM32F103xx增強(qiáng)型產(chǎn)品中,內(nèi)置了多達(dá)3個(gè)可同步運(yùn)行的標(biāo)準(zhǔn)定時(shí)器(TIM2、TIM3和TIM4)。每個(gè)定時(shí)器都有一個(gè)16位的自動(dòng)加載遞加/遞減計(jì)數(shù)器、一個(gè)16位的預(yù)分頻器和4個(gè)獨(dú)立的通道,每個(gè)通道都可用于輸入捕獲、輸出比較、PWM和單脈沖模式輸出.
    • 高級(jí)定時(shí)器:除具備通用定時(shí)器的功能外,還具備帶死區(qū)控制的互補(bǔ)信號(hào)輸出、緊急剎車關(guān)斷輸入等功能,可用于電機(jī)控制數(shù)字電源設(shè)計(jì)。
    • 基本定時(shí)器:幾乎沒(méi)有任何輸入/輸出通道,常用作時(shí)基,實(shí)現(xiàn)基本的定時(shí)/計(jì)數(shù)功能。
    • 通用定時(shí)器:具備多路獨(dú)立的捕獲和比較通道,可以完成定時(shí)/計(jì)數(shù)、輸入捕獲、輸出比較等功能。
  • 專用定時(shí)器

3 定時(shí)器的時(shí)鐘頻率

圖片

4 定時(shí)器的主要功能

4.1 定時(shí)計(jì)數(shù)

  • 計(jì)數(shù)內(nèi)部時(shí)鐘,即定時(shí)器模式
  • 計(jì)數(shù)外部脈沖,即計(jì)數(shù)器模式

4.2 輸出比較

  • PWM輸出
  • 電平翻轉(zhuǎn)
  • 單脈沖輸出
  • 強(qiáng)制輸出

4.3 輸入捕獲

  • 捕獲時(shí)保存定時(shí)器的當(dāng)前計(jì)數(shù)值
  • 捕獲時(shí),可選擇觸發(fā)捕獲中斷
  • 觸發(fā)捕獲的信號(hào)邊沿類型可選擇(上升沿,下降沿,雙邊沿)

5 HAL庫(kù)的定時(shí)器設(shè)計(jì)

5.1 定時(shí)器句柄結(jié)構(gòu)的組成

圖片

5.2 三種外設(shè)編程模型

  • 以后綴區(qū)分編程模型
  • 入口參數(shù)均為外設(shè)句柄的指針
方式函數(shù)
輪詢方式HAL_TIM_Base_Start(TIM_HandleTypeDef *htim );HAL_TIM_Base_Stop TIM_HandleTypeDef *htim );
中斷方式HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim);HAL_TIM_Base_Stop_IT(TIM_HandleTypeDef *htim);
DMA方式HAL_TIM_Base_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length);

6 定時(shí)器的定時(shí)/計(jì)數(shù)功能

6.1 時(shí)基單元

圖片圖片

①預(yù)分頻模塊

  • 預(yù)分頻計(jì)數(shù)器:對(duì)預(yù)分頻時(shí)鐘CK_PSC進(jìn)行分頻
  • 預(yù)分頻寄存器:TIMx_PSC:設(shè)置預(yù)分頻系數(shù)PSC
  • 作用1:擴(kuò)大定時(shí)器的定時(shí)范圍
  • 作用2:獲取精確的計(jì)數(shù)時(shí)鐘

預(yù)分頻模塊工作原理 定時(shí)器啟動(dòng)后,預(yù)分頻計(jì)數(shù)器的初值為0,預(yù)分頻時(shí)鐘CK_PSC每來(lái)一個(gè)時(shí)鐘,預(yù)分頻計(jì)數(shù)器的值就加1。當(dāng)計(jì)數(shù)值等于預(yù)分頻寄存器所設(shè)定的預(yù)分頻系數(shù)PSC時(shí),預(yù)分頻計(jì)數(shù)器的值將清零,開(kāi)始下一輪計(jì)數(shù)。

預(yù)分頻時(shí)序圖:圖片

假設(shè)預(yù)分頻系數(shù)PSC=3,預(yù)分頻計(jì)數(shù)器從0計(jì)數(shù)到PSC實(shí)際計(jì)數(shù)值為PSC+1,也就是進(jìn)行了四分頻。
image.png

②計(jì)數(shù)模塊

  • 核心計(jì)數(shù)器:對(duì)計(jì)數(shù)時(shí)鐘CK_CNT進(jìn)行二次計(jì)數(shù)
  • 計(jì)數(shù)器寄存器:TIMx_CNT:存放核心計(jì)數(shù)器運(yùn)行時(shí)的當(dāng)前計(jì)數(shù)值

③自動(dòng)重載模塊

  • 自動(dòng)重載模塊由自動(dòng)重載寄存器TIMx_ARR組成
    • 遞增計(jì)數(shù)模式:TIMx_ARR的值作為核心計(jì)數(shù)器的計(jì)數(shù)終值
    • 遞減計(jì)數(shù)模式:TIMx_ARR的值作為核心計(jì)數(shù)器的計(jì)數(shù)初值

④計(jì)數(shù)模式

圖片

計(jì)數(shù)模式計(jì)數(shù)器溢出值計(jì)數(shù)器重載值
遞增計(jì)數(shù)CNT=ARRCNT=0
遞減計(jì)數(shù)CNT=0CNT=ARR
中心對(duì)齊計(jì)數(shù)CNT=ARR-1CNT=1CNT=ARRCNT=0

6.2 定時(shí)器時(shí)序圖

圖片

①定時(shí)時(shí)間公式

②相關(guān)寄存器

  • 預(yù)分頻寄存器TIMx_PSC: 設(shè)置預(yù)分頻系數(shù),將預(yù)分頻時(shí)鐘(CK_PSC)進(jìn)行1~65536之間的任意值分頻,得到計(jì)數(shù)時(shí)鐘(CK_CNT)。
  • 計(jì)數(shù)器寄存器TIMx_CNT : 存放核心計(jì)數(shù)器運(yùn)行時(shí)的當(dāng)前計(jì)數(shù)值,便于用戶實(shí)時(shí)掌握核心計(jì)數(shù)器的當(dāng)前計(jì)數(shù)值。芯片復(fù)位后,默認(rèn)值為0。
  • 自動(dòng)重載寄存器TIMx_ARR: 為計(jì)數(shù)器設(shè)置計(jì)數(shù)邊界或重載值。比如計(jì)數(shù)器遞增計(jì)數(shù)時(shí),記到多少發(fā)生溢出;遞減計(jì)數(shù)時(shí),從多少開(kāi)始往下計(jì)數(shù)。

6.3 外部脈沖計(jì)數(shù)

圖片

6.4 數(shù)據(jù)類型和接口函數(shù)

圖片

成員變量:

成員變量ClockDivision的取值范圍:

TIM_CLOCKDIVISION_DIV1對(duì)定時(shí)器時(shí)鐘TIM_CLK進(jìn)行1分頻
TIM_CLOCKDIVISION_DIV2對(duì)定時(shí)器時(shí)鐘TIM_CLK進(jìn)行2分頻
TIM_CLOCKDIVISION_DIV4對(duì)定時(shí)器時(shí)鐘TIM_CLK進(jìn)行4分頻

成員變量CounterMode的取值范圍

TIM_COUNTERMODE_UP遞增計(jì)數(shù)模式
TIM_COUNTERMODE_DOWN遞減計(jì)數(shù)模式
TIM_COUNTERMODE_CENTERALIGNED1中心對(duì)齊計(jì)數(shù)模式1
TIM_COUNTERMODE_CENTERALIGNED2中心對(duì)齊計(jì)數(shù)模式2
TIM_COUNTERMODE_CENTERALIGNED3中心對(duì)齊計(jì)數(shù)模式3

成員變量AutoReloadPreload的取值范圍

TIM_AUTORELOAD_PRELOAD_DISABLE預(yù)裝載功能關(guān)閉
TIM_AUTORELOAD_PRELOAD_ENABLE預(yù)裝載功能開(kāi)啟
  1. 用于設(shè)置自動(dòng)重載寄存器TIMx_ARR的預(yù)裝載功能,即自動(dòng)重裝寄存器的內(nèi)容是更新事件產(chǎn)生時(shí)寫(xiě)入有效,還是立即寫(xiě)入有效;
  2. 預(yù)裝載功能在多個(gè)定時(shí)器同時(shí)輸出信號(hào)時(shí)比較有用,可以確保多個(gè)定時(shí)器的輸出信號(hào)在同一個(gè)時(shí)刻變化,實(shí)現(xiàn)同步輸出;
  3. 單個(gè)定時(shí)器輸出時(shí),一般不開(kāi)啟預(yù)裝載功能。

接口函數(shù):

  1. 時(shí)基單元初始化函數(shù):HAL_TIM_Base_Init

    函數(shù)原型HAL_StatusTypeDef HAL_TIM_Base_Init(TIM_HandleTypeDef *htim)
    功能描述按照定時(shí)器句柄中指定的參數(shù)初始化定時(shí)器時(shí)基單元
    入口參數(shù)htim:定時(shí)器句柄的地址
    返回值HAL狀態(tài)值
    注意事項(xiàng)1. 該函數(shù)將調(diào)用MCU底層初始化函數(shù)HAL_TIM_Base_MspInit完成引腳、時(shí)鐘和中斷的設(shè)置2. 該函數(shù)由CubeMX自動(dòng)生成
  2. 輪詢模式啟動(dòng)函數(shù):HAL_TIM_Base_Start

    函數(shù)原型HAL_StatusTypeDef HAL_TIM_Base_Start(TIM_HandleTypeDef *htim)
    功能描述在輪詢方式下啟動(dòng)定時(shí)器運(yùn)行
    入口參數(shù)htim:定時(shí)器句柄的地址
    返回值HAL狀態(tài)值
    注意事項(xiàng)1. 該函數(shù)在定時(shí)器初始化完成之后調(diào)用2. 函數(shù)需要由用戶調(diào)用,用于輪詢方式下啟動(dòng)定時(shí)器運(yùn)行
  3. 中斷模式啟動(dòng)函數(shù):HAL_TIM_Base_Start_IT

    函數(shù)原型HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim)
    功能描述使能定時(shí)器的更新中斷,并啟動(dòng)定時(shí)器運(yùn)行
    入口參數(shù)htim:定時(shí)器句柄的地址
    返回值HAL狀態(tài)值
    注意事項(xiàng)1. 該函數(shù)在定時(shí)器初始化完成之后調(diào)用2. 函數(shù)需要由用戶調(diào)用,用于使能定時(shí)器的更新中斷,并啟動(dòng)定時(shí)器運(yùn)行3. 啟動(dòng)前需要調(diào)用宏函數(shù) __HAL_TIM_CLEAR_IT 來(lái)清除更新中斷標(biāo)志
  4. 定時(shí)器中斷通用處理函數(shù)HAL_TIM_IRQHandler

    函數(shù)原型void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)
    功能描述作為所有定時(shí)器中斷發(fā)生后的通用處理函數(shù)
    入口參數(shù)htim:定時(shí)器句柄的地址
    返回值無(wú)
    注意事項(xiàng)1. 函數(shù)內(nèi)部先判斷中斷類型,并清除對(duì)應(yīng)的中斷標(biāo)志,最后調(diào)用回調(diào)函數(shù)完成中斷處理2. 該函數(shù)由CubeMX自動(dòng)生成
  5. 定時(shí)器更新中斷回調(diào)函數(shù)HAL_TIM_PeriodElapsedCallback

    函數(shù)原型void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    功能描述回調(diào)函數(shù),用于處理所有定時(shí)器的更新中斷,用戶在該函數(shù)內(nèi)編寫(xiě)實(shí)際的任務(wù)處理程序
    入口參數(shù)htim:定時(shí)器句柄的地址
    返回值無(wú)
    注意事項(xiàng)1.該函數(shù)由定時(shí)器中斷通用處理函數(shù)HAL_TIM_IRQHandler調(diào)用,完成所有定時(shí)器的更新中斷的任務(wù)處理2.函數(shù)內(nèi)部需要根據(jù)定時(shí)器句柄的實(shí)例來(lái)判斷是哪一個(gè)定時(shí)器產(chǎn)生的本次更新中斷3.函數(shù)由用戶根據(jù)具體的處理任務(wù)編寫(xiě)
  6. 計(jì)數(shù)值讀取函數(shù)__HAL_TIM_GET_COUNTER

    #define __HAL_TIM_GET_COUNTER(__HANDLE__) ((__HANDLE__)- >Instance- >CNT)
    

    __HANDLE__:定時(shí)器句柄的地址

    該函數(shù)通過(guò)直接訪問(wèn)計(jì)數(shù)器寄存器TIMx_CNT來(lái)獲取計(jì)數(shù)器的當(dāng)前計(jì)數(shù)值。

  7. 定時(shí)器中斷標(biāo)志清除函數(shù)__HAL_TIM_CLEAR_IT

    #define __HAL_TIM_CLEAR_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)- >Instance- >SR = ~(__INTERRUPT__))
    

    __HANDLE__:定時(shí)器句柄的地址

    __INTERRUPT__:定時(shí)器中斷標(biāo)志

    圖片

任務(wù)實(shí)踐1

基于STM32F103C8T6,開(kāi)發(fā)板原理圖

圖片

利用開(kāi)發(fā)板上的按鍵KEY2來(lái)觸發(fā)外部脈沖,按鍵每按下一次,就利用PA1引腳發(fā)送一個(gè)周期2ms左右的脈沖,送到定時(shí)器2的外部觸發(fā)引腳ETR(PA0)進(jìn)行計(jì)數(shù),并將計(jì)數(shù)結(jié)果通過(guò)串口發(fā)送到PC上顯示。

注:本任務(wù)例程使用的開(kāi)發(fā)板,KEY2與PA5相連接。KEY2原理圖如下:

圖片

使用按鍵時(shí),需要設(shè)置PA5為輸入上拉模式,這樣在KEY2沒(méi)有按下時(shí),PA5可以讀取到高電平,KEY2按下時(shí)PA5可以讀取到低電平。

  1. 配置PA1為GPIO_Output(User Label:PULSE),PA5為GPIO_Input(User Label:KEY2),上拉模式。
    圖片
    圖片
    上述操作在stm32f1xx_hal_gpio.c中生成GPIO引腳初始化函數(shù)MX_GPIO_Init,并在main.c中調(diào)用

    void MX_GPIO_Init(void)
    {
    
      GPIO_InitTypeDef GPIO_InitStruct = {0};
    
      /* GPIO Ports Clock Enable */
      __HAL_RCC_GPIOA_CLK_ENABLE();
      __HAL_RCC_GPIOB_CLK_ENABLE();
    
      /*Configure GPIO pin Output Level */
      HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
    
      /*Configure GPIO pin : PA1 */
      GPIO_InitStruct.Pin = GPIO_PIN_1;
      GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
      GPIO_InitStruct.Pull = GPIO_NOPULL;
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
      HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
      /*Configure GPIO pin : PA5 */
      GPIO_InitStruct.Pin = GPIO_PIN_5;
      GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
      GPIO_InitStruct.Pull = GPIO_PULLUP;
      HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    }
    
  2. 配置定時(shí)器2時(shí)鐘源為外部觸發(fā)引腳ETR2,自動(dòng)重載寄存器ARR配置為一個(gè)相對(duì)較大的計(jì)數(shù),防止溢出。外部脈沖信號(hào)采用默認(rèn)配置:不使用濾波,不進(jìn)行脈沖信號(hào)反相,不進(jìn)行脈沖信號(hào)分頻。
    圖片
    圖片
    上述操作在tim.c生成引腳初始化函數(shù):

    void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
    {
    
      GPIO_InitTypeDef GPIO_InitStruct = {0};
      if(tim_baseHandle- >Instance==TIM2)
      {
      /* USER CODE BEGIN TIM2_MspInit 0 */
    
      /* USER CODE END TIM2_MspInit 0 */
        /* TIM2 clock enable */
        __HAL_RCC_TIM2_CLK_ENABLE();
    
        __HAL_RCC_GPIOA_CLK_ENABLE();
        /**TIM2 GPIO Configuration
        PA0-WKUP     ------ > TIM2_ETR
        */
        GPIO_InitStruct.Pin = GPIO_PIN_0;
        GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
      /* USER CODE BEGIN TIM2_MspInit 1 */
    
      /* USER CODE END TIM2_MspInit 1 */
      }
    }
    
    void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
    {
    
      if(tim_baseHandle- >Instance==TIM2)
      {
      /* USER CODE BEGIN TIM2_MspDeInit 0 */
    
      /* USER CODE END TIM2_MspDeInit 0 */
        /* Peripheral clock disable */
        __HAL_RCC_TIM2_CLK_DISABLE();
    
        /**TIM2 GPIO Configuration
        PA0-WKUP     ------ > TIM2_ETR
        */
        HAL_GPIO_DeInit(GPIOA, GPIO_PIN_0);
    
      /* USER CODE BEGIN TIM2_MspDeInit 1 */
    
      /* USER CODE END TIM2_MspDeInit 1 */
      }
    }
    

    上述操作在tim.c生成如下代碼完成初始化定時(shí)器,并在main.c中調(diào)用

    /* TIM2 init function */
    void MX_TIM2_Init(void)
    {
    
      /* USER CODE BEGIN TIM2_Init 0 */
    
      /* USER CODE END TIM2_Init 0 */
    
      TIM_ClockConfigTypeDef sClockSourceConfig = {0};
      TIM_MasterConfigTypeDef sMasterConfig = {0};
    
      /* USER CODE BEGIN TIM2_Init 1 */
    
      /* USER CODE END TIM2_Init 1 */
      htim2.Instance = TIM2;
      htim2.Init.Prescaler = 0;
      htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
      htim2.Init.Period = 65535;
      htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
      htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
      if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
      {
        Error_Handler();
      }
      sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_ETRMODE2;
      sClockSourceConfig.ClockPolarity = TIM_CLOCKPOLARITY_NONINVERTED;
      sClockSourceConfig.ClockPrescaler = TIM_CLOCKPRESCALER_DIV1;
      sClockSourceConfig.ClockFilter = 0;
      if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
      {
        Error_Handler();
      }
      sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
      sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
      if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
      {
        Error_Handler();
      }
      /* USER CODE BEGIN TIM2_Init 2 */
    
      /* USER CODE END TIM2_Init 2 */
    
    }
    

    其中調(diào)用的HAL_TIM_Base_Init函數(shù)將調(diào)用HAL_TIM_Base_MspInit完成引腳初始化。

  3. 配置串口外設(shè)USART1,選擇異步模式,無(wú)硬件流控。
    圖片
    上述操作在usart.c中生成串口配置相關(guān)函數(shù),并在main.c中調(diào)用。usart的封裝邏輯與tim相同,不再贅述。

    void MX_USART1_UART_Init(void)
    {
    
      /* USER CODE BEGIN USART1_Init 0 */
    
      /* USER CODE END USART1_Init 0 */
    
      /* USER CODE BEGIN USART1_Init 1 */
    
      /* USER CODE END USART1_Init 1 */
      huart1.Instance = USART1;
      huart1.Init.BaudRate = 115200;
      huart1.Init.WordLength = UART_WORDLENGTH_8B;
      huart1.Init.StopBits = UART_STOPBITS_1;
      huart1.Init.Parity = UART_PARITY_NONE;
      huart1.Init.Mode = UART_MODE_TX_RX;
      huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
      huart1.Init.OverSampling = UART_OVERSAMPLING_16;
      if (HAL_UART_Init(&huart1) != HAL_OK)
      {
        Error_Handler();
      }
      /* USER CODE BEGIN USART1_Init 2 */
    
      /* USER CODE END USART1_Init 2 */
    
    }
    
    void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
    {
    
      GPIO_InitTypeDef GPIO_InitStruct = {0};
      if(uartHandle- >Instance==USART1)
      {
      /* USER CODE BEGIN USART1_MspInit 0 */
    
      /* USER CODE END USART1_MspInit 0 */
        /* USART1 clock enable */
        __HAL_RCC_USART1_CLK_ENABLE();
    
        __HAL_RCC_GPIOA_CLK_ENABLE();
        /**USART1 GPIO Configuration
        PA9     ------ > USART1_TX
        PA10     ------ > USART1_RX
        */
        GPIO_InitStruct.Pin = GPIO_PIN_9;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
        GPIO_InitStruct.Pin = GPIO_PIN_10;
        GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
      /* USER CODE BEGIN USART1_MspInit 1 */
    
      /* USER CODE END USART1_MspInit 1 */
      }
    }
    
    void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
    {
    
      if(uartHandle- >Instance==USART1)
      {
      /* USER CODE BEGIN USART1_MspDeInit 0 */
    
      /* USER CODE END USART1_MspDeInit 0 */
        /* Peripheral clock disable */
        __HAL_RCC_USART1_CLK_DISABLE();
    
        /**USART1 GPIO Configuration
        PA9     ------ > USART1_TX
        PA10     ------ > USART1_RX
        */
        HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
    
      /* USER CODE BEGIN USART1_MspDeInit 1 */
    
      /* USER CODE END USART1_MspDeInit 1 */
      }
    }
    
  4. 程序編寫(xiě)
    使用串口輸出,需要在Keil的Options中勾選Use MicroLIB.
    圖片
    在main.c中重定義printfscanf函數(shù)

    /* USER CODE BEGIN Includes */
    #include < stdio.h >
    /* USER CODE END Includes */
    
    /* USER CODE BEGIN 4 */
    int fputc (int ch, FILE *f)
    {
        HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
        return ch;
    }
    int fgetc(FILE *f)
    {
        uint8_t ch = 0;
        HAL_UART_Receive(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
        return ch;
    }
    /* USER CODE END 4 */
    

    用戶變量定義代碼

    /* USER CODE BEGIN PV */
    uint8_t Result = 0;
    /* USER CODE END PV */
    

    用戶變量初始化代碼

    /* USER CODE BEGIN 2 */
      HAL_TIM_Base_Start_IT(&htim2);
      printf("Timer count function test: n");
      /* USER CODE END 2 */
    

    用戶應(yīng)用代碼

    /* USER CODE BEGIN 3 */
        if (HAL_GPIO_ReadPin(GPIOA, KEY2_Pin) == GPIO_PIN_RESET)
        {
          HAL_Delay(10);
          if (HAL_GPIO_ReadPin(GPIOA, KEY2_Pin) == GPIO_PIN_RESET)
          {
            HAL_GPIO_WritePin(GPIOA, PULSE_Pin, GPIO_PIN_SET);
            HAL_Delay(1);
            HAL_GPIO_WritePin(GPIOA, PULSE_Pin, GPIO_PIN_RESET);
            HAL_Delay(1);
            Result = __HAL_TIM_GET_COUNTER(&htim2);
            printf("Count = %d", Result);
          }
          while (HAL_GPIO_ReadPin(GPIOA, KEY2_Pin) == GPIO_PIN_RESET);
        }
      }
      /* USER CODE END 3 */
    

    實(shí)驗(yàn)現(xiàn)象

    圖片

任務(wù)實(shí)踐2

設(shè)計(jì)電子時(shí)鐘,從00:00:00開(kāi)始計(jì)時(shí),并將計(jì)時(shí)信息通過(guò)串口UART1發(fā)送到PC進(jìn)行顯示。

  1. 配置定時(shí)器1產(chǎn)生1s的更新中斷。計(jì)算PSC和ARR的值,將T=1s,TIM_CLK=8000000Hz帶入公式
    得可取值PSC=1999,ARR=3999.
    在CubeMX中使能TIM1,采用內(nèi)部時(shí)鐘 (8MHz) ,設(shè)置PSC和ARR值,并在嵌套向量中斷控制器NVIC設(shè)置中使能TIM1的更新中斷。
    圖片
    圖片
    上述操作在tim.c中生成TIM1初始化函數(shù),并在main.c中調(diào)用

  2. 配置USART1串口輸出,生成代碼后應(yīng)在工程中重定向printfscanf函數(shù),方法同任務(wù)實(shí)踐1,這部分不再贅述。

  3. 編寫(xiě)代碼
    main.c中進(jìn)行用戶數(shù)據(jù)類型定義

    /* USER CODE BEGIN PTD */
    typedef struct
    {
      uint8_t hour;
      uint8_t minutes;
      uint8_t second;
    }CLOCK_Typedef;
    /* USER CODE END PTD */
    

    用戶變量定義

    /* USER CODE BEGIN PV */
    CLOCK_Typedef clock = {0};
    /* USER CODE END PV */
    

    用戶初始化代碼

    /* USER CODE BEGIN 2 */
     // 清除更新中斷標(biāo)志,避免定時(shí)器一啟動(dòng)就進(jìn)入中斷
      __HAL_TIM_CLEAR_IT(&htim1, TIM_IT_UPDATE);
      HAL_TIM_Base_Start_IT(&htim1);
      /* USER CODE END 2 */
    

    用戶應(yīng)用代碼

    /* USER CODE BEGIN 3 */
        printf("Time:%02d:%02d:%02d.rn", clock.hour, clock.minutes, clock.second);
        HAL_Delay(1000);
      }
      /* USER CODE END 3 */
    

    編寫(xiě)定時(shí)器更新中斷回調(diào)函數(shù)

    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    {
      if (htim- >Instance == TIM1)  // 判斷時(shí)鐘源
      {
        clock.second++;
        if (clock.second == 60)
        {
          clock.second = 0;
          clock.minutes++;
          if (clock.minutes == 60)
          {
            clock.minutes = 0;
            clock.hour++;
            if (clock.hour == 24)
            {
              clock.hour = 0;
            }
          }
        }
      }
    }
    
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • mcu
    mcu
    +關(guān)注

    關(guān)注

    146

    文章

    17149

    瀏覽量

    351213
  • STM32
    +關(guān)注

    關(guān)注

    2270

    文章

    10900

    瀏覽量

    356046
  • 計(jì)數(shù)器
    +關(guān)注

    關(guān)注

    32

    文章

    2256

    瀏覽量

    94575
  • 定時(shí)器
    +關(guān)注

    關(guān)注

    23

    文章

    3248

    瀏覽量

    114818
  • 脈沖信號(hào)
    +關(guān)注

    關(guān)注

    6

    文章

    399

    瀏覽量

    36973
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    電機(jī)控制基礎(chǔ)知識(shí)1—定時(shí)器基礎(chǔ)知識(shí)與PWM輸出原理

    轉(zhuǎn)速等。 本篇先介紹 定時(shí)器基礎(chǔ)知識(shí) ,然后對(duì)照這些知識(shí)介紹一下 定時(shí)器輸出PWM的基本原理 ,以及 編程實(shí)現(xiàn)與代碼分析 。 首先來(lái)看一下定時(shí)器
    的頭像 發(fā)表于 06-17 00:11 ?1.2w次閱讀
    電機(jī)控制<b class='flag-5'>基礎(chǔ)知識(shí)</b>1—<b class='flag-5'>定時(shí)器</b><b class='flag-5'>基礎(chǔ)知識(shí)</b>與PWM輸出原理

    定時(shí)器基礎(chǔ)知識(shí)

    目錄:一、定時(shí)器基礎(chǔ)知識(shí)二、基本定時(shí)器(TIM6和TIM7)三、通用定時(shí)器(TIM2~TIM6)1.功能特點(diǎn)2.時(shí)鐘源3.時(shí)基單元4.輸入捕
    發(fā)表于 08-09 07:30

    STM32使用定時(shí)器計(jì)數(shù)

    32完全可以克服這一困難STM32F103系列可使用的定時(shí)器8個(gè),其中通用定時(shí)器有TMI1-TIM7高級(jí)定時(shí)器TIM0 TIM8而在這 我主要使用通用
    發(fā)表于 08-18 07:23

    定時(shí)器基礎(chǔ)知識(shí)與PWM輸出原理是什么

    轉(zhuǎn)速等。本篇先介紹定時(shí)器基礎(chǔ)知識(shí),然后對(duì)照這些知識(shí)介紹一下定時(shí)器輸出PWM的基本原理,以及編程實(shí)現(xiàn)與代碼分析。首先來(lái)看一下定時(shí)器的基礎(chǔ)介紹
    發(fā)表于 01-25 08:16

    定時(shí)計(jì)數(shù)技術(shù)

    單片機(jī)控制系統(tǒng)中常常用到的定時(shí)計(jì)數(shù)問(wèn)題。5.1  定時(shí)計(jì)數(shù)概述1、定時(shí)的定義:      
    發(fā)表于 12-17 14:39 ?24次下載

    ASF設(shè)計(jì):定時(shí)計(jì)數(shù)器的中斷是如何使用的?

    ASF設(shè)計(jì)2:定時(shí)計(jì)數(shù)器的中斷使用
    的頭像 發(fā)表于 07-10 01:05 ?4045次閱讀

    STM32定時(shí)器基本計(jì)數(shù)原理解析

    STM32的TIM定時(shí)器分為三類:基本定時(shí)器、通用定時(shí)器和高級(jí)定時(shí)器。從分類來(lái)看就知道STM32
    發(fā)表于 12-27 16:20 ?1.8w次閱讀
    <b class='flag-5'>STM32</b><b class='flag-5'>定時(shí)器</b>基本<b class='flag-5'>計(jì)數(shù)</b>原理解析

    定時(shí)器計(jì)數(shù)器基礎(chǔ)知識(shí)和使用方法及C程序?qū)崿F(xiàn)1s鐘定時(shí)的程序

    本文檔的主要內(nèi)容詳細(xì)介紹的是定時(shí)器計(jì)數(shù)器基礎(chǔ)知識(shí)和使用方法及C程序?qū)崿F(xiàn)1s鐘定時(shí)的程序。
    發(fā)表于 04-18 17:27 ?6次下載
    <b class='flag-5'>定時(shí)器</b>與<b class='flag-5'>計(jì)數(shù)器</b>的<b class='flag-5'>基礎(chǔ)知識(shí)</b>和使用方法及C程序?qū)崿F(xiàn)1s鐘<b class='flag-5'>定時(shí)</b>的程序

    淺談定時(shí)器基礎(chǔ)知識(shí)與PWM輸出原理

    轉(zhuǎn)速等。 本篇先介紹定時(shí)器基礎(chǔ)知識(shí),然后對(duì)照這些知識(shí)介紹一下定時(shí)器輸出PWM的基本原理,以及編程實(shí)現(xiàn)與代碼分析。 首先來(lái)看一下定時(shí)器的基礎(chǔ)
    的頭像 發(fā)表于 04-05 10:35 ?1.4w次閱讀
    淺談<b class='flag-5'>定時(shí)器</b><b class='flag-5'>基礎(chǔ)知識(shí)</b>與PWM輸出原理

    STM32定時(shí)器-基本定時(shí)器

    目錄定時(shí)器分類基本定時(shí)器功能框圖講解基本定時(shí)器功能時(shí)鐘源計(jì)數(shù)器時(shí)鐘
    發(fā)表于 11-23 18:21 ?31次下載
    <b class='flag-5'>STM32</b><b class='flag-5'>定時(shí)器</b>-基本<b class='flag-5'>定時(shí)器</b>

    電機(jī)控制基礎(chǔ)——定時(shí)器基礎(chǔ)知識(shí)與PWM輸出原理

    轉(zhuǎn)速等。本篇先介紹定時(shí)器基礎(chǔ)知識(shí),然后對(duì)照這些知識(shí)介紹一下定時(shí)器輸出PWM的基本原理,以及編程實(shí)現(xiàn)與代碼分析。首先來(lái)看一下定時(shí)器的基礎(chǔ)介紹
    發(fā)表于 11-30 14:21 ?38次下載
    電機(jī)控制基礎(chǔ)——<b class='flag-5'>定時(shí)器</b><b class='flag-5'>基礎(chǔ)知識(shí)</b>與PWM輸出原理

    STM32---定時(shí)器知多少

    14,15,16章節(jié),里面對(duì)定時(shí)器知識(shí)有詳細(xì)的介紹。STM32F1系列的開(kāi)發(fā)板一共有8個(gè)定時(shí)器,按照功能的不同可以分為:高級(jí)
    發(fā)表于 11-30 14:36 ?19次下載
    <b class='flag-5'>STM32</b>---<b class='flag-5'>定時(shí)器</b>知多少

    stm32中斷源有哪些_【話說(shuō)定時(shí)器系列】之八:STM32定時(shí)器計(jì)數(shù)定時(shí)基本功能實(shí)驗(yàn)...

    TIMER 的基本應(yīng)用原理、常規(guī)應(yīng)用等?,F(xiàn)在將課程內(nèi)容整理為文章,針對(duì)STM32定時(shí)器有基本了解的用戶,分享具體的應(yīng)用實(shí)現(xiàn)環(huán)節(jié)及常見(jiàn)問(wèn)題解決。實(shí)驗(yàn)內(nèi)容:使用STM32定時(shí)器的基本
    發(fā)表于 12-05 13:21 ?0次下載
    <b class='flag-5'>stm32</b>中斷源有哪些_【話說(shuō)<b class='flag-5'>定時(shí)器</b>系列】之八:<b class='flag-5'>STM32</b><b class='flag-5'>定時(shí)器</b><b class='flag-5'>計(jì)數(shù)</b><b class='flag-5'>定時(shí)</b>基本<b class='flag-5'>功能</b>實(shí)驗(yàn)...

    STM32 使用定時(shí)器計(jì)數(shù) 寄存版本

    32完全可以克服這一困難STM32F103系列可使用的定時(shí)器8個(gè),其中通用定時(shí)器有TMI1-TIM7高級(jí)定時(shí)器TIM0 TIM8而在這 我主要使用通用
    發(fā)表于 12-27 18:27 ?0次下載
    <b class='flag-5'>STM32</b> 使用<b class='flag-5'>定時(shí)器</b><b class='flag-5'>計(jì)數(shù)</b> 寄存<b class='flag-5'>器</b>版本

    STM32F03定時(shí)器基礎(chǔ)知識(shí)基本簡(jiǎn)介

    STM32F103微控制定時(shí)器分為系統(tǒng)定時(shí)器(SysTick)、“看門(mén)狗”定時(shí)器(WatchDog)、基本
    的頭像 發(fā)表于 07-03 17:08 ?3800次閱讀
    <b class='flag-5'>STM32</b>F03<b class='flag-5'>定時(shí)器</b><b class='flag-5'>基礎(chǔ)知識(shí)</b>基本簡(jiǎn)介