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