打印
[USB芯片]

【CH32X035评估板测评】+ 高级定时器TIM2测量霍尔PCB相位差

[复制链接]
1682|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
袁胜富|  楼主 | 2023-10-10 23:50 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 袁胜富 于 2023-10-12 09:05 编辑

#申请原创#
一、概述


CH32X035拥有两个高级定时器,TIM1和TIM2,每个定时器拥有四个输入通道,可以输出PWM也可以捕获PWM,平时也可以作为通用定时器使用。
在无刷有霍尔感应的电机,每一个电机需要一个霍尔板,霍尔板上有三颗霍尔元件,通用感应磁场位置进行编码,从而进行六步换相。在生产霍尔板时,需要对其进行良品测试,一般治具下面放个旋转电机,电机轴上放一个磁铁,转动电机模拟磁场变化,在盘上开辟可以完全同心的位置固定霍尔PCB板,当电机转动磁场变化产生霍尔信号,捕获霍尔信号的两两之间的相位差可以判定霍尔PCB的好坏。
此篇评测的是利用CH32X035的TIM2高级定时器外设捕获霍尔的三个信号,计算相位差,从而知道霍尔板的好坏。有兴趣或者有需要完整方案的人士可以联系我。
于是乎为了和大家分享,我出了这个文章。


二、原理分析和硬件连接

原理分析

图1如上图1
所示U1、U2和U3都是霍尔元件,一般公司生产需要测量硬件的好坏,在制作测试治具时一般需要使用定时器的输入捕获功能。

图2
记H1的上升沿时刻为T1,记H2的上升沿时刻为T2,记H3的上升沿时刻为T3,周期为T。
H1和H2两个霍尔之间的相位差计算公式如下:

H2和H3两个霍尔之间的相位差计算公式如下:

硬件连接
霍尔板开发板
Hall1------>PA0
Hall2------>PA1
Hall3------>PA2
VCC------->VCC
GND------->GND


三、代码


HALL.H代码:
#ifndef __HALL_H
#define __HALL_H

#include "debug.h"
#include "String.h"
#include "Stdlib.h"
#include "Stdio.h"
#include "Stdarg.h"
#include "ctype.h"

typedef struct
{
    float        Current_H1_H2_Phase_Diff;//H1和H2的相位差的当前测量值
    float        LowerLimit_H1_H2_Phase_Diff;//H1和H2的相位差的下限值
    float        UpperLimit_H1_H2_Phase_Diff;//H1和H2的相位差的上限值

    float        Current_H2_H3_Phase_Diff;//H2和H3的相位差的当前测量值
    float        LowerLimit_H2_H3_Phase_Diff;//H2和H3的相位差的下限值
    float        UpperLimit_H2_H3_Phase_Diff;//H2和H3的相位差的上限值

    float        Current_NTC_ADC_Value;//敏电阻电压当前测量值
    float        LowerLimit_NTC_ADC_Value;//热敏电阻电压下限值
    float        UpperLimit_NTC_ADC_Value;//热敏电阻电压上限值

    float        Motor_DIR;//电机的转向设置---》1正转----》0反转

    float        Hall_Board_Relay_Time;
}Hall_DATA_TYPEDEF;

extern Hall_DATA_TYPEDEF HALL_Capture_Data;
extern volatile int HFlag;
extern volatile int H1_Value;
extern volatile int H2_Value;
extern volatile int H3_Value;

void  Hall_Singal_Captrue(void);
#endif


Hall.c代码
#include "Hall.h"

Hall_DATA_TYPEDEF HALL_Capture_Data ={0,0,0,0,0,0,0,0,0,0,0};
volatile int Over_flower=0;
volatile int H1_Value=0;
volatile int H2_Value=0;
volatile int H3_Value=0;
volatile int HFlag=0;
volatile int temp=0;
volatile int  f1=0,f2=0,f3=1;


void TIM2_CC_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void TIM2_UP_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));

void  Hall_Singal_Captrue(void)
{
    GPIO_InitTypeDef GPIO_InitStructure={0};
    TIM_ICInitTypeDef TIM_ICInitStructure={0};
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure={0};
    NVIC_InitTypeDef NVIC_InitStructure={0};

    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE );
    RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM2, ENABLE );

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init( GPIOA, &GPIO_InitStructure);

    TIM_TimeBaseInitStructure.TIM_Period = 0xFFFF - 1;
    TIM_TimeBaseInitStructure.TIM_Prescaler = 48-1;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter =  0x00;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);


    TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    TIM_ICInitStructure.TIM_ICFilter = 0x00;
    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
    TIM_ICInit(TIM2, &TIM_ICInitStructure );

    TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    TIM_ICInitStructure.TIM_ICFilter = 0x00;
    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
    TIM_ICInit(TIM2, &TIM_ICInitStructure );

    TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;
    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    TIM_ICInitStructure.TIM_ICFilter = 0x00;
    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
    TIM_ICInit(TIM2, &TIM_ICInitStructure );

    NVIC_InitStructure.NVIC_IRQChannel = TIM2_UP_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = TIM2_CC_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    TIM_ITConfig( TIM2, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_Update, ENABLE );
    TIM_ClearITPendingBit(TIM2, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_Update);

    TIM_Cmd( TIM2, ENABLE );
}


