一、硬件方面:
板卡为专用电机驱动板,因此底板加了一块散热片,开发板的四脚加了脚垫,以便更好地散热,防止底板电路与金属物件接触而导致短路。开发板采用ARM Cortex-M0的32位MCU,MCU最高工作频率可达72MHz,内置高速存储器,丰富的I/O 端口和外设连接到外部总线。具有1个12位的ADC、1个比较器、1个16位通用定时器、1个32位通用定时器、3个16位基本定时器和1个16位高级定时器。还包含标准的通信接口,即1个I2C接口、1个SPI接口和1个UART接口。适合开发吊风扇,电动工具,三相永磁无刷电机等多种应用场合。
由MM32SPIN160C的名称可知该型号的基础配置
开发板主要功能列表:
①、输入电压范围: 12V~28V
②、使用60V/40A N-MOS管*6
③、使用外挂(SPIN0x) GBW 6MHz 高速运放*4
④、MCU 电源使用5V
⑤、支持有/无霍, 方波/弦波驱动
⑥、支持1/2 Shunt R 三相电流采样
⑦、BEMF 电压回授使用ADC 采样
⑧、DC Bus 电压, 总电流量测
⑨、使用MCU 内建比较器做为过电流保护
在淘宝上买了个尼得科无刷电机,无刷电机最大优点是没有碳刷转换器,寿命长,适合长时间工作的场所。
【额定电压】DC 12V
【空载电流】1A
【额定功率】10W
【空载转速】12000转/分钟
【适合电压】6-12V(6000-12000转)
【重量】130克
电机的接口线路如下图所示:
二、电路图方面
关于该开发板的PCBA点位图如下:
开发板的电路原理图如下:
三、开发环境方面
板上集成了JLink调试接口,支持串行调试(SWD),官方提供的资源包中包括基本工程示例,可使用IAR、MDK工具打开,本人习惯使用MDK,因此将基本工程示例导入进Keil中,如果电脑联网,此时会提示安装“MindMotion.MM32SPIN0x_DFP.1.0.8”pack包;如果电脑处于离线状态,可从灵动微官网下载基于MM32SPIN160C开发板的pack包,如下附件,然后将pack导入Keil工具中,而后直接编译即可。
2021-12-19 22:55 上传
点击文件名下载附件
将JLink烧录器与开发板上的CN7接口相连接,Keil中设置SWD模式,即可识别到调试器,并设置烧录后自动重启。
然后将开发板上CN1、CN2、CN3与电机、电源适配器正确连接,由于板卡支持12~28V的电压输入,而电机的额定电压是12V,因此采用12V/1A的电源适配器,实物连线图如下:
采用不带霍尔的轮询控制方式,直接烧录后,电机起震,没有如期得向逆时针或顺时针旋转,现象如同是前进两步后退两步,一直在抖动。在线调试,发现驱动换相函数存在问题,每种无刷电机的接线有所差异。关于BLDC电机,推荐看看TI的技术视频教程深入理解无刷直流电机(BLDC)原理以及控制,关于有刷电机与无刷电机的工作原理如下:
由上图,有刷电机的主要结构就是定子+转子+电刷,通过旋转磁场获得转动力矩,从而输出动能。电刷与换向器不断接触摩擦,在转动中起到导电和换相作用。有刷电机采用机械换向,磁极不动,线圈旋转。电机工作时,线圈和换向器旋转,磁钢和碳刷不转,线圈电流方向的交替变化是随电机转动的换相器和电刷来完成的。
由上图,无刷电机中,换相的工作交由控制器中的控制电路(一般为霍尔传感器+控制器,更先进的技术是磁编码器)来完成。无刷电机采取电子换向,线圈不动,磁极旋转。无刷电机,是使用一套电子设备,通过霍尔元件,感知永磁体磁极的位置,根据这种感知,使用电子线路,适时切换线圈中电流的方向,保证产生正确方向的磁力,来驱动电机,消除了有刷电机的缺点。
四、工程源码
部分源码如下:
- #include "sys.h"
- typedef enum {
- CW = 0, // 顺时钟方向
- CCW = 1 // 逆时针方向
- } motor_dir_t;
- typedef enum {
- START = 0, // 启动
- STOP = 1, // 停机
- RUN = 2 // 运行
- } motor_state_t;
- typedef struct{
- motor_dir_t tMotorDirection; // 电机旋转方向
- motor_state_t tMotorState; // 电机状态
- uint16_t tDuty; // 速度占空比:0~100 为100是占空比为100%
- uint16_t tSpeed; // 电机转速
- uint8_t chHallValue; // 霍尔状态
- struct{
- uint8_t chStartCount; // 启动计数
- uint16_t hwTimeCount; // 堵转超时溢出计数
- }tCount;
- }User_TypeDef_t;
- volatile User_TypeDef_t g_tMotor = {
- CW,
- START,
- 40,
- 0,
- 1,
- 0,
- 0
- };
- extern void Bldc_Phase_Chaneg(uint8_t step);
- extern void Hall_Exti_Callback(void);
- extern void Systick_Callback(void);
- int main(void)
- {
- Systick_Init();
- Led_Init();
- Hall_Init();
- Bldc_Pwm_Init();
- Gate_Driver_Init();
- while(1) {
- switch(g_tMotor.tMotorState) {
- case START: // 电机启动
- if(++g_tMotor.tCount.chStartCount > 20){ //电机启动失败
- g_tMotor.tMotorState = STOP;
- g_tMotor.tCount.chStartCount = 0;
- }
- SET_DUTY_U(BLDC_TIM_PERIOD * g_tMotor.tDuty / 100);
- SET_DUTY_V(BLDC_TIM_PERIOD * g_tMotor.tDuty / 100);
- SET_DUTY_W(BLDC_TIM_PERIOD * g_tMotor.tDuty / 100);
- GATE_DRIVER_ENABLE();
- Hall_Exti_Callback();
- Systick_Delay(5);
- break;
- case RUN: // 电机运行
- if (0){//some err
- g_tMotor.tMotorState = STOP;
- }
- Hall_Exti_Callback();
- break;
- case STOP: // 停机
- GATE_DRIVER_DISABLE();
- BLDC_UH_DISABLE();
- BLDC_UL_DISABLE();
- BLDC_VH_DISABLE();
- BLDC_VL_DISABLE();
- BLDC_WH_DISABLE();
- BLDC_WL_DISABLE();
- break;
- }
- }
- }
- void Bldc_Phase_Chaneg(uint8_t step)
- {
- Systick_Delay(5); //为了更好得看清楚,稍加延时
- switch(step) {
- case 3: //A+ C-
- BLDC_UH_ENABLE();
- BLDC_UL_DISABLE();
- BLDC_VH_DISABLE();;
- BLDC_VL_DISABLE();
- BLDC_WH_DISABLE();
- BLDC_WL_ENABLE();
- break;
- case 1: //B+ C-
- BLDC_UH_DISABLE();
- BLDC_UL_DISABLE();
- BLDC_VH_ENABLE();
- BLDC_VL_DISABLE();
- BLDC_WH_DISABLE();
- BLDC_WL_ENABLE();
- break;
- case 5: //B+ A-
- BLDC_UH_DISABLE();
- BLDC_UL_ENABLE();
- BLDC_VH_ENABLE();
- BLDC_VL_DISABLE();
- BLDC_WH_DISABLE();
- BLDC_WH_DISABLE();
- break;
- case 4: //C+ A-
- BLDC_UH_DISABLE();
- BLDC_UL_ENABLE();
- BLDC_VH_DISABLE();
- BLDC_VL_DISABLE();
- BLDC_WH_ENABLE();
- BLDC_WL_DISABLE();
- break;
- case 6: //C+ B-
- BLDC_UH_DISABLE();
- BLDC_UL_DISABLE();
- BLDC_VH_DISABLE();
- BLDC_VL_ENABLE();
- BLDC_WH_ENABLE();
- BLDC_WL_DISABLE();
- break;
- case 2: //A+ B-
- BLDC_UH_ENABLE();
- BLDC_UL_DISABLE();
- BLDC_VH_DISABLE();
- BLDC_VL_ENABLE();
- BLDC_WH_DISABLE();
- BLDC_WL_DISABLE();
- break;
- default:
- BLDC_UH_DISABLE();
- BLDC_UL_DISABLE();
- BLDC_VH_DISABLE();
- BLDC_VL_DISABLE();
- BLDC_WH_DISABLE();
- BLDC_WL_DISABLE();
- break;
- }
- }
- void Systick_Callback(void)
- {
- if(RUN == g_tMotor.tMotorState) {
- g_tMotor.tCount.hwTimeCount ++;
- if(g_tMotor.tCount.hwTimeCount > 2000) { // 2s超时,电机卡住不运转超过2s时间
- GATE_DRIVER_DISABLE();
- BLDC_UH_DISABLE();
- BLDC_UL_DISABLE();
- BLDC_VH_DISABLE();
- BLDC_VL_DISABLE();
- BLDC_WH_DISABLE();
- BLDC_WL_DISABLE();
- g_tMotor.tMotorState = STOP;
- g_tMotor.tCount.hwTimeCount = 0;
- }
- }
- }
- void Hall_Exti_Callback(void)
- {
- volatile uint8_t chStep = 0;
- // chStep = (uint8_t)((HALL_PORT_U->IDR >> HALL_PINSOURCE_U) |
- // (HALL_PORT_V->IDR >> (HALL_PINSOURCE_V - 1)) |
- // (HALL_PORT_W->IDR >> (HALL_PINSOURCE_W - 2))) & 0x07;
- if(g_tMotor.tMotorState == STOP) {
- return;
- }
- if((HALL_PORT_U ->IDR & HALL_PIN_U) != (uint32_t)Bit_RESET) {
- chStep |= 0x01;
- }
- if((HALL_PORT_V ->IDR & HALL_PIN_V) != (uint32_t)Bit_RESET) {
- chStep |= 0x02;
- }
- if((HALL_PORT_W ->IDR & HALL_PIN_W) != (uint32_t)Bit_RESET) {
- chStep |= 0x04;
- }
- if (g_tMotor.chHallValue != chStep) { //判断是否换向
- g_tMotor.tMotorState = RUN;
- g_tMotor.chHallValue = chStep ;
- }
- if(g_tMotor.tMotorDirection == CCW) { // 方向判断
- chStep = 7 - chStep;
- }
- Bldc_Phase_Chaneg(chStep); //驱动换相
- g_tMotor.tCount.hwTimeCount = 0;
- }
2021-12-20 00:36 上传
点击文件名下载附件
继续阅读本篇相关更多标签
全部回复 2
评测文章
热帖
大家都在看的技术资料
举报
内容系网友发布,其中涉及到安全隐患的内容系网友个人行为,不代表面包板社区观点
关闭
站长推荐 /3
- 返回顶部
工具栏