|
今天早上開始做項目中的測速部分,采用3144E開關(guān)型霍爾傳感器數(shù)字輸出,只要單片機采集模塊輸出的脈沖個數(shù),從而即可計算出速度。折騰了一下下,現(xiàn)在寫下思路。
首先總結(jié)下STM32外部脈沖ETR引腳:
TIMER1-----PA12
TIMER2-----PA0
TIMER3-----PD2
TIMER4-----PE0
其他大家有需要再查數(shù)據(jù)手冊的引腳圖即可。
這邊使用使用定時器TIM1的ETR輸入引腳PA12作為采集脈沖輸入引腳,定時器TIM1是16位可自動裝載初始值的高級計數(shù)器,使能GPIO和TIM1時鐘后,把GPIO口配置成浮空輸入模式,自動重裝初始值和分頻系數(shù)大家可以根據(jù)實際情況自己設(shè)置,這邊開啟更新中斷TIM_IT_Update,查了數(shù)據(jù)手冊后發(fā)現(xiàn)中斷向量號是TIM1_UP_IRQn,并不是TIM1_IRQn。
初始化代碼
void TIM1_Counter_Init(u32 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructuer;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE); ///使能TIM1時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStructuer.GPIO_Pin=GPIO_Pin_12;
GPIO_InitStructuer.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_InitStructuer.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructuer);
//timer1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//搶占優(yōu)先級2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;//子優(yōu)先級2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根據(jù)指定的參數(shù)初始化VIC寄存器
TIM_TimeBaseInitStructure.TIM_Period = arr;//自動重裝載值
TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //定時器分頻
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上計數(shù)模式
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStructure);//初始化TIM1
TIM_ETRClockMode2Config(TIM1, TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted, 5);//5次采樣濾波 外部時鐘模式2
TIM_ClearITPendingBit(TIM1,TIM_IT_Update); //清除中斷標志位,避免第一次自動進入中斷一次
TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);
TIM_SetCounter(TIM1,0);//設(shè)置計數(shù)初值
TIM_Cmd(TIM1,ENABLE); //使能定時器1
}
//定時器1中斷服務(wù)函數(shù)
u8 overflow_cnt=0;//溢出次數(shù)
void TIM1_UP_IRQHandler(void)
{
if(TIM_GetITStatus(TIM1,TIM_IT_Update)==SET) //溢出中斷
{
overflow_cnt++;
printf("\r\n*********測速計數(shù)溢出***********\r\n");
}
TIM_ClearITPendingBit(TIM1,TIM_IT_Update); //清除中斷標志位
}
一開始,中斷服務(wù)函數(shù)名稱寫錯成TIM1_IRQHandler,導(dǎo)致沒有進入中斷,看了下啟動文件中的中斷函數(shù)名發(fā)現(xiàn)定時器1有好幾個中斷函數(shù),于是便看了下數(shù)據(jù)手冊的說明,才發(fā)現(xiàn)是錯了,改正后,程序正常。
主函數(shù)那邊printf("CNT:%d\r\n",TIM_GetCounter(TIM1));獲取計數(shù)值,打開串口調(diào)試助手,再用小磁鋼在模塊旁邊甩動,一開始小磁鋼的方向放錯了,導(dǎo)致計數(shù)值一直沒增加,改用按鍵輸入脈沖調(diào)試了一會想到會不會是因為磁場方向問題,換了下小磁鋼的方向,計數(shù)值就增加了,哎。

因為用了delay函數(shù)延時顯示避免刷屏,所以有點跳數(shù)了,不過數(shù)值還是正確的。
|
|