基于STM32 BLDC直流无刷电机控制器设计,并附上原理图和源码等。源代码是基于免费开源CoOS(UCOS类似)操作系统上写的,在学习无刷电机的控制同时还能学习到操作系统的知识。同时提供用Matlab的GUI编写的串口接收程序和开源的代码,实时接收速度和电流信息,便于PID测试,并且有CAN(TJA1050)接口。同时自己可以进行修改学习Matlab的GUI编程。
1.STM32F103RB处理器 时钟72M Flash 64K RAM 20K
2.MOSFET SUD35N05-26L 55V 35A Rds=0.02
3. MOSFET驱动 IR2101S
部分代码:
main.c
#include "includes.h"
#define TASK_STK_SIZE 128
#define TASK0_PRIO 2
#define TASK1_PRIO 3
#define TASK2_PRIO 4
#define TASK3_PRIO 5
OS_STK STK_TASK0[TASK_STK_SIZE];
OS_STK STK_TASK1[TASK_STK_SIZE];
OS_STK STK_TASK2[TASK_STK_SIZE];
OS_STK STK_TASK3[TASK_STK_SIZE];
void TASK0(void *param);
void TASK1(void *param);
void TASK2(void *param);
void TASK3(void *param);
extern uint32_t Speed_count;
uint8_t USART_Flag = 0;
int main(void)
{
Periph_Init();
CoInitOS();
CoCreateTask( TASK0, (void*)0, TASK0_PRIO, &STK_TASK0[TASK_STK_SIZE - 1], TASK_STK_SIZE);
CoCreateTask( TASK1, (void*)0, TASK1_PRIO, &STK_TASK1[TASK_STK_SIZE - 1], TASK_STK_SIZE);
CoCreateTask( TASK2, (void*)0, TASK2_PRIO, &STK_TASK2[TASK_STK_SIZE - 1], TASK_STK_SIZE);
CoCreateTask( TASK3, (void*)0, TASK3_PRIO, &STK_TASK3[TASK_STK_SIZE - 1], TASK_STK_SIZE);
CoStartOS();
while(1);
}
void TASK0(void *param)
{
uint8_t start_flag=0;
uint8_t sw_state = 1;
KEY_Init();
Speed_PIDInit();
for(;;)
{
if(SW__Read()^sw_state)
{
if(start_flag)
{
BLDC_Stop();
}
sw_state = SW__Read();
if(sw_state)
{
Direction = SET;
}
else
{
Direction = RESET;
}
if(start_flag)
{
BLDC_Start();
}
}
if(KEY_Read(KEY1))
{
CoTickDelay(5);
if(KEY_Read(KEY1))
{
BLDC_Start();
start_flag = 1;
}
}
if(KEY_Read(KEY2))
{
CoTickDelay(5);
if(KEY_Read(KEY2))
{
BLDC_Stop();
start_flag = 0;
}
}
CoTickDelay(10);
}
}
void TASK1(void *param)
{
uint16_t adc_value= 0;
uint8_t i = 0;
for(;;)
{
adc_value= 0;
for(i=0;i<4;i++)
{
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
while(ADC_GetSoftwareStartConvStatus(ADC1));
adc_value += ADC_GetConversionValue(ADC1);
}
ADC_Speed = adc_value/4;
CoTickDelay(10);
}
}
void TASK2(void *param)
{
uint16_t data;
for(;;)
{
if(USART_Flag)
{
data = 1000000/(6*Speed_count);
USART_SendData( USART2, data);
USART_Flag = 0;
}
CoTickDelay(1);
}
}
void TASK3(void *param)
{
LED_Off();
for(;;)
{
LED_On();
CoTickDelay(200);
LED_Off();
CoTickDelay(200);
}
}
BLDC.c
#include "includes.h"
#define IDLE 0
#define START 1
#define RUN 2
#define STOP 3
#define FAULT 4
#define HIGH 1480
#define LOW 3
u8 state;
FlagStatus Direction = SET;
uint8_t stalling_count = 0;
void Delay_us(uint8_t t);
void BLDC_GPIOConfig(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void BLDC_TIM1Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
TIM_DeInit(TIM1);
TIM_TimeBaseStructure.TIM_Prescaler = 2;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned2;
TIM_TimeBaseStructure.TIM_Period = 1500 - 1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
TIM_OCInitStructure.TIM_Pulse =1200;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC1Init(TIM1,&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_Pulse =1200;
TIM_OC2Init(TIM1,&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_Pulse =1200;
TIM_OC3Init(TIM1,&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
TIM_OCInitStructure.TIM_Pulse =1495;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC4Init(TIM1,&TIM_OCInitStructure);
TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
TIM_BDTRInitStructure.TIM_DeadTime = 100;
TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low ;
TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;
TIM_BDTRConfig(TIM1,&TIM_BDTRInitStructure);
TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);
TIM_OC2PreloadConfig(TIM1,TIM_OCPreload_Enable);
TIM_OC3PreloadConfig(TIM1,TIM_OCPreload_Enable);
TIM_SelectInputTrigger(TIM1, TIM_TS_ITR2);
TIM_CtrlPWMOutputs(TIM1,ENABLE);
TIM_ClearITPendingBit( TIM1, TIM_IT_COM);
TIM_ITConfig(TIM1, TIM_IT_COM ,ENABLE);
TIM_Cmd(TIM1,ENABLE);
}
void BLDC_TIM3Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_DeInit(TIM3);
TIM_TimeBaseStructure.TIM_Prescaler = 71;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period =65535;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_TRC;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 10;
TIM_ICInit(TIM3, &TIM_ICInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse =1023;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC2Init(TIM3,&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
TIM_OCInitStructure.TIM_Pulse =65535;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC4Init(TIM3,&TIM_OCInitStructure);
TIM_SelectHallSensor(TIM3,ENABLE);
TIM_SelectInputTrigger(TIM3, TIM_TS_TI1F_ED);
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);
TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_OC2Ref);
TIM_ITConfig(TIM3, TIM_IT_Trigger|TIM_IT_CC4, ENABLE);
}
void huanxiang(void)
{
u8 Hall_data = 0;
Hall_data=(u8)((GPIOA->IDR&0x000000c0)>>6);
Hall_data|=(u8)((GPIOB->IDR&0x00000001)<<2);
if(Direction)
{
switch(Hall_data)
{
case 0x05:{
TIM1->CCER=0x3081;
};break;
case 0x04:{
TIM1->CCER=0x3180;
};break;
case 0x06:{
TIM1->CCER=0x3108;
};break;
case 0x02:{
TIM1->CCER=0x3018;
};break;
case 0x03:{
TIM1->CCER=0x3810;
};break;
case 0x01:{
TIM1->CCER=0x3801;
};break;
default:break;
}
}
else
{
switch(Hall_data)
{
case 0x05:{
TIM1->CCER=0x3018;
};break;
case 0x04:{
TIM1->CCER=0x3810;
};break;
case 0x06:{
TIM1->CCER=0x3801;
};break;
case 0x02:{
TIM1->CCER=0x3081;
};break;
case 0x03:{
TIM1->CCER=0x3180;
};break;
case 0x01:{
TIM1->CCER=0x3108;
};break;
default:break;
}
}
}
void BLDC_Start(void)
{
TIM1->SMCR|=0x0006;
TIM1->DIER=0x0040;
huanxiang();
TIM3->CR1|=0x0001;
TIM3->DIER|=0x0050;
}
void BLDC_Stop(void)
{
TIM1->SMCR&=0xfff8;
TIM1->CCER=0;
Delay_us(40);
TIM1->CCER=0x0ccc;
while(stalling_count<1);
TIM1->CCER=0;
TIM3->CR1&=0xfffe;
TIM3->CNT=0;
TIM3->DIER&=0xffaf;
}
void Delay_us(uint8_t t)
{
while(t--)
{
}
}
BLDC.h
#ifndef BLDC_H
#define BLDC_H
extern FlagStatus Direction;
extern void BLDC_GPIOConfig(void);
extern void BLDC_TIM1Config(void);
extern void BLDC_TIM3Config(void);
extern void huanxiang(void);
extern void BLDC_Start(void);
extern void BLDC_Stop(void);
#endif
usart.c
#include "includes.h"
void USART1_GPIOConfig(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void USART1_NVICConfig(void)
{
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
void USART1_Config(void)
{
USART_InitTypeDef USART_InitStruct;
USART_InitStruct.USART_BaudRate = 9600;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStruct);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_Cmd(USART1, ENABLE);
}
void USART1_SendString(char* data)
{
unsigned char i = 0;
for (i=0; data[i] != '\0'; i++)
{
USART_SendData( USART1, data[i]);
while( USART_GetFlagStatus(USART1 , USART_FLAG_TXE) == RESET );
}
}
usart.h
#ifndef _USART1_H
#define _USART1_H
extern void USART1_GPIOConfig(void);
extern void USART1_Config(void);
extern void USART1_NVICConfig(void);
extern void USART1_SendString( char* data);
extern u8 ASCII_Buff[5];
#endif
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)