娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

歷史上的今天

今天是:2025年05月31日(星期六)

2021年05月31日 | STM32學習之通用定時器的使用

發布者:SerendipityLove 來源: eefocus關鍵字:STM32  通用定時器  RTC 手機看文章 掃描二維碼
隨時隨地手機看文章

簡介:STM32一共有8個通用16位Timer,其中TIMER1和TIMER8是高級定時器,其它的TIMER2~TIMER7是普通定時器。此外還有一個Systick(系統滴答定時器),這個定時器通常在操作系統中作為系統的任務切換周期。還有一個RTC,是一個毫秒定時器,支持秒級中斷,用來做實時時鐘計數器。看門狗定時器 也可以算一個。


8個定時器中,Timer1 和Timer8是由APB2(輸出最高頻率為72MHZ)預分頻后,再通過一個倍頻器得到時鐘頻率,最高為72MHz。Timer2~Timer7則是由APB1(輸出最高頻率為36MHZ)預分頻后,再通過一個倍頻器得到時鐘頻率,最高為36MHz。


1、如何進行程序編寫


這里我通過定時器來控制一個LED亮0.5s 滅0.5s ,交替閃爍。當然要讓定時器正常工作起來,還要配置中斷NVIC。定時器計數到某個數,產生中斷,從而進入中斷服務程序,點亮LED燈。


main函數分析:


#include "stm32f10x.h"


void GPIO_Config(void)//GPIO配置


{


GPIO_InitTypeDef GPIO_InitStructure;


RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//使能gpioc的時


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; //選擇管腳PC.13作LED燈


GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //管腳速度為50M




GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //設置輸出模式為推挽輸出


GPIO_Init(GPIOC, &GPIO_InitStructure); //將上述設置寫入到GPIOC里去


}




void NVIC_Config(void) //中斷控制器的配置


{


NVIC_InitTypeDef NVIC_InitStructure;


NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //優先組設置


NVIC_InitStructure.NVIC_IRQChannel =TIM2_IRQn ; //TIM2中斷選通


NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //搶占優先級


NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子優先級


NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中斷控制


NVIC_Init(&NVIC_InitStructure);


}


void Timer_Config(void) //定時器的配置


{


TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;


RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE); //Timer2 時鐘使能


TIM_DeInit(TIM2); //復位TIM2定時器


TIM_TimeBaseStructure.TIM_Period=1000; //定時器周期


TIM_TimeBaseStructure.TIM_Prescaler=36000-1; //預分頻數


TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; //TIM2時鐘分頻,為1表示不分頻


TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//定時器計數為向上計數模式


TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);


TIM_ClearFlag(TIM2, TIM_FLAG_Update); //清除定時器2的溢出標志位


TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); //使能定時器2溢出中斷


TIM_Cmd(TIM2, ENABLE); //定時器2使能


}






int main(void)


{


SystemInit();//初始化時鐘,配置為72MHz,我試過將這句注釋掉,好像不影響結果。查


了一下,在配置


//main函數之前的啟動代碼有這樣一句 LDR R0, =SystemInit,我疑惑的是難


道啟動的時候就配成72Mhz?


GPIO_Config();


NVIC_Config();


Timer_Config();


while(1)


{


;


}


}








中斷服務函數


void TIM2_IRQHandler(void)


{


static int flag_bit=0;//定義一個標志位




if ( TIM_GetITStatus(TIM2 , TIM_IT_Update) != RESET ) //判斷中斷溢出標志為是否為1


{


TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update); //清除溢出中斷標志位


flag_bit = !flag_bit;


if(flag_bit == 1)


GPIO_SetBits(GPIOC, GPIO_Pin_13); //熄滅LED


if(flag_bit == 0)


GPIO_ResetBits(GPIOC, GPIO_Pin_13); //點亮LED


}




這個函數是寫在stm32f10x_it.c 里面的,我對TIM2_IRQHandler()函數的理解應該是這樣的:


首先由定時器定時,定時好了產生中斷溢出標志位,發送中斷


然后進入中斷服務函數TIM2_IRQHandler(),進入函數之后要做的就是清除中斷溢出


標志位。


最后再執行函數里的其他內容。


定時器定時時間計算是這兩句:


TIM_TimeBaseStructure.TIM_Period=1000; //定時器周期


TIM_TimeBaseStructure.TIM_Prescaler=36000-1; //預分頻數


Prescaler可以理解為定時器的基數是72M / Prescaler+1 = 2000k,也就是500us ,Period 可以理解為要計數多少次,這里是1000次。 所以就是每500us記一次,計數1000次,就是500ms。


公式為:


Period / (72M / (Prescaler+1) )=____ 秒


1000 / (72 M/ (35999+1) ) = 0.5 秒






我有的一些疑問:1、進入中斷函數之后,定時器要干些什么,是不是就停止計數了?


2、計數記到1000發生中斷,計數值是不是有自動清零


問題先放到這兒,邊學習,邊解決。

2、仿真結果觀察



前面第三章已經過如何仿真波形的步驟,可以參看前面。點擊setup 按鈕 會彈出一個窗口,在窗口的右上邊,有個new的按鈕,點擊后輸入 PORTC.13





仿真運行結果如下:



可以從仿真結果中觀察到,方波的周期為一秒。占空比為0.5 ,跟預期一致。



3、對第四章串口的補充

第四章介紹了串口的打印函數printf 是如何調用實現的。但要使用keil自帶的微庫microLIB ,那能不能不使用這個微庫呢。我參照野火的教程,修改了程序,自己編寫usart_printf()函數來實現打印的功能。




USRT1的配置不改變,主要的就是添加打印函數實現串口輸出功能。代碼感覺可能很長,但無非就是一些判斷,看看字符串最后一位是不是

主站蜘蛛池模板: 富顺县| 灵丘县| 衡阳市| 长海县| 双鸭山市| 雅江县| 读书| 宁安市| 商城县| 揭西县| 莆田市| 四子王旗| 长垣县| 会理县| 东兰县| 石河子市| 屯留县| 孝义市| 珲春市| 永丰县| 平和县| 邵东县| 黑河市| 台中县| 龙里县| 攀枝花市| 余干县| 壶关县| 江安县| 成都市| 宜城市| 长汀县| 泾川县| 东莞市| 邹平县| 江源县| 沐川县| 郓城县| 台中县| 蕲春县| 商洛市|