我的小车有4个模式,是通过按键进行切换,按下按键,模式+1,每个模式所执行的程序在while1循环中通过if进行条件判断当前是哪种模式,并在oled中以mode:x的形式显示,但是现在如果烧录整个程序的话,按键按一下就只会跳到模式1,然后oled屏幕的显示就像是卡住了一样,继续按按键mode本来应该会从模式1 到模式2,可现在还是显示moed:1,但是mode的累加是在按键中断函数中执行的,我在中断函数中放了一个led的翻转语句,发现led是可以正常翻转,说明是进的去中断,但是就是不会跳到模式2,while中4个if分别对应mode1~4,mode1定距离跟随,mode2是蓝牙遥控,mode3超声波避障,mode4红外对管循迹,我如果把mode1和mode3屏蔽掉,按键就能按到mode4,然后再按就卡住,如果我把mode1-4分别设置为前进,后退,左转,右转,则按键能很顺利的切换模式
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "Key.h"
#include "LED.h"
#include "Exti.h"
#include "TrackSensor.h"
#include "Motor.h"
#include "PWM.h"
#include "OLED.h"
#include "ADC.h"
#include "SR04.h"
#include "Usart.h"
int Mode=0;
int time=0;
int Distance = 0;
//uint8_t RxData;
extern uint8_t Capture_state;
extern uint16_t Capture_value;
extern char Serial_RxData;
extern int Serial_RxFlag;
extern int Serial3_RxFlag;
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
Usart_Init();
Usart3_Init();
LED_Init();
Motor_Init();
Exti_Init();
TrackSensor_Init();
OLED_Init();
OLED_Clear();
Key_Init();
TrigA0_Init();//超声波PA0
EchoA1_Init(0xFFFF,72-1);//超声波PA1
AD_Init();
TIM3_PWM_Init(999,1439);//舵机初始化72 000 000/预分频psc1440/arr100=50hz
PWM_Init(1999,359);//直流电机初始化72 000 000 /预分频psc360/arr2000=100hz
while(1)
{
uint16_t ADValue;
float Voltage;
//显示距离功能
OLED_ShowString(1,1,"Distance:");
OLED_ShowNum(1,10,SR04_Distance(),2);
//显示电压
OLED_ShowString(2, 1, "Voltage:0.00V");
ADValue = AD_GetValue();
Voltage = (float)ADValue/4095*3.3;
OLED_ShowNum(2,9,Voltage,1);
OLED_ShowNum(2,11,(uint16_t)(Voltage*100)%100,2);
//显示模式
OLED_ShowString(3,1,"Mode:");
OLED_ShowNum(3,6,Mode,1);
if(Mode == 0)//定距离跟随
{
Stop();
}
if(Mode == 1)//定距离跟随
{
if(SR04_Distance()>20)
{
Forward();
Delay_ms(50);
}
if(SR04_Distance()<15)
{
Backward();
Delay_ms(50);
}
Stop();
}
if(Mode == 2)//蓝牙遥控
{
if(Serial3_RxFlag==5)
{
LED13_Turn();
Stop();
}
if(Serial3_RxFlag==1)
{
LED13_Turn();
Forward();
Delay_ms(100);
}
if(Serial3_RxFlag==2)
{
LED13_Turn();
Backward();
Delay_ms(100);
}
if(Serial3_RxFlag==3)
{
LED13_Turn();
Rightward();
Delay_ms(100);
}
if(Serial3_RxFlag==4)
{
LED13_Turn();
Leftward();
Delay_ms(100);
}
}
if(Mode == 3)//超声波避障
{
TIM_SetCompare1(TIM3,80);//前
Delay_ms(500);
if(SR04_Distance()>25)//前方无障碍
{
Forward();
Delay_ms(500);
}
if(SR04_Distance()<25)
{
TIM_SetCompare1(TIM3,45);//舵机右转30度
Delay_ms(200);
if(SR04_Distance()>25)//右侧无障碍物
{
Rightward();
Delay_ms(700);
}
else
{
TIM_SetCompare1(TIM3,115);//舵机左转30度
Delay_ms(200);
if(SR04_Distance()>25)
{
Leftward();
Delay_ms(700);
}
else
{
Backward();
Delay_ms(700);
Rightward();
Delay_ms(700);
}
}
}
}
if(Mode == 4)//红外循迹
{
if(HW_1==0&&HW_2==0&&HW_3==0&&HW_4==0)
{
Forward();
Delay_ms(50);
}
if(HW_1==0&&HW_2==1&&HW_3==0&&HW_4==0)//PB4
{
Rightward();
Delay_ms(150);
}
if(HW_1==1&&HW_2==0&&HW_3==0&&HW_4==0)//PB5
{
Rightward();
Delay_ms(180);
}
if(HW_1==0&&HW_2==0&&HW_3==1&&HW_4==0)//PB3
{
Leftward();
Delay_ms(175);
}
if(HW_1==0&&HW_2==0&&HW_3==0&&HW_4==1)//PA15
{
Leftward();
Delay_ms(175);
}
}
}
}
#include "stm32f10x.h" // Device header
#include "LED.h"
#include "Motor.h"
#include "Delay.h"
extern int Mode;
void Exti_Init(void)
{
EXTI_InitTypeDef EXTI_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
//PA12 下降沿触发
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource12);
EXTI_InitStruct.EXTI_Line = EXTI_Line12;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_Init(&EXTI_InitStruct);
//PA7 上升沿触发
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource7);
EXTI_InitStruct.EXTI_Line = EXTI_Line7;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_Init(&EXTI_InitStruct);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 3;
NVIC_Init(&NVIC_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStruct);
}
按键PA7的中断服务函数
void EXTI9_5_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line7)==SET)
{
Delay_ms(10);
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)==1)//检测暗示是否按下
{
if(Mode==4)
{
Mode=1;
}
else
{
Mode = Mode+1;
}
LED13_Turn();
}
EXTI_ClearITPendingBit(EXTI_Line7);
}
}
按键PA12的中断服务函数
void EXTI15_10_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line12)==SET)//这个是按键通过中断控制led的翻转
{
Delay_ms(10);
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_12)==0)//检测暗示是否按下
{
Mode = 0;
LED13_Turn();
}
EXTI_ClearITPendingBit(EXTI_Line12);
}
}