void TIM2_UP_IRQHandler(void)
{
    if(TIM_GetFlagStatus(TIM2, TIM_FLAG_Update) != RESET)
    {
        if(TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET)
        {
            Over_flower++;
        }
    }
    TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}

void TIM2_CC_IRQHandler(void)
{
    if(TIM_GetFlagStatus(TIM2, TIM_FLAG_CC1)!= RESET)
    {
        if(TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)
        {
            if(f3 == 1)
            {
                H1_Value = (TIM2->CNT + 1) + (Over_flower * 65536);
                HFlag = 1;
                TIM_SetCounter(TIM2, 0);
                Over_flower = 0;
                f3 = 0;
                f1 = 1;
            }
        }
    }

    if(TIM_GetFlagStatus(TIM2, TIM_FLAG_CC2)!= RESET)
    {
        if(TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET)
        {
            if(f1 == 1)
            {
                H2_Value = (TIM2->CNT + 1) + (Over_flower * 65536);
                f2 = 1;
                f1= 0 ;
            }
        }
    }
    if(TIM_GetFlagStatus(TIM2, TIM_FLAG_CC3)!= RESET)
    {
        if(TIM_GetITStatus(TIM2, TIM_IT_CC3) != RESET)
        {
            if(f2 == 1)
            {
                H3_Value = (TIM2->CNT + 1) + (Over_flower * 65536);
                f2 = 0;
                f3 = 1;
            }
        }
    }

    TIM_ClearITPendingBit(TIM2, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3);
}

Main.c代码
#include <stdio.h>
#include "debug.h"
#include "Hall.h"

u8 H1=0,H2=0,H3=0;
float UV_Temp=0.0;
float VW_Temp=0.0;
int NTC_Temp = 0;
float ntc_Temp=0.0;
float UV=0.0;
float VW=0.0;


/*********************************************************************
* @fn      main
*
* [url=home.php?mod=space&uid=247401]@brief[/url]   Main program.
*
* [url=home.php?mod=space&uid=266161]@return[/url]  none
*/
int main(void)
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    SystemCoreClockUpdate();
    Delay_Init();
    USART_Printf_Init(115200);
    Hall_Singal_Captrue();//波形捕获定时器初始化
    while(1)
    {
        if(HFlag == 1)
        {
            HFlag= 0;
            HALL_Capture_Data.Current_H1_H2_Phase_Diff = ((float)H2_Value/(float)H1_Value)*360.0;
            HALL_Capture_Data.Current_H2_H3_Phase_Diff = ((float)(H3_Value -H2_Value)/(float)H1_Value)*360.0;

            printf("UV_Value=%f\r\n",HALL_Capture_Data.Current_H1_H2_Phase_Diff);
            printf("VW_Value=%f\r\n\r\n",HALL_Capture_Data.Current_H1_H2_Phase_Diff);

        }
    }
}




四、展示




工程源码在附件。

CH32X035C8T6_HallAngle.zip

545.06 KB

使用特权

评论回复
沙发
tpgf| | 2024-1-18 18:42 | 只看该作者
我能理解相位差,但是不能理解什么叫做pcb相位差

使用特权

评论回复
板凳
wakayi| | 2024-1-18 19:19 | 只看该作者
只有高级定时器才具有捕获比较的功能吧

使用特权

评论回复
评论
LIzs6 2024-1-19 13:58 回复TA
其他不清楚,CH32、STM32的高级定时器和通用定时器都具有输入捕获和输出比较功能 
地板
paotangsan| | 2024-1-19 08:08 | 只看该作者
如果波形不是方波而是正弦波的话 这个相位差就不那么好测了吧

使用特权

评论回复
5
renzheshengui| | 2024-1-19 08:52 | 只看该作者
这种相位差使用普通的定时器可以进行测量吗

使用特权

评论回复
6
wowu| | 2024-1-19 09:29 | 只看该作者
这种采集方式还需要对外部电路进行防抖设计吗

使用特权

评论回复
7
xiaoqizi| | 2024-1-19 10:11 | 只看该作者
这个和能感应到的磁通量有关系吗

使用特权

评论回复
8
袁胜富|  楼主 | 2024-1-21 13:46 | 只看该作者
xiaoqizi 发表于 2024-1-19 10:11
这个和能感应到的磁通量有关系吗


使用特权

评论回复
9
袁胜富|  楼主 | 2024-1-21 13:47 | 只看该作者
wowu 发表于 2024-1-19 09:29
这种采集方式还需要对外部电路进行防抖设计吗

看情况

使用特权

评论回复
10
袁胜富|  楼主 | 2024-1-21 13:47 | 只看该作者
renzheshengui 发表于 2024-1-19 08:52
这种相位差使用普通的定时器可以进行测量吗

带捕获功能定时器就可以

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

23

主题

131

帖子

2

粉丝