動作確認のため、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");
}
}