OpenEdv-开源电子网

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

求大神帮忙!想用usmart来调试平衡小车,但是好像和外部中断有冲突,使得usmart无法使用!!请大神指导不胜感激。

[复制链接]

1

主题

1

帖子

0

精华

限制会员

积分
-2
金钱
-2
注册时间
2018-2-2
在线时间
3 小时
发表于 2018-2-5 18:43:51 | 显示全部楼层 |阅读模式
10金钱
1.注释掉外部中断初始化函数  MiniBalance_EXTI_Init() 后,usmart可正常使用,如下图:

2.但是如果不注释掉函数 MiniBalance_EXTI_Init()  就用不了,发送多条,才接受几条,如下图

3.其中主函数、 MiniBalance_EXTI_Init()函数代码、和中断函数执行程序:
[C] [color=rgb(51, 102, 153) !important]纯文本查看 [color=rgb(51, 102, 153) !important]复制代码
[color=white !important]
[color=white !important]?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

int main(void)
  {
        delay_init();                       //=====延时函数初始化  
        uart_init(128000);              //=====串口初始化为
        JTAG_Set(JTAG_SWD_DISABLE);     //=====关闭JTAG接口
        JTAG_Set(SWD_ENABLE);           //=====打开SWD接口 可以利用主板的SWD接口调试
        usmart_init(72);                 //=====按键初始化
    MiniBalance_PWM_Init(7199,0);   //=====初始化PWM 10KHZ,用于驱动电机 如需初始化电调接口
//      uart3_init(9600);               //=====串口3初始化
    Encoder_Init_TIM2();            //=====编码器接口
//    Encoder_Init_TIM4();            //=====初始化编码器2
    IIC_Init();                     //=====IIC初始化
    MPU6050_initialize();           //=====MPU6050初始化   
    DMP_Init();                     //=====初始化DMP
//    OLED_Init();                    //=====OLED初始化        
//      TIM3_Cap_Init(0XFFFF,72-1);     //=====超声波初始化
      MiniBalance_EXTI_Init();        //=====MPU6050 5ms定时中断初始化
    while(1)
       {   
//      printf("平衡 倾角  %f \r\n左轮编码器%d \r\n右轮编码器%d \r\n 角速度  %f \r\n",Angle_Balance,Encoder_Left,Encoder_Right,Gyro_Balance);//向串口调试助手发送数据
            delay_ms(50);
         }
}





[C] [color=rgb(51, 102, 153) !important]纯文本查看 [color=rgb(51, 102, 153) !important]复制代码
[color=white !important]
[color=white !important]?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

/**************************************************************************
函数功能:外部中断初始化
入口参数:无
返回  值:无
**************************************************************************/
void MiniBalance_EXTI_Init(void)
{  
        GPIO_InitTypeDef GPIO_InitStructure;
        EXTI_InitTypeDef EXTI_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//外部中断,需要使能AFIO时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB端口时钟
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;               //端口配置
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;         //上拉输入
        GPIO_Init(GPIOB, &GPIO_InitStructure);                        //根据设定参数初始化GPIOB
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource5);
    EXTI_InitStructure.EXTI_Line=EXTI_Line5;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);     //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
        NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;          //使能按键所在的外部中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;    //抢占优先级2,
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;                   //子优先级1
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                             //使能外部中断通道
    NVIC_Init(&NVIC_InitStructure);
}

/**************************************************************************
函数功能:所有的控制代码都在这里面
         5ms定时中断由MPU6050的INT引脚触发
         严格保证采样和数据处理的时间同步               
**************************************************************************/
int EXTI9_5_IRQHandler(void)
{   
     if(INT==0)     
    {   
          EXTI->PR=1<<5;                                                      //清除LINE5上的中断标志位   
           Flag_Target=!Flag_Target;
//        if(delay_flag==1)
//           {
//               if(++delay_50==10)  delay_50=0,delay_flag=0;                     //给主函数提供50ms的精准延时
//           }
          if(Flag_Target==1)                                                  //5ms读取一次陀螺仪和加速度计的值,更高的采样频率可以改善卡尔曼滤波和互补滤波的效果
            {
            Get_Angle(Way_Angle);                                               //===更新姿态   
            return 0;                                                  
            }                                                                   //10ms控制一次,为了保证M法测速的时间基准,首先读取编码器数据
            usmart_scan();
            Encoder_Left=-Read_Encoder(2);                                      //===读取编码器的值,因为两个电机的旋转了180度的,所以对其中一个取反,保证输出极性一致
            Encoder_Right=Read_Encoder(4);                                      //===读取编码器的值
        Get_Angle(Way_Angle);                                               //===更新姿态   
//          Read_Distane();                                                     //===获取超声波测量距离值
//          if(Bi_zhang==0)Led_Flash(100);                                      //===LED闪烁;常规模式 1s改变一次指示灯的状态   
//          if(Bi_zhang==1)Led_Flash(0);                                        //===LED闪烁;避障模式 指示灯常亮   
//          Voltage=Get_battery_volt();                                         //===获取电池电压           
//          Key();                                                              //===扫描按键状态 单击双击可以改变小车运行状态

            Balance_Pwm =balance(Angle_Balance,Gyro_Balance);                   //===平衡PID控制   
          Velocity_Pwm=velocity(Encoder_Left,Encoder_Right);                  //===速度环PID控制  记住,速度反馈是正反馈,就是小车快的时候要慢下来就需要再跑快一点

//      Turn_Pwm    =turn(Encoder_Left,Encoder_Right,Gyro_Turn);            //===转向环PID控制     
          Moto1=Balance_Pwm-Velocity_Pwm+Turn_Pwm;                            //===计算左轮电机最终PWM
        Moto2=Balance_Pwm-Velocity_Pwm-Turn_Pwm;                            //===计算右轮电机最终PWM
        Xianfu_Pwm();                                                       //===PWM限幅
//          if(Pick_Up(Acceleration_Z,Angle_Balance,Encoder_Left,Encoder_Right))//===检查是否小车被那起
//          Flag_Stop=1;                                                          //===如果被拿起就关闭电机
//          if(Put_Down(Angle_Balance,Encoder_Left,Encoder_Right))              //===检查是否小车被放下
//          Flag_Stop=0;                                                          //===如果被放下就启动电机
      if(Turn_Off(Angle_Balance)==0)                              //===如果不存在异常
            Set_Pwm(Moto1,Moto2);                                               //===赋值给PWM寄存器  
    }           
     return 0;   
}





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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2018-2-6 01:04:34 | 显示全部楼层
usmart是通过中断执行的,所以,你必须让usmart有周期的中断发生。
另外,usmart接收数据也是通过中断接收的,如果接收过程,被你中断频繁打断,有可能接收不完整。
所以,可以提高串口中断优先级,尝试看能不能解决。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

6

主题

21

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2018-7-26
在线时间
20 小时
发表于 2019-12-22 17:04:01 | 显示全部楼层
您好,楼主,你解决了这个问题吗?
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-21 10:14

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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