电机控制
直播中

jf_94269963

2年用户 7经验值
擅长:可编程逻辑 嵌入式技术 处理器/DSP 控制/MCU
私信 关注
[讨论]

CW32L011电机开发板测评

CW32L011电机开发板测评

hello,大家好,主播是某不知名公司的实习生一名,最近在学习FOC开发,之前用的是公司前辈制作的FOC控制板,因pcb设计问题总是烧芯片,数据乱码各种原因甚是苦恼。但在几天前水群的时候看到了,芯源半导体正在支持的一个活动:

1元得!电机驱动器开发板,限100套!

企业用户满足条件可 1元 获得开发板体验-需提交申请:

限100名企业用户,参与CW32L011电机开发板测评:

可付100元押金申请CW32L011电机驱动开发套件,满足活动条件的,退还99元押金。

这个活动主播甚是喜欢,于是便申请了该板子,还没有第三天,板子就到了主播手里了,板子还带有金属外壳非常讨主播欢喜

下面是板子的外观和内部裸露结构:

外观

电路板背面

电路板正面

在主播获得板子以后,主播迅速进行了资料的浏览,并且由此进行里下面的准备

  • 主播因为独自一人在外地实习,自己的三相无刷霍尔电机并没有带在身上,于是主播在昨晚在咸鱼上迅速购买了一个垃圾霍尔电机(赌狗赌霍尔能够使用)。
  • 并且发现cw官方的已经非常牛X的把这块开发板的控制代码给写好了,于是在淘宝上把个电位器给买来了。
  • 还有就是这个开发板上的RS485的ttl转差分信号的芯片并没有焊接,但是主播认为,本人个人使用,并不需要RS485信号,使用普通的TTL信号就可以了,就没有购买信号转接芯片。
  • 因为主播在之前的学习中用的角度传感方式是MT6816绝对编码器芯片,并没有使用HALL传感器,所以在评测过程可能会以无感FOC作为主要评测方式,以后可能会更新PWM读取MT6816的绝对角度和HALL传感器读取角度的测评,说到这这块开发板芯片IO口的利用率极高,这是主播作为还未毕业实习生的非常震惊的一点,但是主播的MT6816似乎的就不能用了,不过主播用翻阅了其芯片的资料,似乎MT6816也支持HALL模式以及PWM角度读取模式,并且这块评测板中的VSR(VE)接口作为电位器接口,内置了运算放大器,以及对应的IO口支持 测量输入信号的脉冲宽度(输入捕获)所以未来主播会在这块开发板的基础上添加上相应的PWM角度读取方式。
  • 板子的下载口使用的是直插排针,并不适合下载最新的代码,于是主播将阵脚换成了弯角排针

引脚重焊

正式测评:

说明:主播因为买的咸鱼电机是HALL60°的,例程代码里面的有感就不能测评了,

使用例程代码测试BLDC无感控制(主播一开始以为是FOC控制)

直接开始将代码烧录进入开发板:(很令人伤心的是我把电机功率全开,把我的采样电阻给烧坏了,大家使用的时候要注意)

电机旋转

使用个人设置代码测试无感FOC控制

/*
file:foc.c
user: Liushuangkai
Email:331193752@qq.com

release:0.1

根据开源灯哥模型,重构编写。

*/

#include "foc.h"
#include "HALL.h"
//#include "MT6816.h"
//#include "user_config.h"

#define _3PI_2 4.71238898038f

#define _constrain(amt,low,high) ((amt)<  (low)?(low):((amt)  >(high)?(high):(amt)))
#define SIGN(x)  ( (x) > 0 ? 1 : ((x) < 0 ? -1 : 0) )


#if CONTROL_MODE == CLOSE_CONTROL
#define _electricalAngle(shaft_angle,pole_pairs) (shaft_angle-zero_Angle) * pole_pairs*DIR
#elif CONTROL_MODE == OPEN_CONTROL
#define _electricalAngle(shaft_angle,pole_pairs) shaft_angle * pole_pairs
#endif

U_xy foc_target;
U_xy foc_inv_park;
U_abc foc_inv_clarke;
U_abc foc_output_duty;
PWM_abc open_pwm;

float OUT_Voltage;
float Mechanical_Angle;
float electrical_Angle;
float zero_Angle=0;

unsigned int TimeCountCompuSpeed=0,TimeCountTemp=0,TimeCountSTDelay=0,Icount=0;



