QADJKL 2023-05-30 10:04 采纳率: 0%
浏览 21

STM32F4计时器问题

void delay_ms(uint32_t t)//延时t ms
{
        timer_flag=0;//重置
    TIM_SetCounter(TIM6,0);//counter设置成0
        TIM_SetAutoreload(TIM6, 2*t-1);//ARR设置成2*t 
    TIM_Cmd(TIM6,ENABLE);//使能
    while(timer_flag==0);//等待
    TIM_Cmd(TIM6,DISABLE);//关闭
}

void timer_config(void)
{
    
TIM_TimeBaseInitTypeDef b;    
NVIC_InitTypeDef a;
    
    /*********时钟初始化************/
    b.TIM_CounterMode=TIM_CounterMode_Up;
    b.TIM_Prescaler=42000-1;//周期0.5ms
    TIM_TimeBaseInit(TIM6,&b);
    
    /*********允许中断更新************/
    TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE);
    
/*********中断配置************/
    /*********NVIC配置************/
    a.NVIC_IRQChannelCmd = ENABLE;
    a.NVIC_IRQChannel=TIM6_DAC_IRQn;
    a.NVIC_IRQChannelPreemptionPriority=0;
    a.NVIC_IRQChannelSubPriority = 0;
    NVIC_Init(&a);
    
    TIM_Cmd(TIM6,DISABLE);//中断之前    
}

#include "main.h"

/************定义并且初始化为0*********/
 double position_x=0;
 double position_y=0;
 double position_z=0;

 int timer_flag=0;
 
 int limit_switch_1=0;
 int limit_switch_2=0;
 int limit_switch_3=0;
 int button=0;
 
int main(void)
{
    initial();
    while(button ==0);//等待按键中断
    button =0;//还原
    on_LED1();
        delay_ms(6e4);
    off_LED1();
    while(1);//卡住
}


void initial()
{
    clc_enable();
    
    gpio_config();
    interrupt_config();
    timer_config();//时钟初始化
    off_all_LED();
}


void interrupt_config()
{
    NVIC_InitTypeDef a;
    EXTI_InitTypeDef b;
    
/*********中断配置************/
    /*********NVIC配置************/
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断分组2
    a.NVIC_IRQChannelCmd = ENABLE;
    
    
    a.NVIC_IRQChannel=EXTI1_IRQn;
    a.NVIC_IRQChannelPreemptionPriority=0;
    a.NVIC_IRQChannelSubPriority = 1;
    NVIC_Init(&a);
    
    a.NVIC_IRQChannel=EXTI2_IRQn;
    a.NVIC_IRQChannelPreemptionPriority=1;
    a.NVIC_IRQChannelSubPriority = 1;
    NVIC_Init(&a);
    
    a.NVIC_IRQChannel=EXTI3_IRQn;
    a.NVIC_IRQChannelPreemptionPriority=2;
    a.NVIC_IRQChannelSubPriority = 1;
    NVIC_Init(&a);
    
    a.NVIC_IRQChannel=EXTI4_IRQn;
    a.NVIC_IRQChannelPreemptionPriority=3;
    a.NVIC_IRQChannelSubPriority = 1;
    NVIC_Init(&a);
    
    /*********EXIT配置************/
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能syscfg

    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOD, EXTI_PinSource1);//EXTI通道选择
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource2);
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource3);
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource4);
    
    /*********EXIT每个中断源配置************/
    b.EXTI_Mode = EXTI_Mode_Interrupt;
    b.EXTI_LineCmd = ENABLE;
    
    b.EXTI_Line = EXTI_Line1;//下降沿触发
    b.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_Init(&b);
     
    b.EXTI_Line = EXTI_Line2;//上升沿触发
    b.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_Init(&b);
    
    b.EXTI_Line = EXTI_Line3;
    b.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_Init(&b);
    
    b.EXTI_Line = EXTI_Line4;
    b.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_Init(&b);
}

void gpio_config()
{
    GPIO_InitTypeDef c;
/*********按键配置************/
    c.GPIO_Mode=GPIO_Mode_IN;
    c.GPIO_PuPd=GPIO_PuPd_NOPULL;
    
    c.GPIO_Pin=GPIO_Pin_1;
    GPIO_Init(GPIOD, &c);

    
    
    /*********LED配置************/
    c.GPIO_Mode=GPIO_Mode_OUT;
    c.GPIO_Speed=GPIO_High_Speed;
    c.GPIO_PuPd=GPIO_PuPd_NOPULL;
    c.GPIO_OType=GPIO_OType_PP;
    
    c.GPIO_Pin=GPIO_Pin_0;//D0-C12-C11-C10
    GPIO_Init(GPIOD, &c);
    c.GPIO_Pin=GPIO_Pin_12;
    GPIO_Init(GPIOC, &c);
    c.GPIO_Pin=GPIO_Pin_11;
    GPIO_Init(GPIOC, &c);
    c.GPIO_Pin=GPIO_Pin_10;
    GPIO_Init(GPIOC, &c);

}    


        /*********时钟使能************/
void clc_enable()
{
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);//A使能
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);//C使能
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE);//D使能
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);//E使能

    /***************定时器使能***************/
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE);//TIMR6
}

void TIM6_DAC_IRQHandler(void)
{
    if (TIM_GetITStatus(TIM6,TIM_IT_Update) != RESET)//确保进入中断
      {
    TIM_ClearITPendingBit(TIM6,TIM_IT_Update);//清除中断标志位
        timer_flag=1;
        
     }
}

使用的是STM32F4,使用标准库在MDK上编程,开发板的接口没有问题,GPIO和一些中断还设置了一些其他的应该不影响计时器
主要的问题是:timer_flag=0;这一句,如果放在函数的开头,可以正常计时,现象是开始灯亮经过了准确的时间然后灯灭了,但是如果放在函数末尾,不能正常计时,现象是灯迅速亮灭——肉眼看实际是一直灭的,经过测试两种情况都进入了中断

  • 写回答

1条回答 默认 最新

  • 少林and叔叔 2023-05-30 10:28
    关注

    指的是delay_ms函数里的这个吗?

    评论

报告相同问题?

问题事件

  • 创建了问题 5月30日

悬赏问题

  • ¥20 关于web前端如何播放二次加密m3u8视频的问题
  • ¥20 spring boot集成mqtt的使用问题
  • ¥15 使用百度地图api 位置函数报错?
  • ¥15 metamask如何添加TRON自定义网络
  • ¥66 关于川崎机器人调速问题
  • ¥15 winFrom界面无法打开
  • ¥30 crossover21 ARM64版本安装软件问题
  • ¥15 mymetaobjecthandler没有进入
  • ¥15 mmo能不能做客户端怪物
  • ¥15 osm下载到arcgis出错