完成定时器驱动

This commit is contained in:
MQjehovah 2023-08-23 11:05:48 +08:00
parent 70aa497a47
commit cdbd5c4bfd
15 changed files with 796 additions and 9 deletions

View File

@ -10,8 +10,8 @@
<TargetName>stm32f407_template</TargetName> <TargetName>stm32f407_template</TargetName>
<ToolsetNumber>0x4</ToolsetNumber> <ToolsetNumber>0x4</ToolsetNumber>
<ToolsetName>ARM-ADS</ToolsetName> <ToolsetName>ARM-ADS</ToolsetName>
<pCCUsed>5060960::V5.06 update 7 (build 960)::.\ARMCC</pCCUsed> <pCCUsed>6150000::V6.15::ARMCLANG</pCCUsed>
<uAC6>0</uAC6> <uAC6>1</uAC6>
<TargetOption> <TargetOption>
<TargetCommonOption> <TargetCommonOption>
<Device>STM32F407ZGTx</Device> <Device>STM32F407ZGTx</Device>
@ -313,7 +313,7 @@
</ArmAdsMisc> </ArmAdsMisc>
<Cads> <Cads>
<interw>1</interw> <interw>1</interw>
<Optim>4</Optim> <Optim>2</Optim>
<oTime>0</oTime> <oTime>0</oTime>
<SplitLS>0</SplitLS> <SplitLS>0</SplitLS>
<OneElfS>1</OneElfS> <OneElfS>1</OneElfS>
@ -328,7 +328,7 @@
<uC99>1</uC99> <uC99>1</uC99>
<uGnu>0</uGnu> <uGnu>0</uGnu>
<useXO>0</useXO> <useXO>0</useXO>
<v6Lang>5</v6Lang> <v6Lang>3</v6Lang>
<v6LangP>3</v6LangP> <v6LangP>3</v6LangP>
<vShortEn>1</vShortEn> <vShortEn>1</vShortEn>
<vShortWch>1</vShortWch> <vShortWch>1</vShortWch>
@ -478,6 +478,11 @@
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\src\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_uart.c</FilePath> <FilePath>..\..\src\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_uart.c</FilePath>
</File> </File>
<File>
<FileName>stm32f4xx_ll_tim.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_tim.c</FilePath>
</File>
</Files> </Files>
</Group> </Group>
<Group> <Group>
@ -513,6 +518,11 @@
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\src\Bsp\stm32f4xx_it.c</FilePath> <FilePath>..\..\src\Bsp\stm32f4xx_it.c</FilePath>
</File> </File>
<File>
<FileName>timer.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\Bsp\timer.c</FilePath>
</File>
</Files> </Files>
</Group> </Group>
</Groups> </Groups>

View File

@ -39,7 +39,7 @@ void SystemClock_Config(void)
RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 8; RCC_OscInitStruct.PLL.PLLM = 25;
RCC_OscInitStruct.PLL.PLLN = 336; RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4; RCC_OscInitStruct.PLL.PLLQ = 4;

View File

@ -42,11 +42,11 @@ void led_ctrl(uint8_t cmd)
{ {
if (cmd) if (cmd)
{ {
HAL_GPIO_WritePin(LED1_GPIO_Port, LED0_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, GPIO_PIN_SET);
} }
else else
{ {
HAL_GPIO_WritePin(LED1_GPIO_Port, LED0_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, GPIO_PIN_RESET);
} }
} }

View File

@ -18,7 +18,7 @@ extern "C"
/* Includes ------------------------------------------------------------------*/ /* Includes ------------------------------------------------------------------*/
#include "main.h" #include "stm32f4xx_hal.h"
#define LED0_Pin GPIO_PIN_15 #define LED0_Pin GPIO_PIN_15
#define LED0_GPIO_Port GPIOA #define LED0_GPIO_Port GPIOA

View File