#if CONTROL_MODE == CLOSE_CONTROL

arm_pid_instance_f32 close_pos_pid;

void foc_init()
{
        close_pos_pid.Kd=0;
        close_pos_pid.Ki=0;
        close_pos_pid.Kp=0.03333;//差值P,本系统使用24V电压,偏移12V,则最大电压为12V,采用90度为最大P值输出点,则P约为 12/90=0.133
        arm_pid_init_f32(&close_pos_pid,1);
        
        //MT6816_Init(&hspi1,SPI_CS_GPIO_Port,SPI_CS_Pin);
        //foc_target.U_x=0;

#if angle_calibration == 0 //该校准需要无负载校准//系统开机需支持无负债开机

        electrical_Angle = 0;        
        foc_target.U_y =VOTAGE_POWER_OFFSET/2.0;
        foc_feedforward_path();
        Delay_Ms(3000);
        foc_target.U_y = 0;
        foc_feedforward_path();
        //zero_Angle =get_angle();
        angle_init();

#elif angle_calibration == 1



#endif

        //TIME_ELAPSE();

}

float midd,last_angle;



void foc_control(float * motor_target)//_close_pos
{

        Mechanical_Angle = get_angle();
        //Mechanical_Angle =_normalizeAngle(Mechanical_Angle+Ts**motor_target*PI*2);
//foc_target.U_y = _constrain(arm_pid_f32(&close_pos_pid,*motor_target-Mechanical_Angle),-VOTAGE_POWER_OFFSET,VOTAGE_POWER_OFFSET);
        float Ts = 0.002;//TIME_ELAPSE();
foc_target.U_y = VOTAGE_POWER_OFFSET/2;
if(Mechanical_Angle!=0)
        midd = _normalizeAngle(midd+(Ts)*0.1*PI*2);
        electrical_Angle =_normalizeAngle(_electricalAngle(midd,POLE_PAIRS));

//if(Mechanical_Angle!=last_angle)
//{
//  midd = Mechanical_Angle;
//        last_angle=Mechanical_Angle;
//}else
//{

//midd = midd+(Ts)*2*PI*2*SIGN(Mechanical_Angle);

//}
//        foc_target.U_y = _constrain(arm_pid_f32(&close_pos_pid,*motor_target-Mechanical_Angle),-VOTAGE_POWER_OFFSET,VOTAGE_POWER_OFFSET);
//  electrical_Angle = _electricalAngle(Mechanical_Angle*PI/180,POLE_PAIRS);
        foc_feedforward_path();

}


#elif CONTROL_MODE == OPEN_CONTROL


void foc_init()
{
foc_target.U_x=0;
foc_target.U_y = VOTAGE_POWER_OFFSET;
//TIME_ELAPSE();
}

//开环foc控制时间推算通过dwt计数器完成 //使用的DSP库函数进行的克拉克和帕克变换,如果,使用的库函数封装不同请自行更改。
void foc_control(float * target_velocity)
{

        float Ts = 0.002;//TIME_ELAPSE();
        Mechanical_Angle =_normalizeAngle(Mechanical_Angle+(Ts)*(*target_velocity)*PI*2);
        electrical_Angle =_normalizeAngle(_electricalAngle(Mechanical_Angle,POLE_PAIRS));
        foc_feedforward_path();

}
#endif

float _normalizeAngle(float angle){
  float a = fmod(angle, 2*PI);   //取余运算可以用于归一化,列出特殊值例子算便知
  return a >= 0 ? a : (a + 2*PI);  
  //三目运算符。格式:condition ? expr1 : expr2 
  //其中,condition 是要求值的条件表达式,如果条件成立,则返回 expr1 的值,否则返回 expr2 的值。可以将三目运算符视为 if-else 语句的简化形式。
  //fmod 函数的余数的符号与除数相同。因此,当 angle 的值为负数时,余数的符号将与 _2PI 的符号相反。也就是说,如果 angle 的值小于 0 且 _2PI 的值为正数,则 fmod(angle, _2PI) 的余数将为负数。
  //例如,当 angle 的值为 -PI/2,_2PI 的值为 2PI 时,fmod(angle, _2PI) 将返回一个负数。在这种情况下,可以通过将负数的余数加上 _2PI 来将角度归一化到 [0, 2PI] 的范围内,以确保角度的值始终为正数。
}


