一、工程实现1.led模块仅实现状态指示这里不多做介绍。2.新建time_open_control模块驱动板使能管脚TIM4实现1ms中断一次time4_count计数TIM2输出3路25KHz PWMTIM2配置为中央对齐模式和向上计数模式模式频率计算不同频率 72M / ((预分频 1) × 2 × ARR )time_open_control.h#ifndef __TIME_OPEN_CONTROL_H #define __TIME_OPEN_CONTROL_H #include system.h //使用位带操作 #define PWM_Period 1440 //在BLDCMotor.c文件中TIM_SetCompare4(TIM2, Tc*PWM_Period)中会使用 #define MOTOR_ENABLE PCout(3) 1 #define MOTOR_DISABLE PCout(3) 0 extern uint32_t time4_count; void MOTOR_EN_PIN_Init(void); void TIM4_1MS_Init(void); void TIM2_CH1_CH3_CH4_PWM_Init(u16 per, u16 psc, u16 pulse1, u16 pulse2, u16 pulse3); #endiftime_open_control.c#include system.h #include time_open_control.h uint32_t time4_count 0; void MOTOR_EN_PIN_Init(void) { GPIO_InitTypeDef MY_GPIO_Init; //定义结构体变量 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //在led.c中使能了重复使能不影响 MY_GPIO_Init.GPIO_Pin GPIO_Pin_3; //开发板LED4复用了不影响 MY_GPIO_Init.GPIO_Mode GPIO_Mode_Out_PP; //设置推挽输出模式 MY_GPIO_Init.GPIO_Speed GPIO_Speed_50MHz; //设置传输速率 GPIO_Init(GPIOC, MY_GPIO_Init); GPIO_ResetBits(GPIOC, GPIO_Pin_3); //电机disable但LED4会被点亮 } /***************************************************************************/ //功能定时器2 通道1、3、4输出高有效的PWM(这里使用的是中央对齐模式) //参数1per 自动重装寄存器值 //参数2psc 分频系数 //参数3pulse1 占空比控制 第一路占空比为 pulse1/per //参数4pulse2 占空比控制 第二路占空比为 pulse2/per //参数5pulse3 占空比控制 第三路占空比为 pulse3/per //向上计数模式: //频率 72M / ((预分频 1) × (ARR1) ) //中央对齐模式: //频率 72M / ((预分频 1) × 2 × ARR ) void TIM2_CH1_CH3_CH4_PWM_Init(u16 per, u16 psc, u16 pulse1, u16 pulse2, u16 pulse3) { GPIO_InitTypeDef MY_GPIO_Init;//定义结构体变量 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能TIM2时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //使能IO复用功能端口时钟因为IO口需要重映射 这里在TIM3_CH1_CH2_PWM_Init也有调用 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能GPIOB端口时钟 //RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA端口时钟 在串口中已经使能过了 //GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE); //由查表可知PB10、PB11使用的是完全重映射管脚 GPIO_PinRemapConfig(GPIO_PartialRemap2_TIM2, ENABLE); //由查表可知PB10(CH3)、PB11(CH4)使用的也可以是重映射2管脚以及使用PA0CH1 //CH1 MY_GPIO_Init.GPIO_Pin GPIO_Pin_0; MY_GPIO_Init.GPIO_Mode GPIO_Mode_AF_PP; //设置复用推挽输出模式 MY_GPIO_Init.GPIO_Speed GPIO_Speed_50MHz; //设置传输速率 GPIO_Init(GPIOA, MY_GPIO_Init); //CH3 MY_GPIO_Init.GPIO_Pin GPIO_Pin_10; MY_GPIO_Init.GPIO_Mode GPIO_Mode_AF_PP; //设置复用推挽输出模式 MY_GPIO_Init.GPIO_Speed GPIO_Speed_50MHz; //设置传输速率 GPIO_Init(GPIOB, MY_GPIO_Init); //CH4 MY_GPIO_Init.GPIO_Pin GPIO_Pin_11; MY_GPIO_Init.GPIO_Mode GPIO_Mode_AF_PP; //设置复用推挽输出模式 MY_GPIO_Init.GPIO_Speed GPIO_Speed_50MHz; //设置传输速率 GPIO_Init(GPIOB, MY_GPIO_Init); //初始化定时器参数 TIM_DeInit(TIM2); TIM_TimeBaseStructure.TIM_Period per; TIM_TimeBaseStructure.TIM_Prescaler psc; TIM_TimeBaseStructure.TIM_ClockDivision TIM_CKD_DIV1; //一般配置为TIM_CKD_DIV1 TIM_TimeBaseStructure.TIM_CounterMode TIM_CounterMode_CenterAligned1; TIM_TimeBaseInit(TIM2, TIM_TimeBaseStructure); //初始化PWM CH1输出参数 TIM_OCInitStructure.TIM_OCMode TIM_OCMode_PWM1; //PWM输出模式1 TIM_OCInitStructure.TIM_Pulse pulse1; TIM_OCInitStructure.TIM_OCPolarity TIM_OCPolarity_High; //输出高有效9g舵机控制要求 TIM_OCInitStructure.TIM_OutputState TIM_OutputState_Enable; //输出使能 TIM_OC1Init(TIM2, TIM_OCInitStructure); //初始化PWM CH3输出参数 TIM_OCInitStructure.TIM_OCMode TIM_OCMode_PWM1; //PWM输出模式1 TIM_OCInitStructure.TIM_Pulse pulse2; TIM_OCInitStructure.TIM_OCPolarity TIM_OCPolarity_High; //输出高有效9g舵机控制要求 TIM_OCInitStructure.TIM_OutputState TIM_OutputState_Enable; //输出使能 TIM_OC3Init(TIM2, TIM_OCInitStructure); //初始化PWM CH4输出参数 TIM_OCInitStructure.TIM_OCMode TIM_OCMode_PWM1; //PWM输出模式1 TIM_OCInitStructure.TIM_Pulse pulse3; TIM_OCInitStructure.TIM_OCPolarity TIM_OCPolarity_High; //输出高有效9g舵机控制要求 TIM_OCInitStructure.TIM_OutputState TIM_OutputState_Enable; //输出使能 TIM_OC4Init(TIM2, TIM_OCInitStructure); //使能输出比较预装载寄存器 TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable); TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable); //使能 ARR 预装载寄存器 TIM_ARRPreloadConfig(TIM2, ENABLE); //开启定时器 TIM_Cmd(TIM2, ENABLE); //TIM_CtrlPWMOutputs() 如果使用高级定时器输出PWM还需要调用该函数使能主输出否则不能输出PWM !!! } /***************************************************************************/ //1MS产生一次中断 void TIM4_1MS_Init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; NVIC_InitTypeDef NVIC_InitStructure; //TIM4时钟使能 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //初始化NVIC,这里未配置中断优先级 NVIC_InitStructure.NVIC_IRQChannel TIM4_IRQn; NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE; NVIC_Init(NVIC_InitStructure); TIM_TimeBaseInitStructure.TIM_Period 1000-1; //1ms TIM_TimeBaseInitStructure.TIM_Prescaler 72-1; //72分频 1MHz TIM_TimeBaseInitStructure.TIM_CounterMode TIM_CounterMode_Up; TIM_TimeBaseInitStructure.TIM_ClockDivision TIM_CKD_DIV1; TIM_TimeBaseInit(TIM4, TIM_TimeBaseInitStructure); //开启定时器中断即使用定时器4的更新中断作为NVIC的中断源如计数器到达设定自动重装载寄存器值时触发更新中断 TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); TIM_Cmd(TIM4, ENABLE); } //定时器中断服务函数只做一件事计数器加一 void TIM4_IRQHandler(void) { if(TIM_GetITStatus(TIM4,TIM_IT_Update) SET) //溢出中断 { time4_count; } TIM_ClearITPendingBit(TIM4,TIM_IT_Update); //清除中断标志位 } /***************************************************************************/3.SysTick系统定时器SysTick系统定时器新增SysTick_CountMode接口用于开环控制禁用延时函数详情参考代码及注释SysTick.h#ifndef __SYSTICK_H #define __SYSTICK_H #include system.h void SysTick_Init(u8 SYSCLK); void delay_ms(u16 nms); void delay_us(u32 nus); void SysTick_CountMode(void); #endifSysTick.c#include SysTick.h static u8 fac_us 0; //即延时1us需要的计数次数 static u16 fac_ms 0; //即延时1ms需要的计数次数 //使用延时函数需要先进行初始化 //SYSCLK:系统时钟频率 void SysTick_Init(u8 SYSCLK) { SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //SysTick时钟源为HCLK的8分频由时钟树图可以得知HCLK时钟等于AHB时钟 fac_us SYSCLK/8; //SYSCLK 72M为例fac_us 9即延时1us需要的计数次数为9 fac_ms (u16)fac_us * 1000; } /******************************************************************************* * 函 数 名 : delay_us * 函数功能 : us延时 * 输 入 : nus要延时的us数 注 意 : nus的值,不要大于798915us(最大值即2^24/fac_usfac_us21) * 输 出 : 无 *******************************************************************************/ void delay_us(u32 nus) { u32 temp; SysTick-LOAD nus * fac_us; //将延时对应的预重装值写入LOAD寄存器 SysTick-VAL 0x00; //清空当前数值寄存器VAL SysTick-CTRL | SysTick_CTRL_ENABLE_Msk; // SysTick定时器使能 do { temp SysTick-CTRL; //读取CTRL寄存器 }while((temp0x01)!(temp(116))); //等待时间到达后退出 SysTick-CTRL ~SysTick_CTRL_ENABLE_Msk; // SysTick定时器disable SysTick-VAL 0x00; //清空当前数值寄存器VAL } /******************************************************************************* * 函 数 名 : delay_ms * 函数功能 : ms延时 * 输 入 : nms要延时的ms数 注 意 :nms的值,SysTick-LOAD为24位寄存器 不要大于0xffffff*8*1000/SYSCLK对72M条件下,nms1864ms * 输 出 : 无 *******************************************************************************/ void delay_ms(u16 nms) { u32 temp; SysTick-LOAD (u32)nms * fac_ms; //只有这里不同其他和delay_us延时相同 SysTick-VAL 0x00; SysTick-CTRL | SysTick_CTRL_ENABLE_Msk ; do { tempSysTick-CTRL; }while((temp0x01)!(temp(116))); SysTick-CTRL ~SysTick_CTRL_ENABLE_Msk; SysTick-VAL 0x00; } /******************************************************************************* * 函 数 名 : SysTick_CountMode * 函数功能 : 让SysTick定时器从0xFFFFFF到0循环计数 * 输 入 : 无 * 注 意 : 在BLDCMotor.c中需要读取SysTick-VAL的值它要求 SysTick 必须一直自由跑 * 输 出 : 无 *******************************************************************************/ void SysTick_CountMode(void) { SysTick-LOAD 0xFFFFFF - 1; //set reload register SysTick-VAL 0; SysTick-CTRL SysTick_CTRL_ENABLE_Msk; //Enable SysTick Timer }4.usart模块改造修改接收中断回调中断回调中实现存储字符串用于串口控制命令解析在不需要不需要选择MicroLIB情况下适配代码防止编译器报错fputc的实现兼容库函数操作、寄存器操作usart.h#ifndef __USART_H #define __USART_H #include system.h #include stdio.h //要实现int fputc(int ch,FILE *p) 原型需要包含该头文件 #define USART_REC_LEN 256 /* 声明是全局变量需要在外部文件使用 */ extern unsigned char USART_RX_BUF[USART_REC_LEN]; extern unsigned short USART_RX_STA; void USART1_Init(u32 bound); #endifusart.c#include usart.h /* 1.在不需要不需要选择MicroLIB情况下这些代码是为了骗过编译器报错如果选择了MicroLIB则不需要这段代码也可以使用printf */ #if 1 #pragma import(__use_no_semihosting) //标准库需要的支持函数 struct __FILE { int handle; }; FILE __stdout; //定义_sys_exit避免使用半主机模式 void _sys_exit(int x) { x x; } #endif /* fputc的实现以下两种写法都可以第一种是直接操作寄存器第二种是通过调用库函数的方式 */ #if 1 int fputc(int ch, FILE *f) { while((USART1-SR 0X40) 0); USART1-DR (u8)ch; return ch; } #else int fputc(int ch, FILE *p) //函数默认的函数原型不能改变在使用printf函数时自动调用 { USART_SendData(USART1,(u8)ch); while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) RESET); //USART_FLAG_TXE状态标志表示可以发送下一个数据了发送数据寄存器已经空了发送移位寄存器数据可能没有发完 return ch; } #endif /******************************************************************************/ unsigned char USART_RX_BUF[USART_REC_LEN]; //接收buffer /* 接收状态标志: bit15 1:接收完成标志 bit14 1:接收到0x0D\r 的 16 进制是0x0D bit13~0:接收的字节数 */ unsigned short USART_RX_STA 0; //bound:参数为输入波特率 void USART1_Init(u32 bound) { GPIO_InitTypeDef MY_GPIO_Init; //定义结构体变量 USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; //默认引脚 PA9/PA10没有重映射 → 不需要使能 AFIO 时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //使能串口1时钟 MY_GPIO_Init.GPIO_Pin GPIO_Pin_9; //TX -- PA9 MY_GPIO_Init.GPIO_Mode GPIO_Mode_AF_PP; //设置复用推挽输出模式 MY_GPIO_Init.GPIO_Speed GPIO_Speed_50MHz; //设置传输速率 GPIO_Init(GPIOA, MY_GPIO_Init); MY_GPIO_Init.GPIO_Pin GPIO_Pin_10; //RX -- PA10 MY_GPIO_Init.GPIO_Mode GPIO_Mode_IN_FLOATING; //设置浮空输入 MY_GPIO_Init.GPIO_Speed GPIO_Speed_50MHz; //设置传输速率 GPIO_Init(GPIOA, MY_GPIO_Init); USART_InitStructure.USART_BaudRate bound; //设置波特率 USART_InitStructure.USART_WordLength USART_WordLength_8b; //设置数据位为8位 USART_InitStructure.USART_StopBits USART_StopBits_1; //设置停止位为1位 USART_InitStructure.USART_Parity USART_Parity_No; //无奇偶校验 USART_InitStructure.USART_HardwareFlowControl USART_HardwareFlowControl_None; //无硬件流控 USART_InitStructure.USART_Mode USART_Mode_Tx | USART_Mode_Rx; //发送使能和接收使能 USART_Init(USART1, USART_InitStructure); USART_Cmd(USART1, ENABLE); //使能 USART1串口 //清除USART_FLAG_TC发送完成标志位这个是状态标志位并非中断标志位 USART_ClearFlag(USART1, USART_FLAG_TC); //清除USART_FLAG_TC发送完成标志位这步最好是清除一下 //设置串口中断类型并使能 //USART_IT_RXNE —— 接收数据寄存器非空中断,“我收到了一个字节数据已经放进接收寄存器了快来读” USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //我们选择的是接收中断 NVIC_InitStructure.NVIC_IRQChannel USART1_IRQn; //在stm32f10x.h查看 #if 0 /* 在一般测试中抢占优先级2、响应优先级都设置为0数值越小优先级越高 */ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority 0; #else /* 在FOC电机控制中抢占优先级、响应优先级都设置为3数值越小优先级越高 */ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 3; //抢占优先级3 NVIC_InitStructure.NVIC_IRQChannelSubPriority 3; //响应优先级3 #endif NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE; //IRQ通道使能 NVIC_Init(NVIC_InitStructure); } #if 0 /* 这个中断函数只是测试接收到的数据原样发回。 */ void USART1_IRQHandler(void) { u8 data 0; if(USART_GetITStatus(USART1, USART_IT_RXNE) ! RESET) //串口接收中断标志位检查指定的 USART 中断发生与否,当调用接收函数时会被自动清除。 { //当你调用 USART_ReceiveData() 读取数据时硬件会自动清除 USART_IT_RXNE data USART_ReceiveData(USART1); USART_SendData(USART1, data); //将接收的数据发送出去 //USART_FLAG_TC发送完成标志位,表示当移位寄存器的最后一位数据被发送到 TX 引脚且总线空闲时才置 1。表示数据已经完全发完总线已经空闲。 //USART_FLAG_TXE发送数据寄存器空,当 TDR 寄存器的数据被转移到移位寄存器后立刻置 1,表示 “我可以写下一个数据了”。 while(USART_GetFlagStatus(USART1,USART_FLAG_TC) ! SET); //USART_FLAG_TC发送完成标志位 //while(USART_GetITStatus(USART1, USART_FLAG_TC) ! SET); //开始错用了这个函数导致中断程序在这里卡死 } USART_ClearFlag(USART1, USART_FLAG_TC); //清除USART_FLAG_TC发送完成标志位这个是状态标志位并非中断标志位 } #else /* 串口1中断程序:每收到 1 个字节就进一次这个中断函数将接收数据存放在全局BUF中 1.将RX收到的字节存放到USART_RX_BUF中如[data,...,data,data,\0] 2.USART_RX_STA中bit15、bit14记录接收标志bit13~0:接收的字节数 3.如发送T10.5\r\n 将T10.5存放在USART_RX_BUF中结尾加上字符串结束符\0 */ void USART1_IRQHandler(void) { unsigned char Res; if(USART_GetITStatus(USART1, USART_IT_RXNE) ! RESET) //判断是否是接收中断 { Res USART_ReceiveData(USART1); //读取接收到的一个字节 if((USART_RX_STA0x8000) 0) //bit15 0,接收未完成 { if(USART_RX_STA0x4000) //已经接收到了0x0D即接收到了回车 \r (16进制为0x0D) { if(Res ! 0x0A) // \n 为0x0A { USART_RX_STA 0; //接收错误重新开始 } else { USART_RX_STA | 0x8000; //接收到了\n将bit15 1(接收完成 //USART_RX_STA0X3FFF 为接收的字节数 USART_RX_BUF[USART_RX_STA0X3FFF] \0; //最后一个字节放0’方便判断 } } else //还没收到0x0D { //如果当前字节是\r if(Res 0x0D) { USART_RX_STA | 0x4000; } else { USART_RX_BUF[USART_RX_STA0X3FFF] Res; USART_RX_STA; if(USART_RX_STA (USART_REC_LEN - 1)) { USART_RX_STA 0; //接收数据超过接收buffer大小,接收错误重新开始 } } } } } } #endif5.SimpleFOC库移植将SimpleFOC文件夹拷贝到工程路径下添加SimpleFOC工程组添加如下工程文件到工程组引入头文件路径这些文件开环控制暂不使用先暂存在这个路径下加入头文件依赖FOCMotor.c#include “foc_utils.h”#include “FOCMotor.h”#include “BLDCmotor.h”foc_utils.c#include “foc_utils.h”#include “FOCMotor.h”#include “BLDCmotor.h”BLDCMotor.c#include “time_open_control.h” //是因为需要包含system.h 需要调用TIM_SetCompareX库函数#include “foc_utils.h”#include “FOCMotor.h”#include “BLDCmotor.h”6.main.c函数大致流程状态指示灯管脚配置初始化驱动板SimpleFOC Mini 使能管脚配置初始化串口1初始化配置TIM2输出PWM(此时不输出调用TIM_SetCompareX时输出)配置TIM4定时器中断为1MS配置controller控制模式、voltage_limit、电机极对数pole_pairs等参数驱动板使能SysTick切到CountMode模式while循环指示灯控制–接收控制命令–控制输出调用move函数main.c/* 该代码已经全部调通led状态闪烁默认是速度开环模式高速下电机可能会堵转低速发热比较严重 */ #include stdlib.h #include system.h //已经包含了stm32f10x.h 以及定义了位带操作的宏后续只包含该头文件就可以了 #include SysTick.h //使用delay_ms和delay_us #include led.h //Led_Init()对8个LED GPIO初始化, 状态指示灯需要使用 #include time_open_control.h //三路PWM以及状态指示灯闪烁控制 #include usart.h //使用printf打印以及接收串口命令 #include FOCMotor.h //使用controller全局变量及Type_velocity_openloop等数据结构 #include BLDCmotor.h //voltage_power_supply等全局变量 /* 1.速度开环模式下弧度 T0.01(再小的精度没有测试了) ~ T60(目前测试下再大可能会堵转) 默认T6.28上电后以6.28rad/s的转速转动1圈/秒 2.位置角度开环模式下float的取值范围 默认T6.28上电后顺时针转动1圈后回到起点 T-6.28逆时针转动1圈后回到起点 */ float target 0.0; void commander_run(void) { if((USART_RX_STA0x8000) ! 0) { switch(USART_RX_BUF[0]) { case H: printf(Speed Mode:T-0.01~T-60\r\n); printf(ag:T1.23\r\n); printf(Angle Mode:-float\r\n); printf(ag:T-6.28\r\n); printf(D:Motor disable!\r\n); printf(E:Motor enable!\r\n); break; case T: //T6.28 target atof((const char *)(USART_RX_BUF 1)); printf(RX %.4f\r\n, target); break; case D: //D MOTOR_DISABLE; printf(Motor disable!\r\n); break; case E: //E MOTOR_ENABLE; printf(Motor enable!\r\n); default: break; } USART_RX_STA 0; //不用清除BUF,清除BUF状态下次接收复写即可 } } //开环控制最重要的参数就是voltage_limit //1、电机抖动转不起来把voltage_limit设置的大一点 //2、电机发热严重的把voltage_limit设置的小一点 //3、串口发送指令“T10”后面要有回车换行符 //4、开环不是电机控制的常态不要纠结太久。 int main(void) { SysTick_Init(72); //72为SYSCLK delay_ms延时函数需要使用 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断分组2:2 在使用中断回调函数时都需要调用, 这里虽然没有使用中断但还是留着 Led_Init(); //使用LED1作为状态显示 MOTOR_EN_PIN_Init(); //驱动板SimpleFOC Mini 使能管脚配置 USART1_Init(9600); //使用printf及接收串口控制命令 //中央对齐模式: //频率f 72M / ((预分频 1) * 2 * ARR ) //以25K赫兹 40us为例f 72M / ((01) * 2 * (1440-11)) 72000000 / (1440 * 2) 25000 Hz 25KHz TIM2_CH1_CH3_CH4_PWM_Init(1440 - 1, 0, 0, 0, 0); //25KHz,此时不输出PWM TIM4_1MS_Init(); //interrupt per 1ms delay_ms(1000); //Wait for the system to stabilize /************************参数调整*********************************/ controller Type_velocity_openloop; //选择开环控制类型为速度模式 //controller Type_angle_openloop; //选择开环控制类型为角度模式 voltage_power_supply 12; //V //voltage_limit 2.5; //V最大值需小于12/1.7326.9。大功率航模电机设置的小一点0.5-1小功率云台电机设置的大一点1-3 voltage_limit 3.0; //这里2.5V调整为3V velocity_limit 20; //rad/s angleOpenloop() use it pole_pairs 7; //电机的极对数N-S极多少对 target 6.28; //选择开环控制类型为速度模式为例上电后以6.28rad/s的转速转动1圈/秒 /******************************************************************/ MOTOR_ENABLE; //驱动板SimpleFOC Mini 使能管脚 printf(Control Mode(Speed Mode 3 ,Angle Mode 4):[%d].\r\n, controller); printf(Motor ready.\r\n); /* 在BLDCMotor.c中需要读取SysTick-VAL的值它要求 SysTick 必须一直自由跑 */ SysTick_CountMode(); //后续code不能再调用delay_us()和delay_ms()函数 while(1) { //这个time4_count计数只是为了LED状态指示灯闪烁使用 if(time4_count 200) //0.2s闪烁一次 { time4_count 0; led1 !led1; } move(target); commander_run(); } }