wnsdgza 发表于 2023-5-21 19:11:15

百思不得其解,刚买的平衡车,断电重启的行为和重烧代码的行为不一致。需要大佬指点。

如题所描述,我执行以下步骤
1、编译代码
2、将代码烧录至机器中
3、观察机器,可以看到机器左右轮都在正常转动。
4、断电。
5、给机器供电。
6、机器只有左边电机可以转动,右边电机不转。
附上写的代码。
mian:

```
#include "main.h"
void vSpeedComputation(void)
{
    static uint32_t pre_time = 0;
    static uint32_t print_time_tick = 0;
    static float left_speed,right_speed;
    System_TimeTick_t cur_time;
    cur_time = TIMETICK_BASE;
    if(pre_time == 0)
    {
      pre_time = cur_time.uwSystem_TimeTick_m;
      return;
    }
    if(cur_time.uwSystem_TimeTick_m - pre_time >= 5)
    {
      int leftcount,rightcount;
      pre_time =cur_time.uwSystem_TimeTick_m;
      leftcount = -vEncoder_ReadSpeed(LEFT_PULSECONTER);
      rightcount = -vEncoder_ReadSpeed(RIGHT_PULSECONTER);
      left_speed = leftcount * WHEEL_PULSECOUNT_TO_SPEED;
      right_speed = rightcount * WHEEL_PULSECOUNT_TO_SPEED;
    }
    if(cur_time.uwSystem_TimeTick_s > print_time_tick + 5)
    {
      print_time_tick = cur_time.uwSystem_TimeTick_s;
      printf("l_speed = %f, r_speed = %f\r\n",left_speed,right_speed);
    }
}
int PWM = 5000;
int main(void)
{
      vUart_init(DEBUG_USART_BAUDRATE);
      //vSysTick_Init();
      vMotor_Init();
      //vEncoder_init();
      MOTOR_LEFT_PWMSET(PWM);
      MOTOR_RIGHT_PWMSET(PWM);
      MOTOR_LEFT_FRONT;
      MOTOR_RIGHT_FRONT;
      printf("Hello World!\r\n");
      while(1)
      {
            //vSpeedComputation();
      }
}


```
motor.c:
```
#include "bsp_motor.h"
static void vMotor_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    // 右轮PWM输出GPIO初始化
    RCC_APB2PeriphClockCmd(MOTOR_TIM_RIGHT_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin =MOTOR_TIM_RIGHT_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(MOTOR_TIM_RIGHT_PORT, &GPIO_InitStructure);
    // 右轮方向控制信号输出GPIO初始化
    RCC_APB2PeriphClockCmd(MOTOR_DIR_RIGHT_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin =MOTOR_DIR_RIGHT_PIN1 | MOTOR_DIR_RIGHT_PIN2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(MOTOR_DIR_RIGHT_PORT, &GPIO_InitStructure);
    // 左轮PWM输出GPIO初始化
    RCC_APB2PeriphClockCmd(MOTOR_TIM_LEFT_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin =MOTOR_TIM_LEFT_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(MOTOR_TIM_LEFT_PORT, &GPIO_InitStructure);
    // 左轮方向控制信号输出GPIO初始化
    RCC_APB2PeriphClockCmd(MOTOR_DIR_LEFT_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin =MOTOR_DIR_LEFT_PIN1 | MOTOR_DIR_LEFT_PIN2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(MOTOR_DIR_LEFT_PORT, &GPIO_InitStructure);
    MOTOR_RIGHT_DISABLE;
    MOTOR_LEFT_DISABLE;
}
static void vMotor_TIM_Config(void)
{
   // 开启定时器时钟,即内部时钟CK_INT=72M
    MOTOR_TIM_APBxClock_FUN(MOTOR_TIM_CLK,ENABLE);

/*--------------------时基结构体初始化-------------------------*/
    TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
    // 自动重装载寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断
    TIM_TimeBaseStructure.TIM_Period = MOTOR_TIM_PERIOD;   
    // 驱动CNT计数器的时钟 = Fck_int/(psc+1)
    TIM_TimeBaseStructure.TIM_Prescaler = MOTOR_PSC;   
    // 时钟分频因子 ,配置死区时间时需要用到
    TIM_TimeBaseStructure.TIM_ClockDivision= TIM_CKD_DIV1;      
    // 计数器计数模式,设置为向上计数
    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;      
    // 重复计数器的值,没用到不用管
    TIM_TimeBaseStructure.TIM_RepetitionCounter=0;   
    // 初始化定时器
    TIM_TimeBaseInit(MOTOR_TIM, &TIM_TimeBaseStructure);

    /*--------------------输出比较结构体初始化-------------------*/      
    TIM_OCInitTypeDefTIM_OCInitStructure;
    // 配置为PWM模式1
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    // 输出使能
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    // 设置占空比大小
    TIM_OCInitStructure.TIM_Pulse = MOTOR_TIM_PULSE;
    // 输出通道电平极性配置
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    // 输出通道空闲电平极性配置
    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
    // 初始化外设
    TIM_OC1Init(MOTOR_TIM, &TIM_OCInitStructure);
    TIM_OC4Init(MOTOR_TIM, &TIM_OCInitStructure);
    // 预装载
    TIM_OC1PreloadConfig(MOTOR_TIM, TIM_OCPreload_Enable);
    TIM_OC4PreloadConfig(MOTOR_TIM, TIM_OCPreload_Enable);
   
    TIM_ARRPreloadConfig(MOTOR_TIM, ENABLE); //使能TIMx在ARR上的预装载寄存器
    // 使能计数器
    TIM_Cmd(MOTOR_TIM, ENABLE);   
}
void vMotor_Init(void)
{
    vMotor_GPIO_Config();
    vMotor_TIM_Config();
}

```
motor.h
```
#ifndef _BSP_MOTOR_H
#define _BSP_MOTOR_H
#include "stm32f10x.h"
#include "sysconfig.h"
/************高级定时器TIM参数定义,只限TIM1和TIM8************/
// 当使用不同的定时器的时候,对应的GPIO是不一样的,这点要注意
// 这里我们使用高级控制定时器TIM1

#define      MOTOR_TIM                   TIM1
#define      MOTOR_TIM_APBxClock_FUN   RCC_APB2PeriphClockCmd
#define      MOTOR_TIM_CLK               RCC_APB2Periph_TIM1
// PWM 信号的频率 F = TIM_CLK/{(ARR+1)*(PSC+1)}
#define      MOTOR_TIM_PERIOD            7199
#define      MOTOR_PSC                     0
#define      MOTOR_TIM_PULSE             0
      
#define      MOTOR_TIM_IRQ               TIM1_UP_IRQn
#define      MOTOR_TIM_IRQHandler      TIM1_UP_IRQHandler

// TIM1 左轮输出通道
#define      MOTOR_TIM_LEFT_GPIO_CLK   RCC_APB2Periph_GPIOA
#define      MOTOR_TIM_LEFT_PORT         GPIOA
#define      MOTOR_TIM_LEFT_PIN          GPIO_Pin_8
// DIR 左轮输出通道
#define      MOTOR_DIR_LEFT_GPIO_CLK            RCC_APB2Periph_GPIOB
#define      MOTOR_DIR_LEFT_PORT         GPIOB
#define      MOTOR_DIR_LEFT_PIN1                  GPIO_Pin_14
#define      MOTOR_DIR_LEFT_PIN2                  GPIO_Pin_15

// TIM1 右轮输出通道
#define      MOTOR_TIM_RIGHT_GPIO_CLK    RCC_APB2Periph_GPIOA
#define      MOTOR_TIM_RIGHT_PORT      GPIOA
#define      MOTOR_TIM_RIGHT_PIN         GPIO_Pin_11
// DIR 右轮输出通道
#define      MOTOR_DIR_RIGHT_GPIO_CLK      RCC_APB2Periph_GPIOB
#define      MOTOR_DIR_RIGHT_PORT      GPIOB
#define      MOTOR_DIR_RIGHT_PIN1                GPIO_Pin_12
#define      MOTOR_DIR_RIGHT_PIN2                GPIO_Pin_13

// 电机控制API
#define      MOTOR_RIGHT_PWMSET(x)                {if(x>=7199) x=7199;if(x<=0) x=0;MOTOR_TIM->CCR4 = x;}
#define      MOTOR_RIGHT_FRONT                        {PBOUT(15)=1,PBOUT(14)=0;}
#define      MOTOR_RIGHT_BACK                        {PBOUT(15)=0,PBOUT(14)=1;}
#define      MOTOR_RIGHT_BREAK                        {PBOUT(15)=1,PBOUT(14)=1;}
#define      MOTOR_RIGHT_DISABLE                  {PBOUT(15)=0,PBOUT(14)=0;}
      
#define      MOTOR_LEFT_PWMSET(x)                {if(x>=7199) x=7199;if(x<=0) x=0;MOTOR_TIM->CCR1 = x;}
#define      MOTOR_LEFT_FRONT                        {PBOUT(13)=1,PBOUT(12)=0;}
#define      MOTOR_LEFT_BACK                        {PBOUT(13)=0,PBOUT(12)=1;}
#define      MOTOR_LEFT_BREAK                        {PBOUT(13)=1,PBOUT(12)=1;}
#define      MOTOR_LEFT_DISABLE                  {PBOUT(13)=0,PBOUT(12)=0;}
/**************************函数声明********************************/

void vMotor_Init(void);
#endif

```