void foc_feedforward_path()
{

  // 帕克逆变换
        arm_inv_park_f32(foc_target.U_x,foc_target.U_y,&foc_inv_park.U_x,&foc_inv_park.U_y,arm_sin_f32(electrical_Angle),arm_cos_f32( electrical_Angle));
        arm_inv_clarke_f32(foc_inv_park.U_x,foc_inv_park.U_y,&foc_inv_clarke.Ua,&foc_inv_clarke.Ub);
        foc_inv_clarke.Uc = -foc_inv_clarke.Ua-foc_inv_clarke.Ub+VOTAGE_POWER_OFFSET;
        foc_inv_clarke.Ua+= VOTAGE_POWER_OFFSET;
        foc_inv_clarke.Ub+= VOTAGE_POWER_OFFSET;
        foc_output_duty.Ua= foc_inv_clarke.Ua/VOTAGE_POWER_SUPPLY;
        foc_output_duty.Ub= foc_inv_clarke.Ub/VOTAGE_POWER_SUPPLY;
        foc_output_duty.Uc = foc_inv_clarke.Uc/VOTAGE_POWER_SUPPLY;
        open_pwm.PWMa = foc_output_duty.Ua* PWM_COUNT;
        open_pwm.PWMb = foc_output_duty.Ub * PWM_COUNT;
        open_pwm.PWMc = foc_output_duty.Uc * PWM_COUNT;

        FOC_PWMA=open_pwm.PWMa;
        FOC_PWMB=open_pwm.PWMb; 
        FOC_PWMC=open_pwm.PWMc;


}


void SVPWM()
{




}
void BLDC_Configuration(void)
{
  __SYSCTRL_ATIM_CLK_ENABLE();
        __SYSCTRL_GPIOA_CLK_ENABLE();
  __SYSCTRL_GPIOB_CLK_ENABLE();
        NVIC_EnableIRQ(ATIM_IRQn);
  //上桥引脚
        GPIO_InitTypeDef GPIO_InitStruct = {0};
        GPIO_InitStruct.IT = GPIO_IT_NONE;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pins = PWM_AP_PIN | PWM_BP_PIN; 
  GPIO_Init(CW_GPIOB, &GPIO_InitStruct);
  GPIO_InitStruct.Pins = PWM_CP_PIN;
  GPIO_Init(CW_GPIOB, &GPIO_InitStruct);
        PB05_AFx_ATIMCH1();
        PB06_AFx_ATIMCH2();
        PB07_AFx_ATIMCH3();
        
        //下桥引脚
        GPIO_InitStruct.IT = GPIO_IT_NONE;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pins = PWM_AN_PIN ; 
  GPIO_Init(CW_GPIOA, &GPIO_InitStruct);
        GPIO_InitStruct.Pins = PWM_BN_PIN|PWM_CN_PIN;
        GPIO_Init(CW_GPIOB, &GPIO_InitStruct);
        PB04_AFx_ATIMCH3N();
        PB03_AFx_ATIMCH2N();
        PA15_AFx_ATIMCH1N();

        
        ATIM_InitTypeDef ATIM_InitStruct;
  ATIM_OCInitTypeDef ATIM_OCInitStruct = {0};
  ATIM_InitStruct.BufferState = DISABLE;               //使能缓存寄存器    
  ATIM_InitStruct.CounterAlignedMode = ATIM_COUNT_ALIGN_MODE_CENTER_BOTH;    //中心对齐
  ATIM_InitStruct.CounterDirection = ATIM_COUNTING_UP;        //向上计数;
  ATIM_InitStruct.CounterOPMode = ATIM_OP_MODE_REPETITIVE;    //连续运行模式       
  ATIM_InitStruct.Prescaler = 1 - 1;                          // 计算时钟 96 MHz
  ATIM_InitStruct.ReloadValue = PWM_PERIOD - 1;                   // PWM_TS = 2399
  ATIM_InitStruct.RepetitionCounter = 0;
  ATIM_Init(&ATIM_InitStruct);

        
        ATIM_OCInitStruct.BufferState = DISABLE;
  ATIM_OCInitStruct.OCComplement = ENABLE;
  ATIM_OCInitStruct.OCFastMode = DISABLE;    
  ATIM_OCInitStruct.OCInterruptState = ENABLE;
  ATIM_OCInitStruct.OCMode = ATIM_OCMODE_PWM1;    
  ATIM_OCInitStruct.OCPolarity = ATIM_OCPOLARITY_NONINVERT;
  ATIM_OC1Init(&ATIM_OCInitStruct);
        ATIM_OC2Init(&ATIM_OCInitStruct);
        ATIM_OC3Init(&ATIM_OCInitStruct);
        ATIM_OC4Init(&ATIM_OCInitStruct);

                ATIM_ITConfig(ATIM_IT_UIE, ENABLE);             // 有重复计数器溢出产生进入中断

        ATIM_SetCompare1(0);
  ATIM_SetCompare2(0);
        ATIM_SetCompare3(0);
        ATIM_SetCompare4(PWM_PERIOD/2); 
        ATIM_SetPWMDeadtime(20, 40, ENABLE);    // 前死区为20个单位,后死区为40个单位,死区计算见用户手册

        ATIM_CH1Config(ENABLE);
        ATIM_CH2Config(ENABLE);
        ATIM_CH3Config(ENABLE);
        ATIM_CH4Config(ENABLE);
        
  ATIM_CtrlPWMOutputs(ENABLE);
  ATIM_Cmd(ENABLE);    
}
#ifndef _FOC_H_
#define _FOC_H_

