驱动步进电机

This commit is contained in:
许晟昊 2024-12-07 21:56:08 +08:00
parent 18e5285f02
commit 60070bc904
14 changed files with 863 additions and 579 deletions

View File

@ -78,8 +78,10 @@ void Error_Handler(void);
/* Private defines -----------------------------------------------------------*/
#define LED_BLUE_Pin LL_GPIO_PIN_13
#define LED_BLUE_GPIO_Port GPIOC
#define PWMA_Pin LL_GPIO_PIN_1
#define PWMA_GPIO_Port GPIOA
#define AIN1_Pin LL_GPIO_PIN_4
#define AIN1_GPIO_Port GPIOA
#define AIN2_Pin LL_GPIO_PIN_5
#define AIN2_GPIO_Port GPIOA
#define OLED_SDA_Pin LL_GPIO_PIN_12
#define OLED_SDA_GPIO_Port GPIOB
#define OLDE_SCK_Pin LL_GPIO_PIN_13

View File

@ -56,7 +56,7 @@ void MX_GPIO_Init(void)
LL_GPIO_ResetOutputPin(LED_BLUE_GPIO_Port, LED_BLUE_Pin);
/**/
LL_GPIO_ResetOutputPin(PWMA_GPIO_Port, PWMA_Pin);
LL_GPIO_ResetOutputPin(GPIOA, AIN1_Pin|AIN2_Pin);
/**/
LL_GPIO_ResetOutputPin(GPIOB, OLED_SDA_Pin|OLDE_SCK_Pin);
@ -69,23 +69,33 @@ void MX_GPIO_Init(void)
LL_GPIO_Init(LED_BLUE_GPIO_Port, &GPIO_InitStruct);
/**/
GPIO_InitStruct.Pin = LL_GPIO_PIN_14|LL_GPIO_PIN_15;
GPIO_InitStruct.Pin = LL_GPIO_PIN_14;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
LL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/**/
GPIO_InitStruct.Pin = LL_GPIO_PIN_0|LL_GPIO_PIN_2|LL_GPIO_PIN_3|LL_GPIO_PIN_4
|LL_GPIO_PIN_5|LL_GPIO_PIN_6|LL_GPIO_PIN_7|LL_GPIO_PIN_8
|LL_GPIO_PIN_11|LL_GPIO_PIN_12|LL_GPIO_PIN_15;
GPIO_InitStruct.Pin = LL_GPIO_PIN_15;
GPIO_InitStruct.Mode = LL_GPIO_MODE_FLOATING;
LL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/**/
GPIO_InitStruct.Pin = LL_GPIO_PIN_0;
GPIO_InitStruct.Mode = LL_GPIO_MODE_FLOATING;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/**/
GPIO_InitStruct.Pin = LL_GPIO_PIN_2|LL_GPIO_PIN_3|LL_GPIO_PIN_6|LL_GPIO_PIN_7
|LL_GPIO_PIN_8|LL_GPIO_PIN_11|LL_GPIO_PIN_12|LL_GPIO_PIN_15;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/**/
GPIO_InitStruct.Pin = PWMA_Pin;
GPIO_InitStruct.Pin = AIN1_Pin|AIN2_Pin;
GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
LL_GPIO_Init(PWMA_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/**/
GPIO_InitStruct.Pin = LL_GPIO_PIN_0|LL_GPIO_PIN_1|LL_GPIO_PIN_2|LL_GPIO_PIN_10

View File

@ -256,7 +256,11 @@ void TIM2_IRQHandler(void)
/* USER CODE END TIM2_IRQn 0 */
/* USER CODE BEGIN TIM2_IRQn 1 */
if (IS_TIM_IT_FLAG(PWM_TIM))
{
TIM_IRQ_HANDLER(PWM_TIM);
// GPIO_TOGGLE(PWM_GPIO_Port, PWM_Pin);
}
/* USER CODE END TIM2_IRQn 1 */
}

View File

