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

因?yàn)橛昧薲elay函數(shù)延時(shí)顯示避免刷屏,所以有點(diǎn)跳數(shù)了,不過(guò)數(shù)值還是正確的。
|
|