//#include "dwt.h"
#include "arm_math.h"
#include "main.h"
#include "hall.h"
#define DIR  -1 //编码器方向与a-  >b-  >c相向则 逆 -1   顺 1

//foc模式控制
#define CONTROL_MODE OPEN_CONTROL

 #define OPEN_CONTROL  0
 #define CLOSE_CONTROL 1



#define PWM_AP_PORT                                                                        (CW_GPIOB)
#define PWM_AP_PIN                                                                        (GPIO_PIN_5)
#define PWM_AN_PORT                                                                        (CW_GPIOA)
#define PWM_AN_PIN                                                                        (GPIO_PIN_15)

#define PWM_BP_PORT                                                                        (CW_GPIOB)
#define PWM_BP_PIN                                                                        (GPIO_PIN_6)
#define PWM_BN_PORT                                                                        (CW_GPIOB)
#define PWM_BN_PIN                                                                        (GPIO_PIN_3)

#define PWM_CP_PORT                                                                        (CW_GPIOB)
#define PWM_CP_PIN                                                                        (GPIO_PIN_7)
#define PWM_CN_PORT                                                                        (CW_GPIOB)
#define PWM_CN_PIN                                                                        (GPIO_PIN_4)

#define FOC_PWMA                    CW_ATIM-  >CCR1
#define FOC_PWMB                                                                                CW_ATIM-  >CCR2
#define FOC_PWMC                                                                                 CW_ATIM-  >CCR3

#define PWM_AH_OFF GPIO_WritePin(PWM_AP_PORT,PWM_AP_PIN,GPIO_Pin_RESET) 
#define PWM_BH_OFF GPIO_WritePin(PWM_BP_PORT,PWM_BP_PIN,GPIO_Pin_RESET)
#define PWM_CH_OFF GPIO_WritePin(PWM_CP_PORT,PWM_CP_PIN,GPIO_Pin_RESET)

#define PWM_AH_ON GPIO_WritePin(PWM_AP_PORT,PWM_AP_PIN,GPIO_Pin_SET) 
#define PWM_BH_ON GPIO_WritePin(PWM_BP_PORT,PWM_BP_PIN,GPIO_Pin_SET) 
#define PWM_CH_ON GPIO_WritePin(PWM_CP_PORT,PWM_CP_PIN,GPIO_Pin_SET) 

//上管调制,下管开关控制, 上高电平开关管导通
#define PWM_AL_OFF GPIO_WritePin(PWM_AN_PORT,PWM_AN_PIN,GPIO_Pin_RESET) 
#define PWM_BL_OFF GPIO_WritePin(PWM_BN_PORT,PWM_BN_PIN,GPIO_Pin_RESET) 
#define PWM_CL_OFF GPIO_WritePin(PWM_CN_PORT,PWM_CN_PIN,GPIO_Pin_RESET) 

#define PWM_AL_ON GPIO_WritePin(PWM_AN_PORT,PWM_AN_PIN,GPIO_Pin_SET)
#define PWM_BL_ON GPIO_WritePin(PWM_BN_PORT,PWM_BN_PIN,GPIO_Pin_SET)
#define PWM_CL_ON GPIO_WritePin(PWM_CN_PORT,PWM_CN_PIN,GPIO_Pin_SET)