wnsdgza 发表于 2023-5-21 22:26:05

真的百思不得其解,移植完MUP6050的驱动后又可以正常跑了。明天拿逻辑分析抓一下看一下,我觉得是硬件上有干扰,定时器配置对比厂家源码检查了下寄存器,一模一样,并没有什么问题。唯一的区别在成功驱动MPU6050后PA12输入为高电平。当出现左轮不转时,PA12为低电平。受限于MPU6050的中断引脚,商家给的原理图太不全了,无力吐槽。

wnsdgza 发表于 2023-5-24 00:33:28

巨坑,led也是,还受不知名干扰。调试界面显示od寄存器输出为低电平,但是用表去量居然是高电平,会受到外部电路干扰。还没查出来。真的好坑,之前一直没点灯,现在发现灯都点不亮。

WHEELTEC-ZHS 发表于 2023-6-2 16:08:52

wnsdgza 发表于 2023-5-24 00:33
巨坑,led也是,还受不知名干扰。调试界面显示od寄存器输出为低电平,但是用表去量居然是高电平,会受到外 ...

只有点灯,不包含其它代码的情况下也是不亮吗

WHEELTEC-ZHS 发表于 2023-6-2 16:38:04

wnsdgza 发表于 2023-5-21 22:26
真的百思不得其解,移植完MUP6050的驱动后又可以正常跑了。明天拿逻辑分析抓一下看一下,我觉得是硬件上有 ...

可以先用资料里的代码稍微修改之后进行测试,我这边测试是没有问题的,电机都能够正常转动
页: [1]
查看完整版本: 百思不得其解,刚买的平衡车,断电重启的行为和重烧代码的行为不一致。需要大佬指点。