[开发板] CW32L011电机开发板测评

[复制链接]
猫吠 发表于 2025-8-16 18:10 | 显示全部楼层 |阅读模式
本帖最后由 猫吠 于 2025-8-20 12:13 编辑

CW32L011电机开发板测评

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


1元得!电机驱动器开发板,限100套!
企业用户满足条件可 1元 获得开发板体验-需提交申请:
限100名企业用户,参与CW32L011电机开发板测评:

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


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

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

开发板

开发板
acea3405ceaf73a7d60817a0612e2fcf.png 2.jpg


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

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


正式测评:
说明:主播因为买的咸鱼电机是HALL60°的,例程代码里面的有感就不能测评了
  • 使用例程代码测试BLDC无感控制(主播一开始以为是FOC控制

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


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




过程:
  • 主播试图使用之前的写过的FOC代码进行尝试直接移植,结果发现cw32作为一款低功耗32芯片,将DWT中的CYCCNT寄存器给裁剪掉了,非常令人伤心,本人平常小计时都是使用它的,结果却没有了,只能使用定时器了 5aa8b9a238b9132af8635962b6b127b3.png
  • 主播将代码里的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(不过我推荐入了门就行,没必要买课),并且灯哥的FOC用的是arduino,可以自己尝试在32上使用。

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

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

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

  1. void BLDC_Configuration(void)
  2. {
  3.   __SYSCTRL_ATIM_CLK_ENABLE();
  4.         __SYSCTRL_GPIOA_CLK_ENABLE();
  5.   __SYSCTRL_GPIOB_CLK_ENABLE();
  6.         NVIC_EnableIRQ(ATIM_IRQn);
  7.   //上桥引脚
  8.         GPIO_InitTypeDef GPIO_InitStruct = {0};
  9.         GPIO_InitStruct.IT = GPIO_IT_NONE;
  10.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  11.   GPIO_InitStruct.Pins = PWM_AP_PIN | PWM_BP_PIN;
  12.   GPIO_Init(CW_GPIOB, &GPIO_InitStruct);
  13.   GPIO_InitStruct.Pins = PWM_CP_PIN;
  14.   GPIO_Init(CW_GPIOB, &GPIO_InitStruct);
  15.         PB05_AFx_ATIMCH1();
  16.         PB06_AFx_ATIMCH2();
  17.         PB07_AFx_ATIMCH3();
  18.         
  19.         //下桥引脚
  20.         GPIO_InitStruct.IT = GPIO_IT_NONE;
  21.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  22.   GPIO_InitStruct.Pins = PWM_AN_PIN ;
  23.   GPIO_Init(CW_GPIOA, &GPIO_InitStruct);
  24.         GPIO_InitStruct.Pins = PWM_BN_PIN|PWM_CN_PIN;
  25.         GPIO_Init(CW_GPIOB, &GPIO_InitStruct);
  26.         PB04_AFx_ATIMCH3N();
  27.         PB03_AFx_ATIMCH2N();
  28.         PA15_AFx_ATIMCH1N();

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

  40.         
  41.         ATIM_OCInitStruct.BufferState = DISABLE;
  42.   ATIM_OCInitStruct.OCComplement = ENABLE;
  43.   ATIM_OCInitStruct.OCFastMode = DISABLE;   
  44.   ATIM_OCInitStruct.OCInterruptState = ENABLE;
  45.   ATIM_OCInitStruct.OCMode = ATIM_OCMODE_PWM1;   
  46.   ATIM_OCInitStruct.OCPolarity = ATIM_OCPOLARITY_NONINVERT;
  47.   ATIM_OC1Init(&ATIM_OCInitStruct);
  48.         ATIM_OC2Init(&ATIM_OCInitStruct);
  49.         ATIM_OC3Init(&ATIM_OCInitStruct);
  50.         ATIM_OC4Init(&ATIM_OCInitStruct);

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

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

  57.         ATIM_CH1Config(ENABLE);
  58.         ATIM_CH2Config(ENABLE);
  59.         ATIM_CH3Config(ENABLE);
  60.         ATIM_CH4Config(ENABLE);
  61.         
  62.   ATIM_CtrlPWMOutputs(ENABLE);
  63.   ATIM_Cmd(ENABLE);   
  64. }
  1. /*
  2. file:foc.c
  3. user: Liushuangkai
  4. Email:331193752@qq.com

  5. release:0.1

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

  7. */

  8. #include "foc.h"
  9. #include "HALL.h"
  10. //#include "MT6816.h"
  11. //#include "user_config.h"

  12. #define _3PI_2 4.71238898038f

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


  15. #if CONTROL_MODE == CLOSE_CONTROL
  16. #define _electricalAngle(shaft_angle,pole_pairs) (shaft_angle-zero_Angle) * pole_pairs*DIR
  17. #elif CONTROL_MODE == OPEN_CONTROL
  18. #define _electricalAngle(shaft_angle,pole_pairs) shaft_angle * pole_pairs
  19. #endif

  20. U_xy foc_target;
  21. U_xy foc_inv_park;
  22. U_abc foc_inv_clarke;
  23. U_abc foc_output_duty;
  24. PWM_abc open_pwm;

  25. float OUT_Voltage;
  26. float Mechanical_Angle;
  27. float electrical_Angle;
  28. float zero_Angle=0;

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



  30. #if CONTROL_MODE == CLOSE_CONTROL

  31. arm_pid_instance_f32 close_pos_pid;

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

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

  42.         electrical_Angle = 0;       
  43.         foc_target.U_y =VOTAGE_POWER_OFFSET/2.0;
  44.         foc_feedforward_path();
  45.         Delay_Ms(3000);
  46.         foc_target.U_y = 0;
  47.         foc_feedforward_path();
  48.         //zero_Angle =get_angle();
  49.         angle_init();

  50. #elif angle_calibration == 1



  51. #endif

  52.         //TIME_ELAPSE();

  53. }

  54. float midd,last_angle;



  55. void foc_control(float * motor_target)//_close_pos
  56. {

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

  65. //if(Mechanical_Angle!=last_angle)
  66. //{
  67. //  midd = Mechanical_Angle;
  68. //        last_angle=Mechanical_Angle;
  69. //}else
  70. //{

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

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

  76. }


  77. #elif CONTROL_MODE == OPEN_CONTROL


  78. void foc_init()
  79. {
  80. foc_target.U_x=0;
  81. foc_target.U_y = VOTAGE_POWER_OFFSET;
  82. //TIME_ELAPSE();
  83. }

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

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

  91. }
  92. #endif

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


  101. void foc_feedforward_path()
  102. {

  103.   // 帕克逆变换
  104.         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));
  105.         arm_inv_clarke_f32(foc_inv_park.U_x,foc_inv_park.U_y,&foc_inv_clarke.Ua,&foc_inv_clarke.Ub);
  106.         foc_inv_clarke.Uc = -foc_inv_clarke.Ua-foc_inv_clarke.Ub+VOTAGE_POWER_OFFSET;
  107.         foc_inv_clarke.Ua+= VOTAGE_POWER_OFFSET;
  108.         foc_inv_clarke.Ub+= VOTAGE_POWER_OFFSET;
  109.         foc_output_duty.Ua= foc_inv_clarke.Ua/VOTAGE_POWER_SUPPLY;
  110.         foc_output_duty.Ub= foc_inv_clarke.Ub/VOTAGE_POWER_SUPPLY;
  111.         foc_output_duty.Uc = foc_inv_clarke.Uc/VOTAGE_POWER_SUPPLY;
  112.         open_pwm.PWMa = foc_output_duty.Ua* PWM_COUNT;
  113.         open_pwm.PWMb = foc_output_duty.Ub * PWM_COUNT;
  114.         open_pwm.PWMc = foc_output_duty.Uc * PWM_COUNT;

  115.         FOC_PWMA=open_pwm.PWMa;
  116.         FOC_PWMB=open_pwm.PWMb;
  117.         FOC_PWMC=open_pwm.PWMc;


  118. }


  119. void SVPWM()
  120. {




  121. }









  1. #ifndef _FOC_H_
  2. #define _FOC_H_

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

  8. //foc模式控制
  9. #define CONTROL_MODE OPEN_CONTROL

  10. #define OPEN_CONTROL  0
  11. #define CLOSE_CONTROL 1



  12. #define PWM_AP_PORT                                                                        (CW_GPIOB)
  13. #define PWM_AP_PIN                                                                        (GPIO_PIN_5)
  14. #define PWM_AN_PORT                                                                        (CW_GPIOA)
  15. #define PWM_AN_PIN                                                                        (GPIO_PIN_15)

  16. #define PWM_BP_PORT                                                                        (CW_GPIOB)
  17. #define PWM_BP_PIN                                                                        (GPIO_PIN_6)
  18. #define PWM_BN_PORT                                                                        (CW_GPIOB)
  19. #define PWM_BN_PIN                                                                        (GPIO_PIN_3)

  20. #define PWM_CP_PORT                                                                        (CW_GPIOB)
  21. #define PWM_CP_PIN                                                                        (GPIO_PIN_7)
  22. #define PWM_CN_PORT                                                                        (CW_GPIOB)
  23. #define PWM_CN_PIN                                                                        (GPIO_PIN_4)

  24. #define FOC_PWMA                    CW_ATIM->CCR1
  25. #define FOC_PWMB                                                                                CW_ATIM->CCR2
  26. #define FOC_PWMC                                                                                 CW_ATIM->CCR3

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

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

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

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

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

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

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


  51. typedef struct
  52. {

  53. float U_x;
  54. float U_y;

  55. }U_xy;


  56. typedef struct
  57. {
  58. float Ua;
  59. float Ub;
  60. float Uc;
  61. }U_abc;

  62. typedef struct
  63. {
  64. uint16_t PWMa;
  65. uint16_t PWMb;
  66. uint16_t PWMc;
  67. }PWM_abc;


  68. extern unsigned int TimeCountCompuSpeed,TimeCountTemp,TimeCountSTDelay,Icount;


  69. void foc_control(float * motor_target);
  70. void foc_init(void);
  71. float _normalizeAngle(float angle);
  72. void foc_feedforward_path(void);

  73. #endif

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

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

  1. /*
  2. file:HALL.c
  3. user: Liushuangkai
  4. Email:331193752@qq.com

  5. release:0.1

  6. */
  7. #include "HALL.h"
  8. #include "cw32l011_gpio.h"

  9. #define HALL_INSTA  HALL_60

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

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

  15. uint8_t last_hall = 0xFF;  

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

  17. #if HALL_INSTA==HALL_60

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

  19. float Angle;


  20. void        angle_init()
  21. {

  22. Angle=0;
  23. }


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

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

  34. float hall_get_angle()
  35. {

  36. return Angle+3;

  37. }

  38. #elif HALL_INSTA == HALL_120


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


  40. void HALL_Callback()
  41. {
  42. }


  43. #endif




  44. unsigned char  HALL_Check(void)
  45. {
  46. //         static unsigned char hallerrnum=0;
  47.          unsigned char x=0;
  48.          if (GET_HALL_A==HALL_STATE_SET)x=0x01;
  49.          if (GET_HALL_B==HALL_STATE_SET)x|=0x2;
  50.          if (GET_HALL_C==HALL_STATE_SET)x|=0x4;
  51. //         if(x==0||x==7)
  52. //           {hallerrnum++;if(hallerrnum>=10){hallerrnum=10;}}//ErrorCode=2;}}
  53. //   else hallerrnum=0;
  54.          return x;
  55. }


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

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

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

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

  3. #include <stdint.h>

  4. #define  GET_HALL_A    GPIO_ReadPin(CW_GPIOA,GPIO_PIN_0)
  5. #define  GET_HALL_B    GPIO_ReadPin(CW_GPIOA,GPIO_PIN_1)
  6. #define  GET_HALL_C    GPIO_ReadPin(CW_GPIOA,GPIO_PIN_2)




  7. #define CAP 6U                 // 容量固定 6
  8. typedef struct {
  9.     uint8_t buf[CAP];
  10.     uint8_t  head;             // 读指针
  11.     uint8_t  tail;             // 写指针
  12. } Circ6_t;


  13. typedef enum
  14. {
  15.         DIR_CW = 1,
  16.         DIR_CCW = -1,
  17.         DIR_NONE = 0
  18. } Dir_t;// 方向结果


  19. typedef enum
  20. {
  21.   HALL_STATE_RESET = 0,
  22.   HALL_STATE_SET
  23. } HALL_State;


  24. unsigned char  HALL_Check(void);
  25. void HALL_Callback();
  26. void        angle_init();
  27. static inline Dir_t hall_dir(uint8_t last, uint8_t now);
  28. float hall_get_angle();


  29. #endif



最后我将CW32社区群挂在末端了{:lol:}
CW32生态社区QQ群(3群):610403240
CW32生态社区QQ群(4群):478586307

szt1993 发表于 2025-8-19 15:57 | 显示全部楼层
很不错活动
小小蚂蚁举千斤 发表于 2025-8-21 23:37 | 显示全部楼层
mos管焊接有点糙是图片的问题嘛?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

1

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部

1

主题

1

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部