STM32F103c8t6使用库函数、Tim2输出四路PWM以0.3m/s的速度控制直流减速电机
时间: 2023-05-28 08:07:03 浏览: 149
以下是使用STM32F103c8t6和库函数控制四路PWM以0.3m/s的速度控制直流减速电机的步骤:
1. 初始化TIM2定时器和四个通道的PWM输出,设置PWM频率为10kHz,占空比为0。
```c
// 初始化TIM2定时器和四个通道的PWM输出
void PWM_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
// 使能TIM2时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
// 定时器基本设置
TIM_TimeBaseStructure.TIM_Period = 999; // PWM频率为10kHz
TIM_TimeBaseStructure.TIM_Prescaler = 71; // 定时器时钟为72MHz,分频为71,计数频率为1MHz
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
// PWM设置
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
TIM_OC2Init(TIM2, &TIM_OCInitStructure);
TIM_OC3Init(TIM2, &TIM_OCInitStructure);
TIM_OC4Init(TIM2, &TIM_OCInitStructure);
// 使能TIM2输出比较功能
TIM_CtrlPWMOutputs(TIM2, ENABLE);
// 启动定时器
TIM_Cmd(TIM2, ENABLE);
}
```
2. 初始化ADC1模块,以读取电机的速度反馈信号。
```c
// 初始化ADC1模块
void ADC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
// 使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// 配置PA0为模拟输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 使能DMA1时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
// 配置DMA1通道1
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(ADC1->DR);
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_Value;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
// 使能DMA1通道1
DMA_Cmd(DMA1_Channel1, ENABLE);
// 使能ADC1时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
// ADC1基本设置
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
// 配置ADC1通道0
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5);
// 启动ADC1 DMA模式
ADC_DMACmd(ADC1, ENABLE);
// 启动ADC1
ADC_Cmd(ADC1, ENABLE);
// 校准ADC1
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
}
```
3. 编写速度控制函数,根据速度反馈信号和目标速度,调整PWM输出的占空比,以达到控制电机转速的目的。
```c
// 速度控制函数
void VelocityControl(float target_velocity)
{
uint16_t adc_value;
float actual_velocity;
float error;
float kp = 5.0;
float ki = 0.01;
float kd = 0.01;
float kp_term, ki_term, kd_term;
// 读取ADC值
adc_value = ADC_Value[0];
// 计算实际速度
actual_velocity = (float)adc_value / 4096.0 * 3.3 / 0.018;
// 计算误差
error = target_velocity - actual_velocity;
// 计算控制量
kp_term = kp * error;
ki_term += ki * error;
kd_term = kd * (error - last_error);
last_error = error;
control_value = kp_term + ki_term + kd_term;
// 限制控制量范围
if(control_value > 1.0)
control_value = 1.0;
else if(control_value < -1.0)
control_value = -1.0;
// 根据控制量调整PWM占空比
if(control_value >= 0)
{
TIM_SetCompare1(TIM2, (uint16_t)(999 * control_value));
TIM_SetCompare2(TIM2, 0);
}
else
{
TIM_SetCompare1(TIM2, 0);
TIM_SetCompare2(TIM2, (uint16_t)(999 * fabs(control_value)));
}
TIM_SetCompare3(TIM2, 0);
TIM_SetCompare4(TIM2, 0);
}
```
4. 在主函数中调用PWM初始化函数和速度控制函数,并设置控制循环的时间间隔为10ms。
```c
int main(void)
{
PWM_Init();
ADC_Init();
// 设置控制循环的时间间隔为10ms
SysTick_Config(SystemCoreClock / 100);
while(1)
{
// 设置目标速度为0.3m/s
VelocityControl(0.3);
delay_ms(10);
}
}
```
以上就是使用STM32F103c8t6和库函数控制四路PWM以0.3m/s的速度控制直流减速电机的完整步骤。需要注意的是,在实际使用中,需要根据具体的硬件电路和电机特性进行调整。
阅读全文