chakokuのブログ(rev4)

日々のごった煮ブログです

STEVAL-DRONE01のモータを動かしてみる

動作確認のため、GPIOを操作してSTEVAL-DRONE01のモータを動かしてみる。回路図を見ると、モータはGPIOB_6~9に接続されたFETで制御されていると理解。ただ、、回路図を読んでもなぜこれでモータの電圧が制御できるのか、チト理解できず。とにかく、GPIOB8-9をOn/Offすればモータが制御できるのだろうと推測して、4つのGPIOを操作するテストプログラムを作成。以下の内容で作って、OpenOCD+gdbでDRONE01の制御基板のSTM32F401CCのFlashにテストプログラムを書き込んでテスト実施。結果モータが一つずつ動作することを確認

モータが動いたのはいいけど、、回路図では、VBAT(バッテリーから供給される電源)でモータやらFETが動くようなのだが、シリアルデバッグから供給される3.3V(回路図上でVDD)でモータが動いている。。これでいいのか??(U6 LD39015M33RのOUTからVDD(3.3)が加圧され、それがVBATに流れている??)

/*
 * Drone Motor Test (STEVAL-DRONE01)
 *
 */
#include <stdint.h>

#define GPIOB          0x40020400ul 
                   
#define GPIOB_MODER    (*(uint32_t *)(GPIOB+0x00ul))
#define GPIOB_OSPEEDER (*(uint32_t *)(GPIOB+0x08ul))
#define GPIOB_PUPDR    (*(uint32_t *)(GPIOB+0x0cul))
#define GPIOB_ODR      (*(uint32_t *)(GPIOB+0x14ul))
#define GPIOB_BSRR     (*(uint32_t *)(GPIOB+0x18ul))
#define GPIOB_LCKR     (*(uint32_t *)(GPIOB+0x1Cul))
#define GPIOB_AFRL     (*(uint32_t *)(GPIOB+0x20ul))
#define GPIOB_AFRH     (*(uint32_t *)(GPIOB+0x24ul))

#define RCC_BASE       0x40023800ul
#define RCC_AHB1ENR    (*(uint32_t *)(RCC_BASE + 0x30ul))
#define GPIOBEN        0x01 << 1   // GPIO_B:bit1

#define GPIOB_6 6
#define GPIOB_7 7
#define GPIOB_8 8
#define GPIOB_9 9

#define MOTOR_M1 1
#define MOTOR_M2 2
#define MOTOR_M3 3
#define MOTOR_M4 4

#define DELAY_TIME 300000

void wait(int delay_time);
void setup_motor(void);
void motor_on(int);
void motor_off(int);

void main()
{

  setup_motor();

  while(1){
    motor_on(MOTOR_M1);
    wait(DELAY_TIME);
    motor_off(MOTOR_M1);
    wait(DELAY_TIME);
    motor_on(MOTOR_M2);
    wait(DELAY_TIME);
    motor_off(MOTOR_M2);
    wait(DELAY_TIME);
    motor_on(MOTOR_M3);
    wait(DELAY_TIME);
    motor_off(MOTOR_M3);
    wait(DELAY_TIME);
    motor_on(MOTOR_M4);
    wait(DELAY_TIME);
    motor_off(MOTOR_M4);
    wait(DELAY_TIME);
  }

  // infinit loop
  while(1)
    ;
}

void setup_motor(void){

  // provide clock to GPIOB Block
  RCC_AHB1ENR |= 0x1 << 1; // Enable clocks to GPIOB   (p118)

  // setup GPIOB
  GPIOB_MODER |= (0x01 << (GPIOB_6 * 2));     // set GPIOB_6 as General Output
  GPIOB_MODER |= (0x01 << (GPIOB_7 * 2));     // set GPIOB_7 as General Output
  GPIOB_MODER |= (0x01 << (GPIOB_8 * 2));     // set GPIOB_8 as General Output
  GPIOB_MODER |= (0x01 << (GPIOB_9 * 2));     // set GPIOB_9 as General Output

  //use default setting so skip set register
  //GPIOB_OTYPER |= (0x0 << GPIOB_6 );        // set GPIOB_6 as PuhshPull
  //GPIOB_OSPEEDR |= (0x01 << (GPIOB_6 * 2)); // set GPIOB_6 as Medimu

}

void motor_on(int motor){

  switch(motor){
  case MOTOR_M1:
    GPIOB_ODR |= (1 << GPIOB_6);
    break;
  case MOTOR_M2:
    GPIOB_ODR |= (1 << GPIOB_7);
    break;
  case MOTOR_M3:
    GPIOB_ODR |= (1 << GPIOB_8);
    break;
  case MOTOR_M4:
    GPIOB_ODR |= (1 << GPIOB_9);
    break;
  default:
    // internal Error
    ;
  }
}

void motor_off(int motor){

  switch(motor){
  case MOTOR_M1:
    GPIOB_ODR &= ~(1 << GPIOB_6);
    break;
  case MOTOR_M2:
    GPIOB_ODR &= ~(1 << GPIOB_7);
    break;
  case MOTOR_M3:
    GPIOB_ODR &= ~(1 << GPIOB_8);
    break;
  case MOTOR_M4:
    GPIOB_ODR &= ~(1 << GPIOB_9);
    break;
  default:
    // internal Error
    ;
  }
}

void wait(int delay_time){
  unsigned int i = delay_time;
  while(i--){
    asm("nop");
  }
}