OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3664|回复: 3

STM32F429定时器TIM5_CH1输入捕获,用霍尔传感器测风扇转速

[复制链接]

4

主题

10

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2019-5-15
在线时间
18 小时
发表于 2019-11-21 15:49:04 | 显示全部楼层 |阅读模式
12金钱
TIM_HandleTypeDef TIM5_Handler;         //?¨ê±?÷5??±ú

//?¨ê±?÷5í¨μà1ê?è?2???????
//arr£o×??ˉ??×°?μ(TIM2,TIM5ê?32??μ?!!)
//psc£oê±?ó?¤·??μêy
void TIM5_CH1_Cap_Init(u32 arr,u16 psc)
{
    TIM_IC_InitTypeDef TIM5_CH1Config;
    TIM5_Handler.Instance=TIM5;                          //í¨ó??¨ê±?÷5
    TIM5_Handler.Init.Prescaler=psc;                     //·??μ?μêy
    TIM5_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;    //?òé???êy?÷
    TIM5_Handler.Init.Period=arr;                        //×??ˉ×°???μ
    TIM5_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;//ê±?ó·??μò?×ó
    HAL_TIM_IC_Init(&TIM5_Handler);//3?ê??ˉê?è?2???ê±?ù2?êy
    TIM5_CH1Config.ICPolarity=TIM_ICPOLARITY_RISING;    //é?éy??2???
    TIM5_CH1Config.ICSelection=TIM_ICSELECTION_DIRECTTI;//ó3é?μ?TI1é?
    TIM5_CH1Config.ICPrescaler=TIM_ICPSC_DIV1;          //????ê?è?·??μ£?2?·??μ
    TIM5_CH1Config.ICFilter=0;                          //????ê?è???2¨?÷£?2???2¨
    HAL_TIM_IC_ConfigChannel(&TIM5_Handler,&TIM5_CH1Config,TIM_CHANNEL_1);//????TIM5í¨μà1
    HAL_TIM_IC_Start_IT(&TIM5_Handler,TIM_CHANNEL_1);   //?a??TIM5μ?2???í¨μà1£?2¢?ò?a??2????D??
    __HAL_TIM_ENABLE_IT(&TIM5_Handler,TIM_IT_UPDATE);   //ê1?ü?üD??D??
}

//?¨ê±?÷5μ×2??y?ˉ£?ê±?óê1?ü£?òy??????
//′?oˉêy?á±?HAL_TIM_IC_Init()μ÷ó?
//htim:?¨ê±?÷5??±ú
void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{
    GPIO_InitTypeDef GPIO_Initure;
    if(htim->Instance == TIM5)
    {
        __HAL_RCC_TIM5_CLK_ENABLE();            //ê1?üTIM5ê±?ó
        __HAL_RCC_GPIOH_CLK_ENABLE();   //?a??GPIOHê±?ó
        GPIO_Initure.Pin=GPIO_PIN_10;            //PH10
        GPIO_Initure.Mode=GPIO_MODE_INPUT;      //ê?è?
        GPIO_Initure.Pull=GPIO_NOPULL;        //??à----------
        GPIO_Initure.Alternate=GPIO_AF2_TIM5;   //PH10?′ó??aTIM5í¨μà1
        HAL_GPIO_Init(GPIOH,&GPIO_Initure);
        HAL_NVIC_SetPriority(TIM5_IRQn,2,0);    //éè???D??ó??è??£??à??ó??è??2£?×óó??è??0
        HAL_NVIC_EnableIRQ(TIM5_IRQn);          //?a??ITM5?D??í¨μà
    }
}

