STM32F103ZET6 之 通用定時器單脈衝模式實驗
阿新 • • 發佈:2019-02-19
由於前面買的核心板,供電老有問題,使得我現在的專案又改用了以前用的F103ZET6微控制器!
1、實驗目的
1)產生脈寬任意可調的單脈衝(在允許的範圍內)
2、硬體:通用定時器3、通用定時器4
3、單脈衝模式介紹
單脈衝模式允許計數器響應一個激勵,並在一個程式可控的延時之後,產生一個脈寬可程式控制的脈衝。
可以通過從模式控制器啟動計數器,在輸出比較模式或者PWM模式下產生波形。設定TIMx_CR1 暫存器中的OPM 位將選擇單脈衝模式,這樣可以讓計數器自動的產生下一個更新
事情UEV時停止。
僅當比較值與計數器的初始值不同時,才能產生一個脈衝。啟動之前(當定時器正在等待觸發),必須配置如下:
向上計數方式:CNT (計數器暫存器) < CCRx (比較暫存器)< ARR(自動裝載暫存器)
向下計數方式:CNT > CCRx。
需要在從TI2輸入腳上檢測到一個上升沿開始,延遲tDELAY 之後,在OC1上產生一個長度為tPULSE 的正脈衝。
具體的可以看參考手冊。
4、軟體設計
/** ****************************************************************************** * @file timonepulse.c * @author Cawen * @version V1.0 * @date 2015-12-22 ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include"timonepulse.h" /* Private variables ---------------------------------------------------------*/ uint16_t PrescalerValue = 0; /* * Function Name : GPIO_Configuration * Description : Configure the GPIOD Pins. * Input : None * Output : None * Return : None * Attention : None */ void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; /* TIM4_CH1 pin (PB.06) configuration */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); /* TIM4_CH2 pin (PB.07) configuration */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOB, &GPIO_InitStructure); } /* * Function Name : TIM4_Configuration * Description : TIM4 configuration: One Pulse mode The external signal is connected to TIM4_CH2 pin (PB.07), The Rising edge is used as active edge, The One Pulse signal is output on TIM4_CH1 pin (PB.06) The TIM_Pulse defines the delay value The (TIM_Period - TIM_Pulse) defines the One Pulse value. TIM2CLK = SystemCoreClock, we want to get TIM2 counter clock at 24 MHz: - Prescaler = (TIM2CLK / TIM2 counter clock) - 1 The Autoreload value is 65535 (TIM4->ARR), so the maximum frequency value to trigger the TIM4 input is 24000000/65535 = 300 Hz. The TIM_Pulse defines the delay value, the delay value is fixed to 682.6 us: delay = CCR1/TIM4 counter clock = 682.6 us. The (TIM_Period - TIM_Pulse) defines the One Pulse value, the pulse value is fixed to 2.048 ms: One Pulse value = (TIM_Period - TIM_Pulse) / TIM4 counter clock = 2.048 ms. * Input : None * Output : None * Return : None * Attention : None */ void TIM4_Configuration(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_ICInitTypeDef TIM_ICInitStructure; TIM_OCInitTypeDef TIM_OCInitStructure; /* TIM4 and GPIOB clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); /* Compute the prescaler value */ PrescalerValue = (uint16_t) (72000000 / 10000) - 1; /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 5999; TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); /* TIM4 PWM2 Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 2000; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM4, &TIM_OCInitStructure); /* TIM4 configuration in Input Capture Mode */ TIM_ICStructInit(&TIM_ICInitStructure);//恢復預設值 TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;//選擇輸入端IC2對映到TI2上 TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;//上升沿捕獲 TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//對映到TI2上 TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;//配置輸入分頻,不分頻 TIM_ICInitStructure.TIM_ICFilter = 0;//配置輸入濾波,不濾波 TIM_ICInit(TIM4, &TIM_ICInitStructure); /* 單脈衝模式選擇 */ TIM_SelectOnePulseMode(TIM4, TIM_OPMode_Single);//生成單一的脈衝:計數器在下一個更新事件停止 /* 選擇 TIM 輸入觸發源 */ TIM_SelectInputTrigger(TIM4, TIM_TS_TI2FP2);//TIM 經濾波定時器輸入2 /* 選擇 TIM 從模式 */ TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Trigger); //計數器在觸發的上升沿開始 } /* * Function Name : TIM3_PWM_Init(u16 arr,u16 psc) * Description : TIM3 PWM部分初始化 PWM輸出初始化 arr:自動重灌值 psc:時鐘預分頻數 * Input : None * Output : None * Return : None * Attention : None */ void TIM3_PWM_Init(u16 arr,u16 psc) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定時器3時鐘 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIO外設時鐘 TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中斷,允許更新中斷 NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中斷 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先佔優先順序0級 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //從優先順序3級 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能 NVIC_Init(&NVIC_InitStructure); //根據NVIC_InitStruct中指定的引數初始化外設NVIC暫存器 //設定該引腳為複用輸出功能,輸出TIM3 CH2的PWM脈衝波形 GPIOA7 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //TIM_CH2 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //複用推輓輸出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO //初始化TIM3 TIM_TimeBaseStructure.TIM_Period = arr; //設定在下一個更新事件裝入活動的自動重灌載暫存器週期的值 TIM_TimeBaseStructure.TIM_Prescaler =psc; //設定用來作為TIMx時鐘頻率除數的預分頻值 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設定時鐘分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計數模式 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根據TIM_TimeBaseInitStruct中指定的引數初始化TIMx的時間基數單位 //初始化TIM3 Channel2 PWM模式 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //選擇定時器模式:TIM脈衝寬度調製模式2 TIM_OCInitStructure.TIM_Pulse = 5000; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性:TIM輸出比較極性高 TIM_OC2Init(TIM3, &TIM_OCInitStructure); //根據T指定的引數初始化外設TIM3 OC2 TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的預裝載暫存器 TIM_Cmd(TIM3, ENABLE); //使能TIM3 } //定時器3中斷服務程式 void TIM3_IRQHandler(void) //TIM3中斷 { if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //檢查指定的TIM中斷髮生與否:TIM 中斷源 { TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除TIMx的中斷待處理位:TIM 中斷源 TIM_Cmd(TIM3, DISABLE); //失能TIM3 } }