@ -68,7 +68,9 @@ void MX_TIM2_Init(void)
/* USER CODE END TIM2_Init 0 */
LL_TIM_InitTypeDef TIM_InitStruct = {0};
LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0};
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
/* Peripheral clock enable */
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);
@ -79,18 +81,35 @@ void MX_TIM2_Init(void)
/* USER CODE BEGIN TIM2_Init 1 */
/* USER CODE END TIM2_Init 1 */
TIM_InitStruct.Prescaler = 7199;
TIM_InitStruct.Prescaler = 0;
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
TIM_InitStruct.Autoreload = 99;
TIM_InitStruct.Autoreload = 7199;
TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
LL_TIM_Init(TIM2, &TIM_InitStruct);
LL_TIM_DisableARRPreload(TIM2);
LL_TIM_SetClockSource(TIM2, LL_TIM_CLOCKSOURCE_INTERNAL);
LL_TIM_OC_EnablePreload(TIM2, LL_TIM_CHANNEL_CH2);
TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM2;
TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE;
TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE;
TIM_OC_InitStruct.CompareValue = 0;
TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_LOW;
LL_TIM_OC_Init(TIM2, LL_TIM_CHANNEL_CH2, &TIM_OC_InitStruct);
LL_TIM_OC_EnableFast(TIM2, LL_TIM_CHANNEL_CH2);
LL_TIM_SetTriggerOutput(TIM2, LL_TIM_TRGO_RESET);
LL_TIM_DisableMasterSlaveMode(TIM2);
/* USER CODE BEGIN TIM2_Init 2 */
/* USER CODE END TIM2_Init 2 */
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOA);
/**TIM2 GPIO Configuration
PA1 ------> TIM2_CH2
*/
GPIO_InitStruct.Pin = LL_GPIO_PIN_1;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

View File

@ -155,6 +155,26 @@
<WinNumber>1</WinNumber>
<ItemText>buffer</ItemText>
</Ww>
<Ww>
<count>1</count>
<WinNumber>1</WinNumber>
<ItemText>app,0x0A</ItemText>
</Ww>
<Ww>
<count>2</count>
<WinNumber>1</WinNumber>
<ItemText>0x00000E0F,0x0A</ItemText>
</Ww>
<Ww>
<count>3</count>
<WinNumber>1</WinNumber>
<ItemText>0x0000270F,0x0A</ItemText>
</Ww>
<Ww>
<count>4</count>
<WinNumber>1</WinNumber>
<ItemText>0x000003E7,0x0A</ItemText>
</Ww>
</WatchWindow1>
<Tracepoint>
<THDelay>0</THDelay>
@ -200,9 +220,17 @@
<pMultCmdsp></pMultCmdsp>
<SystemViewers>
<Entry>
<Name>System Viewer\TIM1</Name>
<Name>System Viewer\GPIOA</Name>
<WinId>35905</WinId>
</Entry>
<Entry>
<Name>System Viewer\GPIOC</Name>
<WinId>35903</WinId>
</Entry>
<Entry>
<Name>System Viewer\TIM2</Name>
<WinId>35904</WinId>
</Entry>
</SystemViewers>
</TargetOption>
</Target>

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,31 @@
#include "app.h"
#include "board.h"
#include "flow.h"
static struct flow business_fw; // 业务流程
static struct flow idle_fw; // 空闲任务
app_t app;
static uint8_t business_inspection(struct flow *fl)
{
FL_HEAD(fl);
for (;;)
{
if (app.pwm_percent > 0)
{
GPIO_SET(AIN1_GPIO_Port, AIN1_Pin);
GPIO_RESET(AIN2_GPIO_Port, AIN2_Pin);
}
else
{
GPIO_RESET(AIN1_GPIO_Port, AIN1_Pin);
GPIO_SET(AIN2_GPIO_Port, AIN2_Pin);
}
PWM_SET_DUTY(PWM_TIM, PWM_CHANNEL, ABS(app.pwm_percent));
FL_LOCK_DELAY(fl, FL_CLOCK_SEC*2);
}
FL_TAIL(fl);
}
/**
* @brief
*
@ -32,6 +56,7 @@ static uint8_t idle_inspection(struct flow *fl)
*/
void app_run(void)
{
business_inspection(&business_fw); // 业务流程检测
idle_inspection(&idle_fw);
}
@ -42,7 +67,13 @@ void app_run(void)
*/
void app_init(void)
{
FL_INIT(&business_fw); // 业务流程
FL_INIT(&idle_fw); // 空闲任务
ENABLE_TIM(TASK_TIM);
ENABLE_TIM(PWM_TIM);
PWM_START(PWM_TIM, PWM_CHANNEL);
PWM_SET_DUTY(PWM_TIM, PWM_CHANNEL, 0);
app.pwm_feq = PWM_GET_FREQ(PWM_TIM);
}

View File

@ -8,6 +8,15 @@
#ifndef APP_H
#define APP_H
#include "main.h"
typedef struct
{
float32 pwm_percent;
uint32_t pwm_feq;
} app_t;
extern app_t app;
void app_init(void);
void app_run(void);
#endif // APP_H

View File