//2???×′ì?
//[7]:0,??óD3é1|μ?2???;1,3é1|2???μ?ò?′?.
//[6]:0,?1??2???μ?μíμ???;1,ò??-2???μ?μíμ???á?.
//[5:0]:2???μíμ???oóò?3?μ?′?êy(??óú32???¨ê±?÷à′?μ,1us??êy?÷?ó1,ò?3?ê±??:4294??)
u8  TIM5CH1_CAPTURE_STA=0; //ê?è?2???×′ì?
u32 TIM5CH1_CAPTURE_VAL=0; //ê?è?2????μ(TIM2/TIM5ê?32??)
u16 TIM5_CH1_CAPTURE_Times=0; //ò?3?ê±??
//?¨ê±?÷5?D??·t??oˉêy
void TIM5_IRQHandler(void)
{
    if(__HAL_TIM_GET_FLAG(&TIM5_Handler, TIM_FLAG_UPDATE) != RESET)
    {
        if(__HAL_TIM_GET_IT_SOURCE(&TIM5_Handler, TIM_IT_UPDATE) !=RESET)
        {
            __HAL_TIM_CLEAR_IT(&TIM5_Handler, TIM_IT_UPDATE);
     TIM5_CH1_CAPTURE_Times++;               //??êy?÷ò?3?′?êy+1
     if(TIM5_CH1_CAPTURE_Times>=1000)           //è?1???ê±μ?′?1??
     {
      TIM5CH1_CAPTURE_STA=1;               //?¨á¢2a?ùóDD§±ê??
      TIM5_CH1_CAPTURE_Times=0;              //??0£?×?±???ò?′???ê±
     }
        }
    }
    /* Capture compare 1 event */
    if(__HAL_TIM_GET_FLAG(&TIM5_Handler, TIM_FLAG_CC1) != RESET)
    {
        if(__HAL_TIM_GET_IT_SOURCE(&TIM5_Handler, TIM_IT_CC1) !=RESET)
        {
            {
                __HAL_TIM_CLEAR_IT(&TIM5_Handler, TIM_IT_CC1);
                /* Input capture event */
                if((TIM5_Handler.Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00)
                {
                   if(TIM5CH1_CAPTURE_STA & 0x40)            //è?1?2???μ?μíμ???£¨???μ??£?
         {
          TIM5CH1_CAPTURE_STA&=0xdf;             //?¨á¢?°2???μ?μíμ????±±ê??
          TIM5CH1_CAPTURE_VAL++;  
         __HAL_TIM_DISABLE(&TIM5_Handler);        //1?±??¨ê±?÷5                       //Dy×a′?êy?ó1
          TIM_RESET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1);   //ò??¨òa?è??3y?-à′μ?éè??£?£?
          TIM_SET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1,TIM_ICPOLARITY_RISING);//????TIM5í¨μà1é?éy??2???
           __HAL_TIM_ENABLE(&TIM5_Handler);//ê1?ü?¨ê±?÷5
         }
         else                         //è?1?2???μ???μ???£¨é?éy??£?
         {
          TIM5CH1_CAPTURE_STA|=0x40;             //?¨á¢?°2???μ???μ????±±ê??
         __HAL_TIM_DISABLE(&TIM5_Handler);        //1?±??¨ê±?÷5            //TIM4?Yí£1¤×÷
          TIM_RESET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1);   //ò??¨òa?è??3y?-à′μ?éè??£?£?
          TIM_SET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);//????TIM5í¨μà1é?éy??2???
          __HAL_TIM_ENABLE(&TIM5_Handler);//ê1?ü?¨ê±?÷5          //TIM4??D??aê???êy
         }
        }
            }
        }
    }
    //HAL_TIM_IRQHandler(&TIM5_Handler);//?¨ê±?÷12ó?′|àíoˉêy
}



下面是主函数

extern u16 TIM5_CH1_CAPTURE_Times; //
extern u8  TIM5CH1_CAPTURE_STA;  //ÊäÈë²¶»ñ״̬         
extern u32 TIM5CH1_CAPTURE_VAL; //ÊäÈë²¶»ñÖµ
int main(void)
{
   u32 speed=0;
    HAL_Init();                      //³õʼ»¯HAL¿â   
    Stm32_Clock_Init(360,25,2,8);    //ÉèÖÃʱÖÓ,180Mhz
    delay_init(180);                  //³õʼ»¯ÑÓʱº¯Êý
    uart_init(115200);               //³õʼ»¯USART
    LED_Init();                      //³õʼ»¯LED
    TIM5_CH1_Cap_Init(1000,90-1); //ÒÔ1MHZµÄƵÂʼÆÊý
    while(1)
    {
       if(TIM5CH1_CAPTURE_STA==1)  //Èç¹û³É¹¦²¶»ñ
    {
    speed=TIM5CH1_CAPTURE_VAL*60; //¼ÆËãÿ·ÖÖÓתËÙ
    printf("·çÉȵç»úתËÙ: %d ת/·Ö \r\n",speed); //´®¿ÚÊä³ö²âËÙÖµ
    TIM5CH1_CAPTURE_STA=0;  //×¼±¸ÏÂÒ»´Î²âËÙ
    TIM5CH1_CAPTURE_VAL=0;
    }
    }
}