//载波频率15k
#define PWM_PERIOD 6400 
// (96000000 / 15000 )-1; 

#define VOTAGE_POWER_SUPPLY 24
#define PWM_COUNT 6400
#define VOTAGE_POWER_OFFSET 12
#define POLE_PAIRS 10
#define get_angle()   hall_get_angle()  //HALL获取机械角度
#define angle_calibration 0 //校准模式 1代表的是已经将校准值储存到flash/eprom中直接读取,0代表的是需要电位延时置零
#define Delay_Ms(x)         SysTickDelay(x)

#define TIME_ELAPSE() reckon_elapse_us()*1e-6f


typedef struct
{

float U_x;
float U_y;

}U_xy;


typedef struct
{
float Ua;
float Ub;
float Uc;
}U_abc;

typedef struct
{
uint16_t PWMa;
uint16_t PWMb;
uint16_t PWMc;
}PWM_abc;


extern unsigned int TimeCountCompuSpeed,TimeCountTemp,TimeCountSTDelay,Icount;


void foc_control(float * motor_target);
void foc_init(void);
float _normalizeAngle(float angle);
void foc_feedforward_path(void);

#endif

过程:

  • 主播试图使用之前的写过的FOC代码进行尝试直接移植,结果发现cw32作为一款低功耗32芯片,将DWT中的CYCCNT寄存器给裁剪掉了,非常令人伤心{?},本人平常小计时都是使用它的,结果却没有了{:titter:},只能使用定时器了{:lol:}。
  • 主播将代码里的DSP库重新加载(本人懒鬼),数学函数并不愿意自己写用的DSP库{?} ,这里有两种方法从git上拉取库自己引入工程,第二种直接在KEIL上加载,想要了解具体过程的可以自己去人工智能一下,并且DSP库与CW库文件有冲突,如果需要,把CW里面base_type.h里面的

/** single precision floating point number (4 byte) */

//typedef float float32_t;

/** double precision floating point number (8 byte) */

//typedef double float64_t;

注释掉就行

5.主播也是初学FOC控制,这里推荐灯哥foc(不过我推荐入了门就行,没必要买课{:lol:}),并且灯哥的FOC用的是arduino,可以自己尝试在32上使用。

6.这块板子的例程代码是六步换向的,主播因为以前都是用的直流电机,在学习无刷电机时候没有接触六部换向,把例程的吗当成foc的代码进行移植,结果初始化都有问题,这里主播把初始化放在这里(主播因为懒惰,以前比较喜欢cubemax,面对这一堆配置,主播也不是全部都懂,不过抄就完了)

主播将个人代码烧录进入开发板:

这个是无感FOC(偏移法的控制电机)1ms进行一次计算(需要使用定时器进行,如果你用的别的板子,带有DWT->CYCCNT,可以用它,因为主播喜欢{:lol:}),主播因为也是最近开始学习,所以有感foc还没有开始里面有一部分有感foc代码(所以里面有一堆垃圾),不过还没有写对,如果要用它的话,建议VOTAGE_POWER_OFFSET设置成1V,不然可能因为电机电阻过小,烧电路

最后是电机跑起来的图片:

无感FOC旋转

使用个人设置代码测试HALL+FOC控制

  • 前面主播提到,主播购买的是60°hall传感器电机,主播打算将60°HALL加上位置环,进行位置定位,不幸的是主播的HALL电机为10对极电机,HALL精度为6°,精度太小,会伴有振动发生,并且一点都不顺滑,当主播只好打算进行速度闭环控制,结果发现咸鱼垃圾电机的上面的覆铜掉了,主播的34块钱啊,只好把位置代码贴这这个帖子上了,想看的看一下(原本打算滤波加速度检测,这里滤波还是用的DSP库函数,DSP万岁)(小知识:HALL无刷电机的极性为保证,hall角统一一般为1,2,10对),等主播在咸鱼上在物色一块垃圾电机,在更新。
/*
file:HALL.c
user: Liushuangkai
Email:331193752@qq.com

release:0.1

*/
#include "HALL.h"
#include "cw32l011_gpio.h"

#define HALL_INSTA  HALL_60

#define  HALL_60  60
#define HALL_120 120
#define HALL_BIT  3 //这个是hall的数量,并没有使用,这里作为标注
#define POLE_PAIRS 10