@ -18,6 +18,12 @@ static void uart_init(void)
}
}
static void motor_init(void)
{
GPIO_RESET(AIN1_GPIO_Port, AIN1_Pin);
GPIO_RESET(AIN2_GPIO_Port, AIN2_Pin);
}
/**
* @brief UART发送数据
*
@ -39,4 +45,5 @@ void board_init(void)
{
uart_init();
ssd1306_init();
motor_init();
}

View File

@ -6,6 +6,8 @@
#define UART_TXSIZE (240u) // 发送240个字节
#define TASK_TIM TIM1
#define PWM_TIM TIM2
#define PWM_CHANNEL LL_TIM_CHANNEL_CH2
extern uart_t *uart;

View File

@ -17,7 +17,7 @@
// #include "dacs.h"
#include "dmas.h"
#include "tims.h"
// #include "pwms.h"
#include "pwms.h"
#include "uarts.h"
// #include "eeprom.h"
// #include "spis.h"

View File

@ -0,0 +1 @@
#include "pwms.h"

View File

@ -12,6 +12,7 @@
#ifndef __PWMS_H__
#define __PWMS_H__
#include "lib.h"
/**
* @brief Starts the PWM for a specific channel
* @param TIMx: TIM instance
@ -39,16 +40,51 @@
} while (__LINE__ == -1)
/**
* @brief Sets the duty cycle for a specific channel
* @brief Sets the PWM frequency
* @param TIMx: TIM instance
* @param CHx: Channel to be set
* @param DUTY: Duty cycle value (0-100)
* @param COMPARE: Compare value
* @retval None
*/
#define PWM_SET_DUTY(TIMx, CHx, DUTY) \
do \
{ \
LL_TIM_OC_SetCompareCH##CHx(TIMx, DUTY); \
} while (__LINE__ == -1)
static inline void PWM_SET_COMPARE(TIM_TypeDef *TIMx, uint32_t CHx, uint16_t COMPARE)
{
switch (CHx)
{
case LL_TIM_CHANNEL_CH1:
LL_TIM_OC_SetCompareCH1(TIMx, COMPARE);
break;
case LL_TIM_CHANNEL_CH2:
LL_TIM_OC_SetCompareCH2(TIMx, COMPARE);
break;
case LL_TIM_CHANNEL_CH3:
LL_TIM_OC_SetCompareCH3(TIMx, COMPARE);
break;
case LL_TIM_CHANNEL_CH4:
LL_TIM_OC_SetCompareCH4(TIMx, COMPARE);
break;
default:
break;
}
}
/**
* @brief PWM占空比
*
* TIMx的指定通道CHx的PWM占空比
*
* @param TIMx TIM1TIM2等
* @param CHx TIM_CHANNEL_1TIM_CHANNEL_2等
* @param DUTY 0100
*/
static inline void PWM_SET_DUTY(TIM_TypeDef *TIMx, uint32_t CHx, uint16_t DUTY)
{
PWM_SET_COMPARE(TIMx, CHx, DUTY * LL_TIM_GetAutoReload(TIMx) / 100);
}
// 获取当前频率
static inline uint32_t PWM_GET_FREQ(TIM_TypeDef *TIMx)
{
return SystemCoreClock / (LL_TIM_GetPrescaler(TIMx) + 1) / (LL_TIM_GetAutoReload(TIMx) + 1);
}
#endif ///< __PWMS_H__

View File