我用printf打印后发现代码没有进入捕获中断,定时器更新中断进去了的,请问这个代码哪里有问题啊

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2019-11-22 01:26:44 | 显示全部楼层
回复

使用道具 举报

4

主题

10

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2019-5-15
在线时间
18 小时
 楼主| 发表于 2020-5-13 15:12:42 | 显示全部楼层
#include "input.h"
#include "oled.h"
#include "gizwits_product.h"
extern dataPoint_t currentDataPoint;
TIM_HandleTypeDef TIM5_Handler;         //定时器5句柄


//定时器5通道1输入捕获配置
//arr:自动重装值(TIM2,TIM5是32位的!!)
//psc:时钟预分频数
void TIM5_CH1_Cap_Init(u32 arr,u16 psc)
{
    TIM_IC_InitTypeDef TIM5_CH1Config;

    TIM5_Handler.Instance=TIM5;                          //通用定时器5
    TIM5_Handler.Init.Prescaler=psc;                     //分频系数
    TIM5_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;    //向上计数器
    TIM5_Handler.Init.Period=arr;                        //自动装载值
    TIM5_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;//时钟分频银子
    HAL_TIM_IC_Init(&TIM5_Handler);//初始化输入捕获时基参数

    TIM5_CH1Config.ICPolarity=TIM_ICPOLARITY_RISING;    //上升沿捕获
    TIM5_CH1Config.ICSelection=TIM_ICSELECTION_DIRECTTI;//映射到TI1上
    TIM5_CH1Config.ICPrescaler=TIM_ICPSC_DIV1;          //配置输入分频,不分频
    TIM5_CH1Config.ICFilter=0;                          //配置输入滤波器,不滤波
    HAL_TIM_IC_ConfigChannel(&TIM5_Handler,&TIM5_CH1Config,TIM_CHANNEL_1);//配置TIM5通道1

    HAL_TIM_IC_Start_IT(&TIM5_Handler,TIM_CHANNEL_1);   //开启TIM5的捕获通道1,并且开启捕获中断
    __HAL_TIM_ENABLE_IT(&TIM5_Handler,TIM_IT_UPDATE);   //使能更新中断
}


//定时器5底层驱动,时钟使能,引脚配置
//此函数会被HAL_TIM_IC_Init()调用
//htim:定时器5句柄
void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{
    GPIO_InitTypeDef GPIO_Initure;
    if(htim->Instance == TIM5)
    {
        __HAL_RCC_TIM5_CLK_ENABLE();            //使能TIM5时钟
        __HAL_RCC_GPIOH_CLK_ENABLE();                        //开启GPIOH时钟

        GPIO_Initure.Pin=GPIO_PIN_10;            //PH10
        GPIO_Initure.Mode=GPIO_MODE_AF_PP;      //输入
        GPIO_Initure.Pull=GPIO_PULLUP;        //上拉
        GPIO_Initure.Alternate=GPIO_AF2_TIM5;   //PH10复用为TIM5通道1
        HAL_GPIO_Init(GPIOH,&GPIO_Initure);

        HAL_NVIC_SetPriority(TIM5_IRQn,2,0);    //设置中断优先级,抢占优先级2,子优先级0
        HAL_NVIC_EnableIRQ(TIM5_IRQn);          //开启ITM5中断通道
    }

}


