本帖最后由 袁胜富 于 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);
- }
- }
- }
四、展示

工程源码在附件。
|