@ -39,19 +39,23 @@ Mcu.IPNb=7
Mcu.Name=STM32F103C(8-B)Tx
Mcu.Package=LQFP48
Mcu.Pin0=PC13-TAMPER-RTC
Mcu.Pin1=PD0-OSC_IN
Mcu.Pin10=VP_SYS_VS_Systick
Mcu.Pin11=VP_TIM1_VS_ClockSourceINT
Mcu.Pin12=VP_TIM2_VS_ClockSourceINT
Mcu.Pin2=PD1-OSC_OUT
Mcu.Pin3=PA1
Mcu.Pin4=PB12
Mcu.Pin5=PB13
Mcu.Pin6=PA9
Mcu.Pin7=PA10
Mcu.Pin8=PA13
Mcu.Pin9=PA14
Mcu.PinsNb=13
Mcu.Pin1=PC15-OSC32_OUT
Mcu.Pin10=PA9
Mcu.Pin11=PA10
Mcu.Pin12=PA13
Mcu.Pin13=PA14
Mcu.Pin14=VP_SYS_VS_Systick
Mcu.Pin15=VP_TIM1_VS_ClockSourceINT
Mcu.Pin16=VP_TIM2_VS_ClockSourceINT
Mcu.Pin2=PD0-OSC_IN
Mcu.Pin3=PD1-OSC_OUT
Mcu.Pin4=PA0-WKUP
Mcu.Pin5=PA1
Mcu.Pin6=PA4
Mcu.Pin7=PA5
Mcu.Pin8=PB12
Mcu.Pin9=PB13
Mcu.PinsNb=17
Mcu.ThirdParty0=RealThread.RT-Thread.3.1.5
Mcu.ThirdPartyNb=1
Mcu.UserConstants=
@ -74,15 +78,28 @@ NVIC.TIM1_UP_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.TIM2_IRQn=true\:15\:0\:true\:false\:true\:true\:true\:true
NVIC.USART1_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
PA1.GPIOParameters=GPIO_Label
PA1.GPIO_Label=PWMA
PA1.Signal=GPIO_Output
PA0-WKUP.Locked=true
PA0-WKUP.Signal=GPIO_Input
PA1.Locked=true
PA1.Signal=S_TIM2_CH2
PA10.Mode=Asynchronous
PA10.Signal=USART1_RX
PA13.Mode=Serial_Wire
PA13.Signal=SYS_JTMS-SWDIO
PA14.Mode=Serial_Wire
PA14.Signal=SYS_JTCK-SWCLK
PA4.GPIOParameters=GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultOutputPP
PA4.GPIO_Label=AIN1
PA4.GPIO_ModeDefaultOutputPP=GPIO_MODE_OUTPUT_PP
PA4.GPIO_PuPd=GPIO_PULLUP
PA4.Locked=true
PA4.Signal=GPIO_Output
PA5.GPIOParameters=GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultOutputPP
PA5.GPIO_Label=AIN2
PA5.GPIO_ModeDefaultOutputPP=GPIO_MODE_OUTPUT_PP
PA5.GPIO_PuPd=GPIO_PULLUP
PA5.Locked=true
PA5.Signal=GPIO_Output
PA9.Mode=Asynchronous
PA9.Signal=USART1_TX
PB12.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultOutputPP
@ -102,6 +119,8 @@ PB13.Signal=GPIO_Output
PC13-TAMPER-RTC.GPIOParameters=GPIO_Label
PC13-TAMPER-RTC.GPIO_Label=LED_BLUE
PC13-TAMPER-RTC.Signal=GPIO_Output
PC15-OSC32_OUT.Locked=true
PC15-OSC32_OUT.Signal=GPIO_Input
PD0-OSC_IN.Mode=HSE-External-Oscillator
PD0-OSC_IN.Signal=RCC_OSC_IN
PD1-OSC_OUT.Mode=HSE-External-Oscillator
@ -167,12 +186,21 @@ RealThread.RT-Thread.3.1.5.RT_USING_COMPONENTS_INIT=1
RealThread.RT-Thread.3.1.5.RT_USING_CONSOLE=0
RealThread.RT-Thread.3.1.5.RT_USING_DEVICE=1
RealThread.RT-Thread.3.1.5_SwParameter=RTOSJjkernel\:true;RTOSJjshell\:true;RTOSJjdevice\:true;
SH.S_TIM2_CH2.0=TIM2_CH2,PWM Generation2 CH2
SH.S_TIM2_CH2.ConfNb=1
TIM1.IPParameters=Prescaler,Period
TIM1.Period=99
TIM1.Prescaler=7199
TIM2.IPParameters=Prescaler,Period
TIM2.Period=99
TIM2.Prescaler=7199
TIM2.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_DISABLE
TIM2.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2
TIM2.CounterMode=TIM_COUNTERMODE_UP
TIM2.IPParameters=Prescaler,Period,CounterMode,AutoReloadPreload,OCPolarity_2,TIM_MasterOutputTrigger,Channel-PWM Generation2 CH2,OCFastMode_PWM-PWM Generation2 CH2,OCMode_PWM-PWM Generation2 CH2
TIM2.OCFastMode_PWM-PWM\ Generation2\ CH2=TIM_OCFAST_ENABLE
TIM2.OCMode_PWM-PWM\ Generation2\ CH2=TIM_OCMODE_PWM2
TIM2.OCPolarity_2=TIM_OCPOLARITY_LOW
TIM2.Period=7199
TIM2.Prescaler=0
TIM2.TIM_MasterOutputTrigger=TIM_TRGO_RESET
USART1.IPParameters=VirtualMode
USART1.VirtualMode=VM_ASYNC
VP_SYS_VS_Systick.Mode=SysTick