/****************************************************************************//** * @file main.c * @brief Hello world example file. * @version V1.0.0 * @date 1-May-2020 * @author Zhixin Semiconductor * * @note * Copyright (C) 2020 Zhixin Semiconductor Ltd. All rights reserved. * *******************************************************************************/ #include "Z20K11xM_drv.h" #include "Z20K11xM_tim.h" #include "Z20K11xM_gpio.h" #include "Z20K11xM_clock.h" #include "Z20K11xM_sysctrl.h" #include "Z20K11xM_wdog.h" #include "pwm.h" #include "Motor.h" #include "pwm_hall.h" #define PWM_TIM_ID TIM1_ID //typedef enum { // MOTOR_STOP, // 刹车 // MOTOR_FORWARD, // 正转 (INA=1, INB=0) // MOTOR_REVERSE // 反转 (INA=0, INB=1) //} Motor_Direction; int main() { /* Disable wdog */ WDOG_Disable(); /* Clock init */ CLK_OSC40MEnable2(CLK_OSC_FREQ_MODE_HIGH, ENABLE, CLK_OSC_XTAL); while(ERR == CLK_SysClkSrc(CLK_SYS_OSC40M)); /* Disable wdog */ WDOG_Disable(); CLK_ModuleSrc(CLK_PORTC, CLK_SRC_OSC40M); SYSCTRL_EnableModule(SYSCTRL_PORTC); SYSCTRL_EnableModule(SYSCTRL_GPIO); TIM_system_clock(); /*TIM independent PWM output*/ tim_IndependentPWMOutputInit(); /*start TIM PWM*/ TIM_StartCounter(PWM_TIM_ID, TIM_CLK_SOURCE_SYSTEM, TIM_CLK_DIVIDE_1); Motor_Init(); input_capture_test(); while(1){ // Motor_SetDirection(); GPIO_WritePinOutput(PORT_D, GPIO_3, GPIO_HIGH); //INA GPIO_WritePinOutput(PORT_D, GPIO_2, GPIO_LOW); //INB } } pwm.c /**************************************************************************************************/ /** * @file : main.c * @brief : TIM example file. * @version : V1.8.0 * @date : May-2020 * @author : Zhixin Semiconductor * * @note : This example contains sample code for customer evaluation purpose only. It is not * part of the production code deliverables. The example code is only tested under defined * environment with related context of the whole example project. Therefore, it is not guaranteed * that the example always works under user environment due to the diversity of hardware and * software environment. Do not use pieces copy of the example code without prior and separate * verification and validation in user environment. * * @copyright : Copyright (c) 2020-2023 Zhixin Semiconductor Ltd. All rights reserved. **************************************************************************************************/ #include "Z20K11xM_drv.h" #include "Z20K11xM_tim.h" #include "Z20K11xM_gpio.h" #include "Z20K11xM_clock.h" #include "Z20K11xM_sysctrl.h" #include "Z20K11xM_wdog.h" #include "pwm.h" #define PWM_TIM_ID TIM1_ID //Motor_PWM PTA1 TIM1_CH1 /*PWM Counter define----20K pwm output*/ #define PWM_MAX_COUNTER 800 //ARR void TIM_system_clock() { /* configure gpios */ CLK_ModuleSrc(CLK_PORTA, CLK_SRC_OSC40M); SYSCTRL_EnableModule(SYSCTRL_PORTA); SYSCTRL_EnableModule(SYSCTRL_GPIO); /*TIM clock source select*/ CLK_SetClkDivider(CLK_CORE, CLK_DIV_1); CLK_ModuleSrc(CLK_TIM1, CLK_SRC_OSC40M); CLK_SetClkDivider(CLK_TIM1, CLK_DIV_1); /*TIM module enable*/ SYSCTRL_ResetModule(SYSCTRL_TIM1); SYSCTRL_EnableModule(SYSCTRL_TIM1); } void tim_IndependentPWMOutputInit() { /* TIM PWM output config array*/ TIM_PwmChannelConfig_t cPwmChConfig[1] = { { .channelId = TIM_CHANNEL_1, .pwmModeConfig = TIM_PWM_HIGH_TRUE_PULSE, .polarity = TIM_POL_HIGH, .compareValue = (PWM_MAX_COUNTER * 8/ 100), .faultCtrlChannelEnable = DISABLE, .ccvUpdateEnable = ENABLE }, }; /* TIM PWM output Config*/ TIM_PwmConfig_t cPwmConfig = { 1, /*channel number*/ 0, /*counter init value*/ PWM_MAX_COUNTER, /*counter max value*/ cPwmChConfig /*channel config pointer*/ }; /*TIM reload config*/ TIM_ReloadConfig_t reloadConfig = { .reloadMode = TIM_RELOAD_FULL_CYCLE, .loadFrequency = 0, .numChannels = 0, .channelMatchConfig = NULL }; /*TIM sync config for update ccv*/ TIM_PwmSyncConfig_t syncConfig = { .cntinitSync = TIM_UPDATE_PWM_SYN, .outswcSync = TIM_UPDATE_PWM_SYN, .syncSWTriggerEnable = DISABLE, .syncReloadEnable = ENABLE, .reloadConfig = &reloadConfig }; /*only channel 0, gpio config, other channels need config too*/ PORT_PinmuxConfig(PORT_A, GPIO_1, PTA1_TIM1_CH1); /* set up-counting mode */ TIM_CountingModeConfig(PWM_TIM_ID, TIM_COUNTING_UP); /* output complementary init*/ TIM_OutputEdgeAlignedPwmConfig(PWM_TIM_ID, &cPwmConfig); /* reload config*/ TIM_SyncConfig(PWM_TIM_ID, &syncConfig); /* pair0 output enable */ TIM_ChannelOutputEnable(PWM_TIM_ID, TIM_CHANNEL_1); } pwm_hall.c #include "Z20K11xM_drv.h" #include "Z20K11xM_tim.h" #include "Z20K11xM_gpio.h" #include "Z20K11xM_clock.h" #include "Z20K11xM_sysctrl.h" #include "Z20K11xM_wdog.h" #include "pwm_hall.h" uint8_t i = 0; uint16_t ccvVal1[64]; uint16_t ccvVal2[64]; uint16_t getccv[64]; uint16_t getccvPe[64]; uint8_t intflag0 = 0; uint8_t intflag1 = 0; //HALL SA1: PTD16 TIM0_CH1 AND PTD15 TIM0_CH0 //HALL SA2: PTE9 TIM0_CH7 AND PTE8 TIM0_CH6 void PWM_HALL_system_clock() { /* configure gpios */ CLK_ModuleSrc(CLK_PORTA, CLK_SRC_OSC40M); SYSCTRL_EnableModule(SYSCTRL_PORTA); SYSCTRL_EnableModule(SYSCTRL_GPIO); CLK_ModuleSrc(CLK_PORTD, CLK_SRC_OSC40M); SYSCTRL_EnableModule(SYSCTRL_PORTD); SYSCTRL_EnableModule(SYSCTRL_GPIO); CLK_ModuleSrc(CLK_PORTE, CLK_SRC_OSC40M); SYSCTRL_EnableModule(SYSCTRL_PORTE); SYSCTRL_EnableModule(SYSCTRL_GPIO); /*TIM clock source select*/ CLK_SetClkDivider(CLK_CORE, CLK_DIV_1); CLK_ModuleSrc(CLK_TIM0, CLK_SRC_OSC40M); CLK_SetClkDivider(CLK_TIM0, CLK_DIV_1); /*TIM module enable*/ SYSCTRL_ResetModule(SYSCTRL_TIM0); SYSCTRL_EnableModule(SYSCTRL_TIM0); /* config pinmux, PTB12 CONNECT TO PTD16 PTE9 */ PORT_PinmuxConfig(PORT_A, GPIO_1, PTA1_TIM1_CH1); /* output Motor PWM*/ PORT_PinmuxConfig(PORT_D, GPIO_16, PTD16_TIM0_CH1); /* input HALL SA1*/ PORT_PinmuxConfig(PORT_D, GPIO_15, PTD15_TIM0_CH0); /* input HALL SA1*/ PORT_PinmuxConfig(PORT_E, GPIO_9, PTE9_TIM0_CH7); /* input HALL SA2*/ PORT_PinmuxConfig(PORT_E, GPIO_8, PTE8_TIM0_CH6); /* input HALL SA2*/ PORT_PullConfig(PORT_A, GPIO_1,PORT_PULL_DOWN); } void channel1_cbf() { /* get CCV value: read channel0 before channel1 */ ccvVal1[i] = TIM_GetCCVal(TIM0_ID, TIM_CHANNEL_0); ccvVal2[i] =TIM_GetCCVal(TIM0_ID, TIM_CHANNEL_1); i++; if(i == 64) { intflag0 = 1; TIM_StopCounter(TIM0_ID); } /* clear flag0 before flag1 */ TIM_IntClear(TIM0_ID, TIM_INT_CH0); TIM_IntClear(TIM0_ID, TIM_INT_CH1); } void channel2_cbf() { /* get CCV value: read channel1 before channel7 */ ccvVal1[i] = TIM_GetCCVal(TIM0_ID, TIM_CHANNEL_6); ccvVal2[i] =TIM_GetCCVal(TIM0_ID, TIM_CHANNEL_7); i++; if(i == 64) { intflag0 = 1; TIM_StopCounter(TIM0_ID); } /* clear flag0 before flag1 */ TIM_IntClear(TIM0_ID, TIM_INT_CH6); TIM_IntClear(TIM0_ID, TIM_INT_CH7); } void tim_init() { CLK_SetClkDivider(CLK_CORE, CLK_DIV_1); CLK_ModuleSrc(CLK_TIM0, CLK_SRC_OSC40M); CLK_ModuleSrc(CLK_TIM1, CLK_SRC_OSC40M); SYSCTRL_ResetModule(SYSCTRL_TIM0); SYSCTRL_EnableModule(SYSCTRL_TIM0); SYSCTRL_ResetModule(SYSCTRL_TIM1); SYSCTRL_EnableModule(SYSCTRL_TIM1); /* input config, the TIM input channel should be in low level if it is set to capture rising edge first when TIM is in input capture mode*/ /* TIM input capture channel config struct initial:channelId, falling,rising, disable filter, continue capture */ TIM_DualEdgeChannelConfig_t chconfig1 = { TIM_PAIR_CHANNEL_0, TIM_INPUT_EDGE_RISING, TIM_INPUT_EDGE_FAILING, TIM_INPUT_FILTER_DISABLED, TIM_CONTINUOUS_PULSE_CAPTURE }; TIM_DualEdgeChannelConfig_t chconfig2 = { TIM_PAIR_CHANNEL_3, TIM_INPUT_EDGE_RISING, TIM_INPUT_EDGE_FAILING, TIM_INPUT_FILTER_DISABLED, TIM_CONTINUOUS_PULSE_CAPTURE }; /* TIM input capture global config struct initial: number 1,mod value 0xFFFF, input capture channel config struct */ const TIM_DualEdgeCaptureConfig_t config1 = { 1, 0xFFFF, &chconfig1 }; const TIM_DualEdgeCaptureConfig_t config2 = { 1, 0xFFFF, &chconfig2 }; /*input capture init*/ TIM_DualEdgeCaptureInit(TIM0_ID, &config1); TIM_SetCounterInitialVal(TIM0_ID, 0x0000); } void input_capture_test() { /* callback function */ TIM_InstallCallBackFunc(TIM0_ID, TIM_INT_CH1, channel1_cbf); TIM_InstallCallBackFunc(TIM0_ID, TIM_INT_CH7, channel1_cbf); /* counting mode: up counting mode */ TIM_CountingModeConfig(TIM0_ID, TIM_COUNTING_UP); TIM_CountingModeConfig(TIM1_ID, TIM_COUNTING_UP); /*start counter*/ TIM_StartCounter(TIM0_ID, TIM_CLK_SOURCE_SYSTEM, TIM_CLK_DIVIDE_1); /* reload flag clear */ TIM_IntClear(TIM0_ID, TIM_INT_RLD); /* clear CHF before dual edge capture */ TIM_IntClear(TIM0_ID, TIM_INT_CH0); TIM_IntClear(TIM0_ID, TIM_INT_CH1); TIM_IntClear(TIM0_ID, TIM_INT_CH6); TIM_IntClear(TIM0_ID, TIM_INT_CH7); /* enable the interrupt */ TIM_IntMask(TIM0_ID, TIM_INT_CH1, UNMASK); TIM_IntMask(TIM0_ID, TIM_INT_CH7, UNMASK); /* enable IRQ*/ NVIC_EnableIRQ(TIM0_IRQn); while(intflag0 == 0); for (int k = 0; k < 64; k++) { if (ccvVal1[k] < ccvVal2[k]) { getccv[k] = ccvVal2[k] - ccvVal1[k]; } else { getccv[k] = ccvVal2[k] + 65536 - ccvVal1[k]; } } } 根据这几份程序文件来看,我的HALL SA1和 HALL SA2可以成功捕获了吗
时间: 2025-06-01 19:03:57 浏览: 10
### 确认HALL SA1和HALL SA2输入捕获功能是否正常工作的方法
为了验证HALL SA1和HALL SA2的输入捕获功能是否正常工作,可以通过以下步骤实现。以下是详细的分析与代码示例。
#### 1. 配置定时器通道以支持输入捕获
在嵌入式系统中,通常使用定时器模块来捕获外部信号的边沿变化。对于HALL SA1 (PTD16 TIM0_CH1 和 PTD15 TIM0_CH0) 和 HALL SA2 (PTE9 TIM0_CH7 和 PTE8 TIM0_CH6),需要确保定时器的输入捕获功能已正确配置[^1]。
```c
// 配置TIM0定时器以支持输入捕获
void configure_timer_input_capture(void) {
// 启用时钟
SIM_SCGC |= SIM_SCGC_TIM0;
// 配置TIM0为输入捕获模式
TIM0_MCR = 0x0; // 模式控制寄存器:停止计数器溢出中断
TIM0_CNT = 0x0; // 清零计数器
// 配置通道1和通道0为输入捕获模式
TIM0_C0SC = 0x30; // 通道0:输入捕获,上升沿触发
TIM0_C1SC = 0x30; // 通道1:输入捕获,上升沿触发
// 配置通道7和通道6为输入捕获模式
TIM0_C7SC = 0x30; // 通道7:输入捕获,上升沿触发
TIM0_C6SC = 0x30; // 通道6:输入捕获,上升沿触发
}
```
#### 2. 配置GPIO引脚作为定时器输入捕获源
确保PTD16、PTD15、PTE9和PTE8被正确配置为定时器输入捕获的源引脚[^2]。
```c
// 配置GPIO引脚为定时器输入捕获源
void configure_gpio_for_input_capture(void) {
// 配置PTD16和PTD15为TIM0_CH1和TIM0_CH0
PORTD_PCR16 = PORT_PCR_MUX(4); // PTD16复用为TIM0_CH1
PORTD_PCR15 = PORT_PCR_MUX(4); // PTD15复用为TIM0_CH0
// 配置PTE9和PTE8为TIM0_CH7和TIM0_CH6
PORTE_PCR9 = PORT_PCR_MUX(4); // PTE9复用为TIM0_CH7
PORTE_PCR8 = PORT_PCR_MUX(4); // PTE8复用为TIM0_CH6
}
```
#### 3. 捕获并处理输入信号
通过读取定时器的捕获寄存器值,可以确认信号是否被成功捕获。如果捕获寄存器值发生变化,则说明输入捕获功能正常工作[^3]。
```c
// 捕获并处理输入信号
void capture_and_process_signal(void) {
uint16_t capture_value_ch0, capture_value_ch1;
uint16_t capture_value_ch6, capture_value_ch7;
// 读取通道0和通道1的捕获值
capture_value_ch0 = TIM0_C0V;
capture_value_ch1 = TIM0_C1V;
// 读取通道6和通道7的捕获值
capture_value_ch6 = TIM0_C6V;
capture_value_ch7 = TIM0_C7V;
// 打印捕获值以验证功能
printf("Capture CH0: %d\n", capture_value_ch0);
printf("Capture CH1: %d\n", capture_value_ch1);
printf("Capture CH6: %d\n", capture_value_ch6);
printf("Capture CH7: %d\n", capture_value_ch7);
}
```
#### 4. 测试与验证
在实际测试中,可以使用示波器或逻辑分析仪观察PTD16、PTD15、PTE9和PTE8上的信号,并与程序捕获的结果进行对比。如果捕获值与实际信号一致,则说明输入捕获功能正常工作[^4]。
---
###
阅读全文