개발환경 : stm32cubeide, stm32f4 개발보드, hal 라이브러리
https://github.com/mokhwasomssi/stm32f4_hal_dshot
매우 간단하게 코드를 짰다.
원래는 이것저것 넣으려고 했지만
모터는 잘 돌아가는 것 같아서 나중에 필요할 때 넣기로 했다.
dshot600
속도 제어만 가능 (48 - 2000 throttle)
다른 명령 안됨 (led, 방향 바꾸기, 등등등)
값 넣으면 속도는 잘 바뀌는데 다른 명령이 적용이 안되는 걸로 봐서
아마 다른 절차가 있는 것 같다.
소스코드
dshot.h
#ifndef _DSHOT_H_
#define _DSHOT_H_
#include "stm32f4xx_hal.h"
#include <stdbool.h>
#define MOTOR_BIT_0 7
#define MOTOR_BIT_1 14
#define MOTOR_BITLENGTH 20
#define DSHOT_FRAME_SIZE 18 // 0-15 : dshot frame, 16-17 : reset
void dshot600(uint32_t *motor, uint16_t value);
#endif /* _DSHOT_H_ */
dshot.c
#include "dshot.h"
void dshot600(uint32_t *motor, uint16_t value)
{
uint16_t packet = value << 1;
// compute checksum
int csum = 0;
int csum_data = packet;
for (int i = 0; i < 3; i++) {
csum ^= csum_data; // xor data by nibbles
csum_data >>= 4;
}
csum &= 0xf;
// append checksum
packet = (packet << 4) | csum;
// encoding
int i;
for (i = 0; i < 16; i++)
{
motor[i] = (packet & 0x8000) ? MOTOR_BIT_1 : MOTOR_BIT_0; // MSB first
packet <<= 1;
}
motor[i++] = 0;
motor[i++] = 0;
}
main.c
...
#include "dshot.h"
...
uint32_t motor1[DSHOT_FRAME_SIZE]; // dshot data frame array transmitted through DMA
uint16_t value = 0; // need to keep value = 0 for a while after power on
...
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim == &htim11)
{
dshot600(motor1, value);
HAL_TIM_PWM_Start_DMA(&htim2, TIM_CHANNEL_1, motor1, 18);
}
}
...
int main(void)
{
...
HAL_TIM_Base_Start_IT(&htim11); // timer interrupt 1kHz
...
}
...
STM32CubeMX TIM, DMA 설정
TIM
베타플라이트 디샷 코드의 프리스케일러는 계산은 이렇다.
// src > main > drivers > pwm_output_dshot_hal.c
Prescaler = (uint16_t)(lrintf((float) timerClock(timer) / getDshotHz(pwmProtocolType) + 0.01f) - 1);
대충 이렇게 구하면 된다.
프리스케일러 = 사용하는 타이머 클럭 속도 / 디샷 클럭 속도 - 1
TIM2 클럭 속도 : 100Mhz
Dshot600 클럭 속도 : 12Mhz
프리스케일러 : 8.33333 ≒ 8 - 1
DMA
왜 이런 설정을 쓰는지는 잘 모르겠지만 나중에 알아보도록 하자.
코드는 베타플라이트 깃헙과 MGeo 씨의 코드를 참고했다.
https://github.com/betaflight/betaflight
https://forum.arduino.cc/index.php?topic=624454.0
MGeo씨가 tim, dma 설정 다 찾아준 덕에 수월하게 할 수 있었다.