#define HALL_ANGLE 6 //  360/(POLE_PAIRS*HALL_BIT*2)

uint8_t last_hall = 0xFF;  

Circ6_t HALL_CAP;//HALL方向读取储存

#if HALL_INSTA==HALL_60

const unsigned int hall_tbl[6]={3,1,5,4,6,2};//3,1,5,4,6,2(顺时针为正) 3,2,6,4,5,1(逆时针为负)

float Angle;


void        angle_init()
{

Angle=0;
}


/*需要将HALL判断插入中断中*/
void HALL_Callback()
{
        unsigned char x;
                x=HALL_Check();
                Angle += HALL_ANGLE*hall_dir(last_hall,x);
                last_hall = x;
                        //circ6_push(&HALL_CAP,x);//查询HALL数据方向,当你的电机不知道方向是否正确时候,把HALL_CALLBACK写入中断,电机开环逆时针运行进入调试,查看HALL_CAP

                        //if(x==0||x==7){return;} //HALL错位检查                
}

float hall_get_angle()
{

return Angle+3;

}

#elif HALL_INSTA == HALL_120


const unsigned char STEP_TAB[2][6]={{4,0,5,2,3,1},{1,3,2,5,0,4}};


void HALL_Callback()
{
}


#endif




unsigned char  HALL_Check(void)
{
//         static unsigned char hallerrnum=0;
         unsigned char x=0;
         if (GET_HALL_A==HALL_STATE_SET)x=0x01;
         if (GET_HALL_B==HALL_STATE_SET)x|=0x2;
         if (GET_HALL_C==HALL_STATE_SET)x|=0x4;
//         if(x==0||x==7)
//           {hallerrnum++;if(hallerrnum  >=10){hallerrnum=10;}}//ErrorCode=2;}}
//   else hallerrnum=0;
         return x;
}


/*HALL方向判定函数*/
static inline Dir_t hall_dir(uint8_t last, uint8_t now)
{
    if (last == now) return DIR_NONE;

    int8_t idx_last = -1, idx_now = -1;
    for (uint8_t i = 0; i < 6; i++) {
        if (hall_tbl[i] == last) idx_last = i;
        if (hall_tbl[i] == now)  idx_now  = i;
    }
    if (idx_last < 0 || idx_now < 0) return DIR_NONE;   // 非法值

    int8_t diff = idx_now - idx_last;
    if (diff ==  1 || diff == -5) return DIR_CW;   // 右移一格
    if (diff == -1 || diff ==  5) return DIR_CCW;  // 左移一格
    return DIR_NONE;                               // 跳变/丢步
}

/*查询HALL数据方向函数*/
static inline void circ6_push(Circ6_t *q, uint8_t v)
{
    q-  >buf[q-  >tail] = v;
    q-  >tail = (q-  >tail + 1U) % CAP;
    if (q-  >tail == q-  >head)                     // 满 -  > 覆盖旧数据
        q-  >head = (q-  >head + 1U) % CAP;
}
#ifndef _HALL_H_
#define _HALL_H_ 

#include <  stdint.h  >

#define  GET_HALL_A    GPIO_ReadPin(CW_GPIOA,GPIO_PIN_0)
#define  GET_HALL_B    GPIO_ReadPin(CW_GPIOA,GPIO_PIN_1)
#define  GET_HALL_C    GPIO_ReadPin(CW_GPIOA,GPIO_PIN_2)




#define CAP 6U                 // 容量固定 6
typedef struct {
    uint8_t buf[CAP];
    uint8_t  head;             // 读指针
    uint8_t  tail;             // 写指针
} Circ6_t;


typedef enum 
{
        DIR_CW = 1, 
        DIR_CCW = -1, 
        DIR_NONE = 0
} Dir_t;// 方向结果


typedef enum
{
  HALL_STATE_RESET = 0,
  HALL_STATE_SET
} HALL_State;


unsigned char  HALL_Check(void);
void HALL_Callback();
void        angle_init();
static inline Dir_t hall_dir(uint8_t last, uint8_t now);
float hall_get_angle();


#endif

下一步计划:等待主播购买一块新的电机,HALL的?或者磁编的(主播再自己画上PWM读取角度的板子),预计9月中

5615865dd328525c133989ad0c52df56

更多回帖

发帖
×
20
完善资料,
赚取积分