stm32通用定時器用做外部脈沖計數(shù)器的例程
最近幾天要用到stm32對外部輸入脈沖進行計數(shù),很自然想到定時器,可是手上資料沒有講解stm32定時器如何用作外部計數(shù)器的,在網(wǎng)上找例程,也沒找到幾個正確的,自己硬著頭皮仔細研究參考手冊,終于知道如何配置了,并寫了一個例程,希望將來對一些網(wǎng)友有用。
其實stm32通用定時器做計數(shù)器,對外部脈沖計數(shù),還是比較簡單的,使用外部時鐘模式2即可輕松實現(xiàn),但要注意,這種模式下,外部輸入脈沖信號一定要接在相應TIM的ETR引腳上,不能接在TIMx_CHy引腳上。
使用stm32定時器的外部時鐘模式2,主要就是通過配置TIMx_SMCR寄存器相應位。步驟如下:
1. 若不需要濾波器,置TIMx_SMCR寄存器中的ETF[3:0]=0000
2. 設置預分頻,TIMx_SMCR寄存器中的ETPS[1:0]
3. 設置ETR的檢測極性,TIMx_SMCR寄存器中的ETP位
4. 開啟外部時鐘模式2,置TIMx_SMCR寄存器中的ECE=1
5. 啟動計數(shù)器,置TIMx_CR1寄存器中的CEN=1
我的例程是利用定時器2,定時產(chǎn)生周期1s的方波信號,通過PB5(LED0)輸出,通過導線將PB5的方波信號輸入到TIMER3的ETR引腳PD2上,通過TIMER3對該方波信號計數(shù),計數(shù)次數(shù)到了之后,更改LED1的狀態(tài)。
以下程序已經(jīng)過測試,可行。
//timer2 ,定時器模式
void TIM2_Int_Init(u16 arr,u16 psc)
{
RCC->APB1ENR |= 1<<0;//TIM2時鐘使能
TIM2->ARR = arr;
TIM2->PSC = psc;
TIM2->DIER |= 1<<0;//允許更新中斷
TIM2->DIER |= 1<<6;//使能觸發(fā)中斷
MY_NVIC_Init(1,2,TIM2_IRQChannel,2);//搶占1,子優(yōu)先級2,組2
TIM2->CR1 |= 1<<0;//使能定時器
}
//定時器2中斷服務程序
void TIM2_IRQHandler(void)
{
if(TIM2->SR&0X0001)//溢出中斷
{
LED0=!LED0; //PB5,硬件連線:將PB5連接至TIM3_ETR引腳PD2上
}
TIM2->SR&=~(1<<0);//清除中斷標志位
}
//通用定時器3 用作外部計數(shù)器 初始化
//arr:計數(shù)自動重裝值。
void TIM3_Int_Init(u16 arr)
{
RCC->APB2ENR|=1<<5;//開啟GPIOD端口時鐘
GPIOD->CRL &= 0xfffff0ff;
GPIOD->CRL |= 0x00000400;//PD.2 浮空輸入
RCC->APB1ENR |= 1<<1;//使能TIM3時鐘
TIM3->ARR=arr; //設定計數(shù)器自動重裝值
TIM3->PSC=0; //不分頻
TIM3->SMCR &= ~(0xf<<8);//無濾波
TIM3->SMCR &= ~(3<<12);//關(guān)閉預分頻
TIM3->SMCR |= 1<<15;//ETR被反相,低電平或下降沿有效
TIM3->SMCR |= 1<<14;//使能外部時鐘模式2
TIM3->DIER |= 1<<0;//允許更新中斷
TIM3->DIER |= 1<<6;//允許觸發(fā)中斷
MY_NVIC_Init(1,3,TIM3_IRQChannel,2);//搶占1,子優(yōu)先級3,組2
TIM3->CNT = 0x0;//清零計數(shù)器
TIM3->CR1 |= 1<<0;//使能定時器,開啟計數(shù)。
}
//定時器3中斷服務程序
void TIM3_IRQHandler(void)
{
if(TIM3->SR&0X0001)//溢出中斷
{
LED1=!LED1;
}
TIM3->SR&=~(1<<0);//清除中斷標志位
}
int main(void)
{
Stm32_Clock_Init(9);//系統(tǒng)時鐘設置
uart_init(72,9600);//串口初始化為9600
delay_init(72);//延時初始化
LED_Init(); //初始化與LED連接的硬件接口
BEEP_Init(); //初始化蜂鳴器端口
KEY_Init(); //初始化與按鍵連接的硬件接口
TIM3_Int_Init(20); //計數(shù)次數(shù)
TIM2_Int_Init(4999,7199);//時鐘周期0.1ms,計數(shù)5000次=定時0.5s
while(1);
}
實驗結(jié)果:LED0 :1s點亮一次,LED1: 20s點亮一次。