打印
[STM32F0]

STM32F030F4P6无法进入捕获中断的解决方法

[复制链接]
3666|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yellow555|  楼主 | 2024-3-31 11:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
出于节约成本又想快速上手的角度出发选择了这款单片机进行开发。但是stm32f030这款单片机的网上资源比其他系列少了很多,输入捕获采集的例程更是极少。楼主使用PB1口进行捕获采集计算频率时发现无法进入捕获中断,经过学习其他历程发现输入捕获时io口初始化很重要,io口需要设置为复用推挽输出才能触发捕获中断(请原谅楼主第一次用捕获中断)。最后实测频率1-1000hz的信号源输出误差在1%以下。部分代码分享如下,后续会上传整个工程方便大家利用。

1.复用功能映射

GPIO_PinAFConfig(GPIOB, GPIO_Pin_1, GPIO_AF_0);//配置PB1为TIM14_CH1

使用特权

评论回复
沙发
yellow555|  楼主 | 2024-3-31 11:52 | 只看该作者
.IO口初始化

GPIO_InitStruct.GPIO_Pin    = GPIO_Pin_1;
GPIO_InitStruct.GPIO_Mode   = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_PuPd   = GPIO_PuPd_NOPULL;//浮空状态
GPIO_InitStruct.GPIO_OType  = GPIO_OType_PP;   //复用推挽输出
GPIO_InitStruct.GPIO_Speed  = GPIO_Speed_10MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
GPIO_ResetBits(GPIOB,GPIO_Pin_1);

使用特权

评论回复
板凳
yellow555|  楼主 | 2024-3-31 11:53 | 只看该作者
定时器初始化

    TIM_TimeBaseInitTypeDef     TIM_TimeBaseStructure;
        TIM_ICInitTypeDef                         TIM_ICInitStruct;
    NVIC_InitTypeDef            NVIC_InitStructure;
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB,ENABLE);//使能时钟
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14, ENABLE);
    /* 时基配置 */
    TIM_TimeBaseStructure.TIM_Period          = (0XFFFF) ;  //设置计数器
    TIM_TimeBaseStructure.TIM_Prescaler       = (48-1);  //设置预分频的值48,1Mhz
    TIM_TimeBaseStructure.TIM_ClockDivision   = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode     = TIM_CounterMode_Up;//向上计数
   
    TIM_TimeBaseInit(TIM14, &TIM_TimeBaseStructure);
        TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;//通道2
        TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;//上升沿捕获
        TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;//映射到TI1上
        TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;//配置输入分频,不分频TIM_ICPSC_DIV1
        TIM_ICInitStruct.TIM_ICFilter = 0;//配置输入滤波器,不滤波
        TIM_ICInit(TIM14, &TIM_ICInitStruct);
   
    /* 使能TIM3全局中断*/
    NVIC_InitStructure.NVIC_IRQChannel            = TIM14_IRQn ;
    NVIC_InitStructure.NVIC_IRQChannelPriority    = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd         = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
        TIM_ITConfig(TIM14,TIM_IT_Update,ENABLE);//允许更新中断
    TIM_ITConfig(TIM14,TIM_IT_CC1,ENABLE);//允许捕获比较2中断
   
        TIM_ClearITPendingBit(TIM14, TIM_IT_Update);//清除更新中断
    TIM_ClearITPendingBit(TIM14, TIM_IT_CC1);//清除捕获中断
    TIM_Cmd(TIM14, ENABLE);

使用特权

评论回复
地板
yellow555|  楼主 | 2024-3-31 11:53 | 只看该作者
溢出中断调用函数

void time14_updata_irq(void)//定时器更新中断(计数溢出)中断处理回调函数
{
        if((TIM14_CH1_STA&0X80)==0)//还未成功捕获
        {
                if(TIM14_CH1_STA&0X40)//已经捕获到高电平了
                {
                        if((TIM14_CH1_STA&0X3F)==0X3F)//高电平太长了
                        {
                                TIM14_CH1_STA|=0X80;                //标记成功捕获了一次
                                TIM14_CH1_VAL=0XFFFF;
                        }
                        else
                        {
                                TIM14_CH1_STA++;
                        }
                }         
        }
}

使用特权

评论回复
5
yellow555|  楼主 | 2024-3-31 11:53 | 只看该作者
捕获中断调用函数
void TIM14_CH1_CaptureCallback(void)//捕获中断发生时执行
{                                            
        if((TIM14_CH1_STA&0X80)==0)//还未成功捕获
        {
                if(TIM14_CH1_STA&0X40)                //捕获到一个下降沿                
                {                                 
                        TIM14_CH1_STA|=0X80;                //标记成功捕获到一次高电平脉宽
            TIM14_CH1_VAL=TIM_GetCapture1(TIM14);//获取当前的捕获值.
                        TIM_OC1NPolarityConfig(TIM14,TIM_ICPolarity_Rising);//配置TIM5通道1上升沿捕获
                }
                else                                                                  //还未开始,第一次捕获上升沿
                {
                        TIM14_CH1_STA=0;                        //清空
                        TIM14_CH1_VAL=0;
                        TIM14_CH1_STA|=0X40;                //标记捕获到了上升沿
                        TIM_Cmd(TIM14, DISABLE);//关闭定时器5
                        TIM_SetCounter(TIM14,0);//清零计数
                        TIM_OC1NPolarityConfig(TIM14,TIM_ICPolarity_Falling);//定时器5通道1设置为下降沿捕获
                        TIM_Cmd(TIM14, ENABLE);//使能定时器5
                }                    
        }       

使用特权

评论回复
6
yellow555|  楼主 | 2024-3-31 11:53 | 只看该作者
计算频率

if(TIM14_CH1_STA&0X80)        //成功捕获到了一次高电平
{
        temp=TIM14_CH1_STA&0X3F;
        temp*=0XFFFF;                             //溢出时间总和
        temp+=TIM14_CH1_VAL;      //得到总的高电平时间
        sys_state.sys_temp = temp;
        sys_state.frequency = (float)(1000000 / (float)sys_state.sys_temp);
        TIM14_CH1_STA=0;          //开启下一次捕获
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

37

主题

463

帖子

3

粉丝