//捕获状态
//[7]:0,没有成功的捕获;1,成功捕获到一次.
//[6]:0,还没捕获到低电平;1,已经捕获到低电平了.
//[5:0]:捕获低电平后溢出的次数(对于32位定时器来说,1us计数器加1,溢出时间:4294秒)
u8  TIM5CH1_CAPTURE_STA=0;        //输入捕获状态
u32        TIM5CH1_CAPTURE_VAL=0;        //输入捕获值(TIM2/TIM5是32位)
u16 TIM5_CH1_CAPTURE_Times=0;        //溢出时间
extern u32 speed;
extern u8 wifi_sta;
//定时器5中断服务函数
void TIM5_IRQHandler(void)
{

    if(__HAL_TIM_GET_FLAG(&TIM5_Handler, TIM_FLAG_UPDATE) != RESET)
    {
        if(__HAL_TIM_GET_IT_SOURCE(&TIM5_Handler, TIM_IT_UPDATE) !=RESET)
        {
            __HAL_TIM_CLEAR_IT(&TIM5_Handler, TIM_IT_UPDATE);
            TIM5_CH1_CAPTURE_Times++;                                                                                                                        //计数器溢出次数+1
            if(TIM5_CH1_CAPTURE_Times>=1000)                                                                                        //如果计时到达1秒
            {
                TIM5CH1_CAPTURE_STA=1;                                                                                                                        //建立测速有效标志

                if(TIM5CH1_CAPTURE_STA==1)         //如果成功捕获
                {
                    speed=TIM5CH1_CAPTURE_VAL*20; //计算每分钟转速
                                                                        if(wifi_sta)
                                                                        {
                                                                                //OLED_ShowString(0,40,"speed",12);
                                                                                //printf("转速:%d\r\n",speed);
                                                                                //OLED_ShowNum(50,40,speed,6,12);
                                                                                //OLED_Refresh_Gram();//更新显示到OLED       
                                                                        }
                                                                                currentDataPoint.valueFan_Speed = speed;
                    TIM5CH1_CAPTURE_STA=0;         //准备下一次测速
                    TIM5CH1_CAPTURE_VAL=0;
                }
                TIM5_CH1_CAPTURE_Times=0;                                                                                                                //清0,准备下一次计时
            }
        }
    }
    /* Capture compare 1 event */
    if(__HAL_TIM_GET_FLAG(&TIM5_Handler, TIM_FLAG_CC1) != RESET)
    {
        if(__HAL_TIM_GET_IT_SOURCE(&TIM5_Handler, TIM_IT_CC1) !=RESET)
        {
            {
                __HAL_TIM_CLEAR_IT(&TIM5_Handler, TIM_IT_CC1);
                /* Input capture event */
                if((TIM5_Handler.Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00)
                {
                    if(TIM5CH1_CAPTURE_STA & 0x40)                                                                                                //如果捕获到低电平(下降沿)
                    {
                        TIM5CH1_CAPTURE_STA&=0xdf;                                                                                                 //建立“捕获到低电平”标志
                        TIM5CH1_CAPTURE_VAL++;                                                                                                                //旋转次数加1
                        __HAL_TIM_DISABLE(&TIM5_Handler);                                                //关闭定时器5                       
                        TIM_RESET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1);   //一定要先清除原来的设置!!
                        TIM_SET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1,TIM_ICPOLARITY_RISING);//配置TIM5通道1上升沿捕获
                        __HAL_TIM_ENABLE(&TIM5_Handler);                                                                                                                                                                        //使能定时器5
                    }
                    else                                                                                                                                                                                                        //如果捕获到高电平(上升沿)
                    {
                        TIM5CH1_CAPTURE_STA|=0x40;                                                                                                 //建立“捕获到高电平”标志
                        __HAL_TIM_DISABLE(&TIM5_Handler);                                                //关闭定时器5
                        TIM_RESET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1);   //一定要先清除原来的设置!!
                        TIM_SET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);//配置TIM5通道1下降沿捕获
                        __HAL_TIM_ENABLE(&TIM5_Handler);//使能定时器5                                               
                    }
                }
            }
        }
    }
    //HAL_TIM_IRQHandler(&TIM5_Handler);//定时器共用处理函数
}
回复

使用道具 举报

4

主题

10

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2019-5-15
在线时间
18 小时
 楼主| 发表于 2020-5-13 15:13:12 | 显示全部楼层
基本能实现,就是感觉不太准确
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-21 00:02

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表