@ -62,7 +62,7 @@
/* #define HAL_SD_MODULE_ENABLED */ /* #define HAL_SD_MODULE_ENABLED */
/* #define HAL_MMC_MODULE_ENABLED */ /* #define HAL_MMC_MODULE_ENABLED */
/* #define HAL_SPI_MODULE_ENABLED */ /* #define HAL_SPI_MODULE_ENABLED */
/* #define HAL_TIM_MODULE_ENABLED */ #define HAL_TIM_MODULE_ENABLED
#define HAL_UART_MODULE_ENABLED #define HAL_UART_MODULE_ENABLED
/* #define HAL_USART_MODULE_ENABLED */ /* #define HAL_USART_MODULE_ENABLED */
/* #define HAL_IRDA_MODULE_ENABLED */ /* #define HAL_IRDA_MODULE_ENABLED */

282
src/Bsp/timer.c Normal file
View File

@ -0,0 +1,282 @@
/**
* @file timer.c
* @author jimingqing
* @date 2023-08-14
* @version 0.0.1
* @copyright XiazhiTech Copyright (c) 2023
*
* @brief
*/
/* Includes ------------------------------------------------------------------*/
#include "timer.h"
#include "board.h"
#include "stm32f4xx_ll_tim.h"
TIM_HandleTypeDef htim1;
TIM_HandleTypeDef htim3;
/**
* @brief TIM1 Initialization Function
* @param None
* @retval None
*/
void MX_TIM1_Init(void)
{
TIM_SlaveConfigTypeDef sSlaveConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
/**
* 84M
*/
htim1.Instance = TIM1;
htim1.Init.Prescaler = 0;
htim1.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED1;
htim1.Init.Period = (84 * 1000000 / 16000);
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV2;
htim1.Init.RepetitionCounter = 1;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
sSlaveConfig.SlaveMode = TIM_SLAVEMODE_TRIGGER;
sSlaveConfig.InputTrigger = TIM_TS_ITR1;
if (HAL_TIM_SlaveConfigSynchro(&htim1, &sSlaveConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM2;
sConfigOC.Pulse = ((84 * 1000000 / 16000) - 1);
if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
{
Error_Handler();
}
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_ENABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_ENABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_1;
// sBreakDeadTimeConfig.DeadTime = ((DEAD_TIME_COUNTS) / 2);
sBreakDeadTimeConfig.DeadTime = 100;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_LOW;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief TIM3 Initialization Function
* @param None
* @retval None
*/
void MX_TIM3_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_HallSensor_InitTypeDef sConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
htim3.Instance = TIM3;
htim3.Init.Prescaler = 0;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 65535;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
sConfig.IC1Filter = 11;
sConfig.Commutation_Delay = 0;
if (HAL_TIMEx_HallSensor_Init(&htim3, &sConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC2REF;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief TIM_Base MSP Initialization
* This function configures the hardware resources used in this example
* @param htim_base: TIM_Base handle pointer
* @retval None
*/
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim_base)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if (htim_base->Instance == TIM1)
{
/* Peripheral clock enable */
__HAL_RCC_TIM1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**TIM1 GPIO Configuration
PA10 ------> TIM1_CH3
PA9 ------> TIM1_CH2
PA8 ------> TIM1_CH1
PB13 ------> TIM1_CH1N
PB14 ------> TIM1_CH2N
PB15 ------> TIM1_CH3N
*/
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
else if (htim_base->Instance == TIM3)
{
/* Peripheral clock enable */
__HAL_RCC_TIM3_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/**TIM3 GPIO Configuration
PC8 ------> TIM3_CH3
PC7 ------> TIM3_CH2
PC6 ------> TIM3_CH1
*/
GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}
}
/**
* @brief TIM_Base MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param htim_base: TIM_Base handle pointer
* @retval None
*/
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef *htim_base)
{
if (htim_base->Instance == TIM1)
{
/* Peripheral clock disable */
__HAL_RCC_TIM1_CLK_DISABLE();
/* TIM1 interrupt DeInit */
HAL_NVIC_DisableIRQ(TIM1_BRK_TIM9_IRQn);
HAL_NVIC_DisableIRQ(TIM1_UP_TIM10_IRQn);
}
else if (htim_base->Instance == TIM3)
{
/* Peripheral clock disable */
__HAL_RCC_TIM3_CLK_DISABLE();
/**TIM3 GPIO Configuration
PC8 ------> TIM3_CH3
PC7 ------> TIM3_CH2
PC6 ------> TIM3_CH1
*/
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8);
/* TIM3 interrupt DeInit */
HAL_NVIC_DisableIRQ(TIM3_IRQn);
}
}
/**
* @brief This function handles first motor TIMx Update interrupt request.
* @param None
* @retval None
*/
void TIM1_UP_TIM10_IRQHandler(void)
{
// LL_TIM_ClearFlag_UPDATE(PWM_Handle_M1.pParams_str->TIMx);
// R3_2_TIMx_UP_IRQHandler(&PWM_Handle_M1);
}
/**
* @brief This function handles first motor BRK interrupt.
* @param None
* @retval None
*/
void TIM1_BRK_TIM9_IRQHandler(void)
{
// if (LL_TIM_IsActiveFlag_BRK(PWM_Handle_M1.pParams_str->TIMx))
// {
// LL_TIM_ClearFlag_BRK(PWM_Handle_M1.pParams_str->TIMx);
// R3_2_BRK_IRQHandler(&PWM_Handle_M1);
// }
// /* Systick is not executed due low priority so is necessary to call MC_Scheduler here.*/
// MC_Scheduler();
}
/**
* @brief This function handles TIMx global interrupt request for M1 Speed Sensor.
* @param None
* @retval None
*/
void TIM3_IRQHandler(void)
{
/* HALL Timer Update IT always enabled, no need to check enable UPDATE state */
if (LL_TIM_IsActiveFlag_UPDATE(TIM3))
{
LL_TIM_ClearFlag_UPDATE(TIM3);
// HALL_TIMx_UP_IRQHandler(&HALL_M1);
}
/* HALL Timer CC1 IT always enabled, no need to check enable CC1 state */
if (LL_TIM_IsActiveFlag_CC1(TIM3))
{
LL_TIM_ClearFlag_CC1(TIM3);
// HALL_TIMx_CC_IRQHandler(&HALL_M1);
}
}

30
src/Bsp/timer.h Normal file
View File

@ -0,0 +1,30 @@
/**
* @file gpio.h
* @author jimingqing
* @date 2023-08-14
* @version 0.0.1
* @copyright XiazhiTech Copyright (c) 2023
*
* @brief
*/
#ifndef __TIMER_H__
#define __TIMER_H__
#ifdef __cplusplus
extern "C"
{
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"
void MX_TIM1_Init(void);
#ifdef __cplusplus
}
#endif
#endif /*__ __TIMER_H__ */
/* END OF FILE ---------------------------------------------------------------*/

116
src/Foc/hall.c Normal file
View File

@ -0,0 +1,116 @@
#include "hall.h"
/**
* @brief HALL状态
* @param handle
* @param new_state
*/
void calc_hall_angle(hall_handle_t *handle, uint8_t new_state)
{
switch (new_state)
{
case HALL_STATE_5:
if (handle->state == HALL_STATE_4)
{
handle->Direction = POSITIVE;
handle->MeasuredElAngle = handle->PhaseShift;
}
else if (handle->state == HALL_STATE_1)
{
handle->Direction = NEGATIVE;
handle->MeasuredElAngle = (int16_t)(handle->PhaseShift + S16_60_PHASE_SHIFT);
}
else
{
}
break;
case HALL_STATE_1:
if (handle->state == HALL_STATE_5)
{
handle->Direction = POSITIVE;
handle->MeasuredElAngle = handle->PhaseShift + S16_60_PHASE_SHIFT;
}
else if (handle->state == HALL_STATE_3)
{
handle->Direction = NEGATIVE;
handle->MeasuredElAngle = (int16_t)(handle->PhaseShift + S16_120_PHASE_SHIFT);
}
else
{
}
break;
case HALL_STATE_3:
if (handle->state == HALL_STATE_1)
{
handle->Direction = POSITIVE;
handle->MeasuredElAngle = (int16_t)(handle->PhaseShift + S16_120_PHASE_SHIFT);
}
else if (handle->state == HALL_STATE_2)
{
handle->Direction = NEGATIVE;
handle->MeasuredElAngle = (int16_t)(handle->PhaseShift + S16_120_PHASE_SHIFT +
S16_60_PHASE_SHIFT);
}
else
{
}
break;
case HALL_STATE_2:
if (handle->state == HALL_STATE_3)
{
handle->Direction = POSITIVE;
handle->MeasuredElAngle = (int16_t)(handle->PhaseShift + S16_120_PHASE_SHIFT + S16_60_PHASE_SHIFT);
}
else if (handle->state == HALL_STATE_6)
{
handle->Direction = NEGATIVE;
handle->MeasuredElAngle = (int16_t)(handle->PhaseShift - S16_120_PHASE_SHIFT);
}
else
{
}
break;
case HALL_STATE_6:
if (handle->state == HALL_STATE_2)
{
handle->Direction = POSITIVE;
handle->MeasuredElAngle = (int16_t)(handle->PhaseShift - S16_120_PHASE_SHIFT);
}
else if (handle->state == HALL_STATE_4)
{
handle->Direction = NEGATIVE;
handle->MeasuredElAngle = (int16_t)(handle->PhaseShift - S16_60_PHASE_SHIFT);
}
else
{
}
break;
case HALL_STATE_4:
if (handle->state == HALL_STATE_6)
{
handle->Direction = POSITIVE;
handle->MeasuredElAngle = (int16_t)(handle->PhaseShift - S16_60_PHASE_SHIFT);
}
else if (handle->state == HALL_STATE_5)
{
handle->Direction = NEGATIVE;
handle->MeasuredElAngle = (int16_t)(handle->PhaseShift);
}
else
{
}
break;
default:
/* Bad hall sensor configutarion so update the speed reliability */
handle->SensorIsReliable = false;
break;
}
}

44
src/Foc/hall.h Normal file
View File

@ -0,0 +1,44 @@
/**
* @file hall.h
* @author jimingqing
* @date 2023-05-25
* @version 0.0.1
* @copyright XiazhiTech Copyright (c) 2023
*
* @brief
*/
#include "stm32f407xx.h"
#define HALL_STATE_0 (uint8_t)0
#define HALL_STATE_1 (uint8_t)1
#define HALL_STATE_2 (uint8_t)2
#define HALL_STATE_3 (uint8_t)3
#define HALL_STATE_4 (uint8_t)4
#define HALL_STATE_5 (uint8_t)5
#define HALL_STATE_6 (uint8_t)6
#define HALL_STATE_7 (uint8_t)7
#define S16_120_PHASE_SHIFT (int16_t)(65536 / 3)
#define S16_60_PHASE_SHIFT (int16_t)(65536 / 6)
enum
{
NEGATIVE = -1,
POSITIVE = 1,
}
typedef struct
{
// |||
// |||
// |||
uint8_t state; // 霍尔状态真值表
int16_t phase_shift; // 同步电角度
int8_t direction; // 转子方向
int16_t measure_elec_angle; // 测量转子电角度
int16_t control_elec_angle; // 控制转子电角度
} hall_handle_t;

11
src/Foc/main.c Normal file
View File

@ -0,0 +1,11 @@
int main()
{
/**
*
* 1.
* 2.
*/
}

110
src/Foc/math.c Normal file
View File

@ -0,0 +1,110 @@
#include "math.h"
#define SIN_MASK 0x0300u
#define U0_90 0x0200u
#define U90_180 0x0300u
#define U180_270 0x0000u
#define U270_360 0x0100u
const int16_t hSin_Cos_Table[256] = {
0x0000, 0x00C9, 0x0192, 0x025B, 0x0324, 0x03ED, 0x04B6, 0x057F,
0x0648, 0x0711, 0x07D9, 0x08A2, 0x096A, 0x0A33, 0x0AFB, 0x0BC4,
0x0C8C, 0x0D54, 0x0E1C, 0x0EE3, 0x0FAB, 0x1072, 0x113A, 0x1201,
0x12C8, 0x138F, 0x1455, 0x151C, 0x15E2, 0x16A8, 0x176E, 0x1833,
0x18F9, 0x19BE, 0x1A82, 0x1B47, 0x1C0B, 0x1CCF, 0x1D93, 0x1E57,
0x1F1A, 0x1FDD, 0x209F, 0x2161, 0x2223, 0x22E5, 0x23A6, 0x2467,
0x2528, 0x25E8, 0x26A8, 0x2767, 0x2826, 0x28E5, 0x29A3, 0x2A61,
0x2B1F, 0x2BDC, 0x2C99, 0x2D55, 0x2E11, 0x2ECC, 0x2F87, 0x3041,
0x30FB, 0x31B5, 0x326E, 0x3326, 0x33DF, 0x3496, 0x354D, 0x3604,
0x36BA, 0x376F, 0x3824, 0x38D9, 0x398C, 0x3A40, 0x3AF2, 0x3BA5,
0x3C56, 0x3D07, 0x3DB8, 0x3E68, 0x3F17, 0x3FC5, 0x4073, 0x4121,
0x41CE, 0x427A, 0x4325, 0x43D0, 0x447A, 0x4524, 0x45CD, 0x4675,
0x471C, 0x47C3, 0x4869, 0x490F, 0x49B4, 0x4A58, 0x4AFB, 0x4B9D,
0x4C3F, 0x4CE0, 0x4D81, 0x4E20, 0x4EBF, 0x4F5D, 0x4FFB, 0x5097,
0x5133, 0x51CE, 0x5268, 0x5302, 0x539B, 0x5432, 0x54C9, 0x5560,
0x55F5, 0x568A, 0x571D, 0x57B0, 0x5842, 0x58D3, 0x5964, 0x59F3,
0x5A82, 0x5B0F, 0x5B9C, 0x5C28, 0x5CB3, 0x5D3E, 0x5DC7, 0x5E4F,
0x5ED7, 0x5F5D, 0x5FE3, 0x6068, 0x60EB, 0x616E, 0x61F0, 0x6271,
0x62F1, 0x6370, 0x63EE, 0x646C, 0x64E8, 0x6563, 0x65DD, 0x6656,
0x66CF, 0x6746, 0x67BC, 0x6832, 0x68A6, 0x6919, 0x698B, 0x69FD,
0x6A6D, 0x6ADC, 0x6B4A, 0x6BB7, 0x6C23, 0x6C8E, 0x6CF8, 0x6D61,
0x6DC9, 0x6E30, 0x6E96, 0x6EFB, 0x6F5E, 0x6FC1, 0x7022, 0x7083,
0x70E2, 0x7140, 0x719D, 0x71F9, 0x7254, 0x72AE, 0x7307, 0x735E,
0x73B5, 0x740A, 0x745F, 0x74B2, 0x7504, 0x7555, 0x75A5, 0x75F3,
0x7641, 0x768D, 0x76D8, 0x7722, 0x776B, 0x77B3, 0x77FA, 0x783F,
0x7884, 0x78C7, 0x7909, 0x794A, 0x7989, 0x79C8, 0x7A05, 0x7A41,
0x7A7C, 0x7AB6, 0x7AEE, 0x7B26, 0x7B5C, 0x7B91, 0x7BC5, 0x7BF8,
0x7C29, 0x7C59, 0x7C88, 0x7CB6, 0x7CE3, 0x7D0E, 0x7D39, 0x7D62,
0x7D89, 0x7DB0, 0x7DD5, 0x7DFA, 0x7E1D, 0x7E3E, 0x7E5F, 0x7E7E,
0x7E9C, 0x7EB9, 0x7ED5, 0x7EEF, 0x7F09, 0x7F21, 0x7F37, 0x7F4D,
0x7F61, 0x7F74, 0x7F86, 0x7F97, 0x7FA6, 0x7FB4, 0x7FC1, 0x7FCD,
0x7FD8, 0x7FE1, 0x7FE9, 0x7FF0, 0x7FF5, 0x7FF9, 0x7FFD, 0x7FFE};
/**
* @brief This function transforms stator voltage qVq and qVd, that belong to
* a rotor flux synchronous rotating frame, to a stationary reference
* frame, so as to obtain qValpha and qVbeta:
* Valfa= Vq*Cos(theta)+ Vd*Sin(theta)
* Vbeta=-Vq*Sin(theta)+ Vd*Cos(theta)
* @param Input: stator voltage Vq and Vd in qd_t format
* @param Theta: rotating frame angular position in q1.15 format
* @retval Stator voltage Valpha and Vbeta in qd_t format
*/
alphabeta_t math_rev_park(qd_t input, int16_t theta)
{
alphabeta_t output;
int32_t alpha_tmp1, alpha_tmp2, beta_tmp1, beta_tmp2;
int32_t shindex;
uint16_t uhindex;
int16_t hSin = 0, hCos = 0;
/* 10 bit index computation */
shindex = ((int32_t)32768 + (int32_t)theta);
uhindex = (uint16_t)shindex;
uhindex = uhindex >> 6;
// uhindex /= (uint16_t)64;
/**
| hAngle | angle | std |
| (0,16384] | U0_90 | (0,0.5] |
| (16384,32767] | U90_180 | (0.5,0.99] |
| (-16384,-1] | U270_360 | (0,-0.5] |
| (-16384,-32768] | U180_270 | (-0.5,-1) |
*/
switch ((uint16_t)(uhindex)&SIN_MASK)
{
case U0_90:
hSin = hSin_Cos_Table[(uint8_t)(uhindex)];
hCos = hSin_Cos_Table[(uint8_t)(0xFFu - (uint8_t)(uhindex))];
break;
case U90_180:
hSin = hSin_Cos_Table[(uint8_t)(0xFFu - (uint8_t)(uhindex))];
hCos = -hSin_Cos_Table[(uint8_t)(uhindex)];
break;
case U180_270:
hSin = -hSin_Cos_Table[(uint8_t)(uhindex)];
hCos = -hSin_Cos_Table[(uint8_t)(0xFFu - (uint8_t)(uhindex))];
break;
case U270_360:
hSin = -hSin_Cos_Table[(uint8_t)(0xFFu - (uint8_t)(uhindex))];
hCos = hSin_Cos_Table[(uint8_t)(uhindex)];
break;
default:
break;
}
/*No overflow guaranteed*/
alpha_tmp1 = input.q * (int32_t)hCos;
alpha_tmp2 = input.d * (int32_t)hSin;
output.alpha = (int16_t)(((alpha_tmp1) + (alpha_tmp2)) >> 15);
beta_tmp1 = input.q * (int32_t)hSin;
beta_tmp2 = input.d * (int32_t)hCos;
output.beta = (int16_t)((beta_tmp2 - beta_tmp1) >> 15);
return (output);
}

53
src/Foc/math.h Normal file
View File

@ -0,0 +1,53 @@
#include "type.h"
#define SQRT_2 1.4142
#define SQRT_3 1.732
/**
* @brief Macro to compute logarithm of two
*/
#define LOG2(x) \
((x) == 65535 ? 16 : ((x) == 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 ? 15 : ((x) == 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 ? 14 : ((x) == 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 ? 13 : ((x) == 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 ? 12 : ((x) == 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 ? 11 : ((x) == 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 ? 10 : ((x) == 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 ? 9 : ((x) == 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 ? 8 : ((x) == 2 * 2 * 2 * 2 * 2 * 2 * 2 ? 7 : ((x) == 2 * 2 * 2 * 2 * 2 * 2 ? 6 : ((x) == 2 * 2 * 2 * 2 * 2 ? 5 : ((x) == 2 * 2 * 2 * 2 ? 4 : ((x) == 2 * 2 * 2 ? 3 : ((x) == 2 * 2 ? 2 : ((x) == 2 ? 1 : ((x) == 1 ? 0 : -1)))))))))))))))))
/**
* @brief This function transforms stator currents Ia and qIb (which are
* directed along axes each displaced by 120 degrees) into currents
* Ialpha and Ibeta in a stationary qd reference frame.
* Ialpha = Ia
* Ibeta = -(2*Ib+Ia)/sqrt(3)
* @param Curr_Input: stator current Ia and Ib in ab_t format
* @retval Stator current Ialpha and Ibeta in alphabeta_t format
*/
alphabeta_t math_clarke(ab_t Input);
/**
* @brief This function transforms stator values alpha and beta, which
* belong to a stationary qd reference frame, to a rotor flux
* synchronous reference frame (properly oriented), so as Iq and Id.
* Id= Ialpha *sin(theta)+qIbeta *cos(Theta)
* Iq=qIalpha *cos(Theta)-qIbeta *sin(Theta)
* @param Curr_Input: stator values alpha and beta in alphabeta_t format
* @param Theta: rotating frame angular position in q1.15 format
* @retval Stator current q and d in qd_t format
*/
qd_t math_park(alphabeta_t Input, int16_t Theta);
/**
* @brief This function transforms stator voltage qVq and qVd, that belong to
* a rotor flux synchronous rotating frame, to a stationary reference
* frame, so as to obtain qValpha and qVbeta:
* Valfa= Vq*Cos(theta)+ Vd*Sin(theta)
* Vbeta=-Vq*Sin(theta)+ Vd*Cos(theta)
* @param Curr_Input: stator voltage Vq and Vd in qd_t format
* @param Theta: rotating frame angular position in q1.15 format
* @retval Stator values alpha and beta in alphabeta_t format
*/
alphabeta_t math_rev_park(qd_t Input, int16_t Theta);
/**
* @brief It calculates the square root of a non-negative s32. It returns 0
* for negative s32.
* @param Input int32_t number
* @retval int32_t Square root of Input (0 if Input<0)
*/
int32_t math_sqrt(int32_t wInput);

87
src/Foc/svpwm.c Normal file
View File

@ -0,0 +1,87 @@
#include "svpwm.h"
void svpwm(int16_t alpha, int16_t beta)
{
int32_t wX, wY, wZ, wUAlpha, wUBeta, wTimePhA, wTimePhB, wTimePhC;
wUAlpha = alpha * (int32_t)pHandle->hT_Sqrt3;
wUBeta = -(beta * (int32_t)(pHandle->PWMperiod)) * 2;
wX = wUBeta;
wY = (wUBeta + wUAlpha) / 2;
wZ = (wUBeta - wUAlpha) / 2;
/* Sector calculation from wX, wY, wZ */
if (wY < 0)
{
if (wZ < 0)
{
pHandle->Sector = SECTOR_5;
wTimePhA = (int32_t)(pHandle->PWMperiod) / 4 + ((wY - wZ) / (int32_t)262144);
wTimePhB = wTimePhA + wZ / 131072;
wTimePhC = wTimePhA - wY / 131072;
pHandle->lowDuty = wTimePhC;
pHandle->midDuty = wTimePhA;
pHandle->highDuty = wTimePhB;
}
else /* wZ >= 0 */
if (wX <= 0)
{
pHandle->Sector = SECTOR_4;
wTimePhA = (int32_t)(pHandle->PWMperiod) / 4 + ((wX - wZ) / (int32_t)262144);
wTimePhB = wTimePhA + wZ / 131072;
wTimePhC = wTimePhB - wX / 131072;
pHandle->lowDuty = wTimePhC;
pHandle->midDuty = wTimePhB;
pHandle->highDuty = wTimePhA;
}
else /* wX > 0 */
{
pHandle->Sector = SECTOR_3;
wTimePhA = (int32_t)(pHandle->PWMperiod) / 4 + ((wY - wX) / (int32_t)262144);
wTimePhC = wTimePhA - wY / 131072;
wTimePhB = wTimePhC + wX / 131072;
pHandle->lowDuty = wTimePhB;
pHandle->midDuty = wTimePhC;
pHandle->highDuty = wTimePhA;
}
}
else /* wY > 0 */
{
if (wZ >= 0)
{
pHandle->Sector = SECTOR_2;
wTimePhA = (int32_t)(pHandle->PWMperiod) / 4 + ((wY - wZ) / (int32_t)262144);
wTimePhB = wTimePhA + wZ / 131072;
wTimePhC = wTimePhA - wY / 131072;
pHandle->lowDuty = wTimePhB;
pHandle->midDuty = wTimePhA;
pHandle->highDuty = wTimePhC;
}
else /* wZ < 0 */
if (wX <= 0)
{
pHandle->Sector = SECTOR_6;
wTimePhA = (int32_t)(pHandle->PWMperiod) / 4 + ((wY - wX) / (int32_t)262144);
wTimePhC = wTimePhA - wY / 131072;
wTimePhB = wTimePhC + wX / 131072;
pHandle->lowDuty = wTimePhA;
pHandle->midDuty = wTimePhC;
pHandle->highDuty = wTimePhB;
}
else /* wX > 0 */
{
pHandle->Sector = SECTOR_1;
wTimePhA = (int32_t)(pHandle->PWMperiod) / 4 + ((wX - wZ) / (int32_t)262144);
wTimePhB = wTimePhA + wZ / 131072;
wTimePhC = wTimePhB - wX / 131072;
pHandle->lowDuty = wTimePhA;
pHandle->midDuty = wTimePhB;
pHandle->highDuty = wTimePhC;
}
}
pHandle->CntPhA = (uint16_t)wTimePhA;
pHandle->CntPhB = (uint16_t)wTimePhB;
pHandle->CntPhC = (uint16_t)wTimePhC;
}

18
src/Foc/svpwm.h Normal file
View File

@ -0,0 +1,18 @@
/**
* @file svpwm.h
* @author jimingqing
* @date 2023-05-30
* @version 0.0.1
* @copyright XiazhiTech Copyright (c) 2023
*
* @brief
*/
#include "stm32f407xx.h"
#define SECTOR_1 0u
#define SECTOR_2 1u
#define SECTOR_3 2u
#define SECTOR_4 3u
#define SECTOR_5 4u
#define SECTOR_6 5u

26
src/Foc/type.h Normal file
View File

@ -0,0 +1,26 @@
#include "stm32f407xx.h"
/**
* @brief Two components q, d type definition
*/
typedef struct
{
int16_t q;
int16_t d;
} qd_t;
/**
* @brief Two components a,b type definition
*/
typedef struct
{
int16_t a;
int16_t b;
} ab_t;
/**
* @brief Two components alpha, beta type definition
*/
typedef struct
{
int16_t alpha;
int16_t beta;
} alphabeta_t;