标题:
STM32F405霍尔方波控制无刷电机程序
[打印本页]
作者:
brzfzt
时间:
2018-11-29 11:14
标题:
STM32F405霍尔方波控制无刷电机程序
三霍尔直流无刷电机控制
单片机源程序如下:
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"
#include "main.h"
#include "ADC.h"
#include "STM103REG.h"
#include "DISPLAY.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static vu32 TimingDelay = 0;
volatile struct {
unsigned Key : 1;
unsigned CalSpeed : 1;
unsigned Sec : 1;
unsigned Fault : 1;
}Flags;
unsigned int DesiredSpeed=500;
unsigned int ActualSpeed;
unsigned int pwm=500;
unsigned int T3Count;
unsigned int ActualSpeed5[3];
vu16 ADC_DMABUF;
unsigned int AveActualSpeed;
unsigned char AveNum;
unsigned char j;
float kp=0.5,ki=0.08,kd=0.0;
int ek=0,ek1=0,ek2=0;
float duk;
int du;
int ekSpeed=0;
s16 speedref[2]={1,-1};
u16 motor_statue=0;
u8 startcnt=0;
int ucT1S=0;
int ucT2S=0;
unsigned int dc_bus;
short int ia_zm,ib_zm,ic_zm;
u8 Direction1,Cur_Flag=1;
extern u16 My_PWM;
extern u16 Hall,time;
extern u8 Direction;
extern u8 TIM1_Configuration1(void);
int state,state1,state2,state3,counter1,counter2,counter3,speed_1,aim_speed,check_run,speed_code,vol_over;
short ADC_ConvertedValue[7]={0,0,0,0,0,0,0};
TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
ErrorStatus HSEStartUpStatus;
/* Private function prototypes -----------------------------------------------*/
void RCC_Configuration(void);
void GPIO_Configuration(void);
void LCD_GPIO_Configuration(void);
void NVIC_Configuration(void);
void CalculateDC(int u,int y);
void TIM3_Configuration1(void);
void TIM2_Configuration1(void);
void TIM4_Configuration1(void);
void SysTick_Configuration(void);
int pid(int nonce,int aim);
u8 key_con(void);
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : main
* Description : Main program.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
int main(void)
{
#ifdef DEBUG
debug();
#endif
int i;
u8 keytemp=0;
u8 flagccw=0;
/* System Clocks Configuration */
RCC_Configuration();
/* NVIC configuration */
NVIC_Configuration();
bsp_InitADC();
TIM1_Configuration1();
TIM2_Configuration1();
TIM4_Configuration1();
GPIO_Configuration();
LCD_GPIO_Configuration();
SysTick_Configuration();
//SysTick_CounterCmd(SysTick_Counter_Enable);
ShowMenu_init();
aim_speed=1000;
MENOFF();
MENON();//芯片端使能
LcdReset();
while (1)
{
dc_bus=ADC_ConvertedValue[4]/60;
if((dc_bus>30)|(dc_bus<18))
{
vol_over++;
if(vol_over==4)//防止电压抖动
{
TIM_Cmd(TIM1, DISABLE);
TIM_CtrlPWMOutputs(TIM1, DISABLE);
vol_over=0;
}
}
else
{
vol_over=0;
}
ia_zm =(short int)(((ADC_ConvertedValue[5])-560));
ib_zm =(short int)(((ADC_ConvertedValue[6])-560));
ic_zm =(short int)(((0-(ADC_ConvertedValue[5])-(ADC_ConvertedValue[6]))+560+560));
if((ia_zm>400)|(ib_zm>400)|(ic_zm>400))
{
TIM_Cmd(TIM1, DISABLE);
TIM_CtrlPWMOutputs(TIM1, DISABLE);
Cur_Flag=0;
}
keytemp= key_con();
if(keytemp==1)
{
TIM_Cmd(TIM1, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE);
startcnt=0;
}
if(keytemp==2)
{
Cur_Flag=1;
TIM_Cmd(TIM1, DISABLE);
TIM_CtrlPWMOutputs(TIM1, DISABLE);
}
if(keytemp==5)
{
if(time >1800)
{
time=0;
if(flagccw==0)
{
Direction=1;
Direction1=1;
}
else
{
Direction=0;
Direction1=0;
}
flagccw=~flagccw;
}
}
ucT1S++;
ucT2S++;
if(ucT1S>=30)
{
ShowMenuMain();
ucT1S=0;
}
keytemp= key_con();
if(startcnt<36) //换相6次后启动
{
if(time>10)
{
Hall_SW();
Hall++;
if( Hall>6)Hall=1;
time=0;
}
startcnt++;
}
else
{
startcnt=37;
aim_speed=ADC_ConvertedValue[3]/60*40;
if(aim_speed>2500)aim_speed=2500;
for(i=0;i<100000;i++);
My_PWM+=pid(speed_1,aim_speed)/((speed_1/My_PWM)+1);
if(My_PWM<=0)
My_PWM=0;
if(My_PWM>5000)
My_PWM=5000;
}
}
}
int pid(int nonce,int aim)
{
static int ek_2=0;
static int ek_1=0;
static int ek=0;
// int ec;
int uk;
ek=aim-nonce;
// ec=ek/T;
uk=kp*(ek-ek_1+ki*ek+kd*(ek-2*ek_1+ek_2));
ek_2=ek_1;
ek_1=ek;
return (uk);
}
/*******************************************************************************
* Function Name : RCC_Configuration
* Description : Configures the different system clocks.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void RCC_Configuration(void)
{
ErrorStatus HSEStartUpStatus;
// RCC system reset(for debug purpose)
RCC_DeInit();
// Enable HSE
RCC_HSEConfig(RCC_HSE_ON);
// Wait till HSE is ready
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if(HSEStartUpStatus == SUCCESS)
{
// Enable Prefetch Buffer
FLASH_PrefetchBufferCmd(ENABLE);
// Flash 2 wait state
FLASH_SetLatency(FLASH_Latency_2);
// HCLK = SYSCLK
RCC_HCLKConfig(RCC_SYSCLK_Div1);
// PCLK2 = HCLK
RCC_PCLK2Config(RCC_HCLK_Div1);
// PCLK1 = HCLK/2
RCC_PCLK1Config(RCC_HCLK_Div2);
// PLLCLK = 8MHz * 9 = 72 MHz
// RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
RCC_PLLConfig(RCC_PLLSource_HSE,25, 336, 2, 7);
// Enable PLL
RCC_PLLCmd(ENABLE);
// Wait till PLL is ready
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
}
// Select PLL as system clock source
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
// Wait till PLL is used as system clock source
while(RCC_GetSYSCLKSource() != 0x08)
{
}
}
else
{
// If HSE fails to start-up, the application will have wrong clock configuration.
// User can add here some code to deal with this error
// Go to infinite loop
while (1)
{
}
}
}
/*******************************************************************************
* Function Name : key_con
* Description : Configures the Motor operation mode
* Input : None
* Output : None
* Return : None
*******************************************************************************/
u8 key_con(void)
{
static u8 key;
key=0;
if(!GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_5))
{
key=2;
}
if(!GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_15))
{
key=1;
}
if(!GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1))
{
key=3;
}
if(!GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_10))
{
key=4;
}
if(!GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11))
{
key=5;
}
return key;
}
/*******************************************************************************
* Function Name : GPIO_Configuration
* Description : Configures the different GPIO ports.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOD ,ENABLE);
//按键输入
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 |GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//IO口上拉
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_10|GPIO_Pin_11 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//IO口
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* 配置Hall接口IO */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/*霍尔信号线中断配置*/
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource6);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource7);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource8);
EXTI_InitStructure.EXTI_Line = EXTI_Line6|EXTI_Line7|EXTI_Line8;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/*PA8,PA9,PA10 为上半桥臂*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8| GPIO_Pin_9 | GPIO_Pin_10 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_TIM1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_TIM1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_TIM1);
/*PB13,PB14,PB15 为下半桥臂*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void LCD_GPIO_Configuration()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOD,ENABLE);
/*-----------------GPIOA--------------------*/
//DO 点
GPIO_InitStructure.GPIO_Pin =PAO_LCDDB0|PAO_LCDEN|PAO_LCDRS;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/*-----------------GPIOB--------------------*/
//DO 点
GPIO_InitStructure.GPIO_Pin = PBO_LCDCS1|PBO_LCDCS2|PBO_LCDDB5|PBO_LCDDB6|PBO_LCDDB7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/*-----------------GPIOC--------------------*/
GPIO_InitStructure.GPIO_Pin = PCO_LCDDB1|PCO_LCDDB2|PCO_LCDDB3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/*-----------------GPIOD--------------------*/
GPIO_InitStructure.GPIO_Pin = PDO_LCDDB4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
}
//闭环计算子程序
void CalculateDC(int u,int y)
{
ek=u-y;
if(ek>1||ek<-1)
{
duk=kp*(ek-ek1)+ki*ek+kd*(ek+ek2-ek1*2);
du=(int)duk;
if(duk>1)duk=1;
if(duk<-1)duk=-1;
if(du>10)du=10;
if(du<-5)du=-5;
pwm+=du;
if(pwm<60)
{
pwm=60;
}
if(pwm>0x7FE)
{
pwm=0x7FE;
}
ek2=ek1;
ek1=ek;
}
}
/*******************************************************************************
* Function Name : NVIC_Configuration
* Description : Configure the nested vectored interrupt controller.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
// #ifdef VECT_TAB_RAM
// /* Set the Vector Table base location at 0x20000000 */
// NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
// #else /* VECT_TAB_FLASH */
// /* Set the Vector Table base location at 0x08000000 */
// NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
// #endif
// /* Configure one bit for preemption priority */
// NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
#ifdef DEBUG
/*******************************************************************************
* Function Name : assert_failed
* Description : Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* Input : - file: pointer to the source file name
* - line: assert_param error line source number
* Output : None
* Return : None
*******************************************************************************/
void assert_failed(u8* file, u32 line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif
/*******************************************************************************
* Function Name : SysTick_Config
* Description : Configure a SysTick Base time to 10 ms.
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
F405霍尔方波控制无刷电机.rar
(505.81 KB, 下载次数: 76)
2018-11-30 03:13 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
CZM129
时间:
2019-1-8 14:11
程序不能运行 提示有一个error
stm32f4xx.h(102): error: #35: #error directive: "Please select first the target STM32F4xx device used in your application (in stm32f4xx.h file)"
#error "Please select first the target STM32F4xx device used in your application (in stm32f4xx.h file)"
main.c: 0 warnings, 1 error
"main.c" - 1 Error(s), 0 Warning(s).
作者:
Fake-BBA
时间:
2019-12-30 21:51
比较简单
作者:
Fake-BBA
时间:
2019-12-30 21:52
基本上还是属于简单的,没有结构。
作者:
mxper
时间:
2022-8-3 14:43
下来学习,我也想做一个无刷
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1