STM32 霍尔 测量
本帖最后由 wooten_2017 于 2018-1-25 11:39 编辑
#include "public.h"
#include "Systick.h"
#include "led.h"
#include "usart.h"
#include "inputcapture.h"
#include "ADC.h"
extern float bohelunzhuansu;
//extern u32 timer_times;//定时器溢出次数
//extern u16 BOHELUN_PI_STA;
//extern u32 BOHELUN_PI_VAL[2];
int main()
{
u8 i=0;
SysTick_Init(72);//初始化时钟源
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级分组
LED_Init();
USART1_Init(9600);
TIM3_Cap_Init(1000,71); //定时器周期ARR=1000,时钟频率1MHZ,一个更新中断周期1ms
while(1)
{
printf("转一圈时间 %.2fsrn",bohelunzhuansu);
if(i%20==0)
{
led1=!led1;
}
delay_ms(500);
}
}
#include "inputcapture.h"
//采用定时器5的通道1进行输入捕获
float bohelunzhuansu=0;
//int gedaosudu=0;
//int jiaolongzhuansu=0;
u32 timer_times;//定时器溢出次数
u16 BOHELUN_PI_STA;
u32 BOHELUN_PI_VAL;
TIM_ICInitTypeDef TIM3_ICInitStructure;
void TIM3_Cap_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器3
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //设置端口时钟,对时钟使能,根据原理图可以发现TIM3_CH1对应的是PA6管脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //设置端口 +
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置GPIO输出模式为上拉输入,这样默认电平是高电平,当传感器接收到信号后变成低电平。||*****************************此处需要根据霍尔传感器的特性决定
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化
GPIO_ResetBits(GPIOA,GPIO_Pin_6); //既然是上拉输入,那么先把电压置1
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
// GPIO_Init(GPIOB, &GPIO_InitStructure);
// GPIO_ResetBits(GPIOB,GPIO_Pin_0);
TIM_TimeBaseStructure.TIM_Period = arr; //定时器周期
TIM_TimeBaseStructure.TIM_Prescaler =psc; //分频系数
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分频,1分频,没有滤波作用
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数功能
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //初始化定时器
//设置TIM3_CH1的输入捕获功能
TIM3_ICInitStructure.TIM_Channel = TIM_Channel_1; //通道1
TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling; //下降沿捕获
TIM3_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //直接映射到TI1,因为根据手册200页的框图,IC1会被映射到TI1和TI2,所以需选择
TIM3_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //不分频
TIM3_ICInitStructure.TIM_ICFilter = 0x00; //无滤波
TIM_ICInit(TIM3, &TIM3_ICInitStructure); //完成TIM3_CH1初始化配置
// TIM3_ICInitStructure.TIM_Channel = TIM_Channel_2;
// TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
// TIM3_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
// TIM3_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
// TIM3_ICInitStructure.TIM_ICFilter = 0x00;
// TIM_ICInit(TIM3, &TIM3_ICInitStructure);
// TIM3_ICInitStructure.TIM_Channel = TIM_Channel_3;
// TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
// TIM3_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
// TIM3_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
// TIM3_ICInitStructure.TIM_ICFilter = 0x00;
// TIM_ICInit(TIM3, &TIM3_ICInitStructure);
//NVIC结构体初始化,初始化结构体成员
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_ITConfig(TIM3,TIM_IT_Update|TIM_IT_CC1,ENABLE); //开启定时器溢出计数的更新中断和通道1的输入捕获中断,这个根据200页的原理图可以看出,每一个输入捕获寄存器可以对应4个中断通道
TIM_Cmd(TIM3,ENABLE ); //使能定时器
}
void TIM3_IRQHandler(void)//测频率,对应3路PI
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //当更新中断产生,继续下面操作
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除更新中断标志
timer_times++; //产生更新中断的次数加1
BOHELUN_PI_STA++; //拨禾轮状态参数加1
// GEDAO_PI_STA++;
// JIAOLONG_PI_STA++;
if(BOHELUN_PI_STA>=2000)//转速太低,小于30r/min //如果拨禾轮在两次下降沿捕获之间的更新中断次数大于200,也就是意味着两次霍尔开关打开的时间过长,那么就可以认为拨禾轮转速为0
{
bohelunzhuansu=0;
}
// if(GEDAO_PI_STA>=200)//转速太低,小于30r/min
// {
// gedaosudu=0;
// }
// if(JIAOLONG_PI_STA>=200)//转速太低,小于30r/min
// {
// jiaolongzhuansu=0;
// }
}
if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET) //如果产生下降沿捕获,那么继续下列操作
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC1); //清空下降沿捕获标志
BOHELUN_PI_STA=0; //清空拨禾轮状态标志
BOHELUN_PI_VAL=timer_times*1000+TIM_GetCounter(TIM3);//计算此次拨禾轮转一圈所需时间,单位us
bohelunzhuansu=(BOHELUN_PI_VAL/1000000); //计算出拨禾轮转一圈时间,单位s
}
// if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)
// {
// TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
// GEDAO_PI_STA=0;
// GEDAO_PI_VAL[0]=GEDAO_PI_VAL[1];
// GEDAO_PI_VAL[1]=timer_times*10000+TIM_GetCounter(TIM3);
// gedaosudu=1000000*60/(GEDAO_PI_VAL[1]-GEDAO_PI_VAL[0]);
// }
// if (TIM_GetITStatus(TIM3, TIM_IT_CC3) != RESET)
// {
// TIM_ClearITPendingBit(TIM3, TIM_IT_CC3);
// JIAOLONG_PI_STA=0;
// JIAOLONG_PI_VAL[0]=JIAOLONG_PI_VAL[1];
// JIAOLONG_PI_VAL[1]=timer_times*10000+TIM_GetCounter(TIM3);
// jiaolongzhuansu=1000000*60/(JIAOLONG_PI_VAL[1]-JIAOLONG_PI_VAL[0]);
// }
}
更多回帖