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;这一句,如果放在函数的开头,可以正常计时,现象是开始灯亮经过了准确的时间然后灯灭了,但是如果放在函数末尾,不能正常计时,现象是灯迅速亮灭——肉眼看实际是一直灭的,经过测试两种情况都进入了中断