BLDC启动不起来,附程序,图纸
/***********************************************************************//* */
/*FILE :NOHALL_BLDC.c */
/*DATE :Thu, Mar 03, 2011 */
/*DESCRIPTION :main program file. */
/*CPU GROUP :2K */
/* */
/*This file is generated by Renesas Project Generator (Ver.4.18). */
/*NOTE:THIS IS A TYPICAL EXAMPLE. */
/***********************************************************************/
#include "includes.h"
/**********************************************************************************/
/* RAM
/**********************************************************************************/
#definepLED p1_3 //LED
#definepTBU p1_6 //摇头同步电机光耦
#definepkey_TBU p1_5 //同步电机启/停
#define pkey_ON p3_3 //开关
#definepIR p1_4 //遥控接收
#definepTSU p0_5 //调试按钮
#definepIerror p4_5 //过流检测,过流保护
#definepICHECK p0_2 //启动电流检测
#definepMos p3_4 //控制MOS管输出,强制截止
/*
#define pHUPWM p2_1 //U上臂
#definepLUPWM p2_3 //U下臂
#definepNU p2_2 //U相位
#define pHVPWM p2_4 //V上臂
#definepLVPWM p2_6 //V下臂
#definepNV p1_7 //V相位
#define pHWPWM p2_5 //W上臂
#definepLWPWM p2_7 //W下臂
#definepNW p2_0 //W相位
*/
#defineSENSER_DEG0 0x80
#defineSENSER_DEG60 0x81
#defineSENSER_DEG120 0x01
#defineSENSER_DEG180 0x05
#defineSENSER_DEG240 0x04
#defineSENSER_DEG300 0x84
#defineMOTOR_OFF 0x00
#defineMOTOR_START 0x01
/**********************************************************************************/
/* RAM
/**********************************************************************************/
unsigned char flag_on = 0;
unsigned char flag_TBU = 0;
unsigned char ad_num = 0;
unsigned int dianliu_ad = 0;
unsigned int tiaosu_ad = 0;
unsigned int DutyCycle = 0;
unsigned int ClockTick = 0;
unsigned char ErrorFlag = 0;
unsigned char motor_sts = 0;
unsigned int CountTick = 0;
unsigned char SENSINPUT = 0;
unsigned int sens_count = 0;
/**********************************************************************************/
/* ROM
/**********************************************************************************/
/**********************************************************************************/
/* Pragma
/**********************************************************************************/
void MCU_Clock_Init (void); /* Initial setting of MCU operation clock */
void IO_Init(void);
void Timer_RA_Init(void); /* Initial setting of Timer RA SFR */
void Timer_RC_Init(void); /* Initial setting of Timer RC SFR */
void Timer_RD_Init(void); /* Initial setting of Timer RD SFR */
void ADC_Init(void);
static u08 _Sens_Input ( void );
void Motor_Start (void); /* Starting motor */
void State_Switch (unsigned char state); /* Switching to next state */
void Delay_10ms (unsigned char n); /* Delay n*10ms */
void delay_ms (int ms);
void Error_Process(void); /* User's error processing routine */
void tra_handler(void); /* Timer RA interrupt service routine */
void trc_handler(void); /* Timer RC interrupt service routine */
void int0_handler(void); /* INT0 interrupt service routine */
/**********************************************************************************/
/* Main Program
/**********************************************************************************/
void main(void)
{
MCU_Clock_Init(); /* Initial setting of MCU operation clock */
IO_Init();
Timer_RA_Init(); /* Initial setting of Timer RA SFR */
//Timer_RC_Init(); /* Initial setting of Timer RC SFR */
Timer_RD_Init(); /* Initial setting of Timer RD SFR */
ADC_Init();
asm("FSET I");
while(1)
{
if (pkey_ON == 0)
{
if (flag_on == 0)
{
DutyCycle = 1235;
//Timer_RD_Init();
State_Switch(SENSER_DEG120);
SENSINPUT = SENSER_DEG120;
sens_count = 0;
//delay_ms(1);
trdstr= 0x0F;
//delay_ms(5);
flag_on = 1;
//pLED = 0;
}
else
{
flag_on = 0;
//pLED = 1;
if (flag_TBU == 1)
{
flag_TBU = 0;
// pTBU =1;
}
}
Delay_10ms(10);
while(!pkey_ON);
Delay_10ms(30);
}
if (pkey_TBU == 0)
{
if (flag_on == 1)
{
if (flag_TBU == 0)
{
flag_TBU = 1;
// pTBU = 0;
}
else
{
flag_TBU = 0;
// pTBU = 1;
}
Delay_10ms(10);
while(!pkey_TBU);
Delay_10ms(30);
}
}
}
}
/**********************************************************************************/
/* MCU clock initialization
/**********************************************************************************/
void MCU_Clock_Init(void)
{
_asm("FCLR I"); //Interrupt disabled
prc0=1; //Protect off
//**************************************
// CPU Clock Setting
//**************************************
//Note: Include asm("nop") for oscillator's stabilization period after clock setting is done
cm13=0;cm05=1;cm02=0;cm14=0;ocd0=0;ocd1=0; //On-chip oscillator selected(cm0 bit 2 and 5, cm1 bit 3 and 4, ocd bit 0 and 1)
ocd2=1; //On-chip oscillator selected(ocd bit 2)
cm16=0;cm17=0;cm06=0; //CPU时钟不分频
fra00=1;fra01=1;fra20=0;fra21=0;fra22=0;
prc0=0; //Protect on
}
//----------------------------------------------------------------
void IO_Init()
{
//**************************************
// Port0 Setting
//**************************************
//Read/write data to register P0
prc2=1; //Enable write to PD0(prcr bit 2)
pd0=0x0B; //Port P0 direction register
//**************************************
// Port1 Setting
//**************************************
//Read/write data to register P1
pd1=0xCF; //Port P1 direction register
//**************************************
// Port2 Setting
//**************************************
//Read/write data to register P2
pd2=0xFA; //Port P2 direction register
p2drr=0xFA; //Port P2 drive capacity control register
p2 = 0b11001000;
//**************************************
// Port3 Setting
//**************************************
//Read/write data to register P3
pd3=0x30; //Port P3 direction register
//**************************************
// Port4 Setting
//**************************************
//Read/write data to register P4
pd4=0x00; //Port P4 direction register
pLED = 1;
}
//----------------------------------------------------------------
/**********************************************************************************/
/* Initial setting of Timer RA SFR
/**********************************************************************************/
void Timer_RA_Init (void)
{
//**************************************
// Timer RA Setting
//**************************************
tstart_tracr=0; //t = trapre * tra /(Fosc/2) = 250 * 40 /(40 / 2) = 500us = 0.5ms
tcstf_tracr=0; //t = trapre * tra /(Fosc/2) = 250 * 2 /(40 / 2) = 25us = 0.025ms
trapre=249; //Set timer value(for timer mode)/half period timing(for pulse output mode) to trapre and tra
tra=4; //Set timer value(for timer mode)/half period timing(for pulse output mode) to trapre and tra
tmod0_tramr=0;tmod1_tramr=0;tmod2_tramr=0;//Timer mode selected(tramr bit 0, 1 and 2)
tck0_tramr=0;tck1_tramr=0;tck2_tramr=0;//Count source f1 selected(tramr bit 4, 5 and 6)
traic=0x06; //Set interrupt priority level 0(traic)
tstart_tracr=1; //Set tstart_tracr=1 to start Timer RA counting
//Note: Timer RA does not start yet for event counter mode.
//The first active edge of external signal is used not to decrement the timer count register but to start timer RA.
//The second active edge will trigger the first decrement on timer count register.
}
/**********************************************************************************/
/* Initial setting of Timer RC SFR
/**********************************************************************************/
void Timer_RC_Init (void)
{
pur0 = 0x84; /* Pull-up P1_1, P1_2 and P3_4 when using as input */
/* capture port: TRCIOA, TRCIOB, TRCIOC */
trcic = 0x00; /* Disable Timer RC Interrupt */
trcmr = 0x08; /* Stop Timer RC and set Timer RC to work in Timer Mode */
/* (Input Capture Function) */
trccr1 = 0x40; /* Select Counter Source: f32 */
trcier = 0x87; /* Enable Input Capture interrupts on channel A, B and*/
/* C. Enable Timer RC Overflow interrupt */
trcior0 = 0x6E; /* Input Capture occurs at both rising and falling */
trcior1 = 0x66; /* edges on channel A, B and C */
trc = 0; /* Clear counter register and general regesters A, B */
trcgra = 0; /* and C */
trcgrb = 0;
trcgrc = 0;
trcdf = 0x05; /* Enable digital filter on channel A, B and C */
/* digital filter's sampling clock: f32 */
trcmr |= 0x80; /* Start Timer RC */
}
/**********************************************************************************/
/* Initial setting of Timer RD SFR
/**********************************************************************************/
void Timer_RD_Init (void)
{
trd0ic = 0x00; /* Disable Timer RD Interrupt */
trd1ic = 0x00; /* Disable Timer RD Interrupt */
trdstr = 0x0C; /* Stop Timer RD. Count continues after compare match */
/* between TRD0 and TRDGRA0; between TRD1 and TRDGRA1 */
trdmr = 0xE0; /* TRDGRD0, TRDGRC1 and TRDGRD1 function as buffer */ /* registers of TRDGRB0, TRDGRA1 and TRDGRB1 */
trdfcr = 0x07; /* Transfer value set in buffer registers to general */ /* registers at the compare match between TRD0 and */
/* TRDGRA0. Normal-phase and Counter-phas output: */
/* Initial output 'L', Active level 'H' */
//trdoer1 = 0xff; /* Disable all PWM output */
ols0_trdfcr=1; //Normal-phase initial output "L", active level "H"(trdfcr bit 2)
ols1_trdfcr=0; //Counter-phase initial output "H", active level "L"(trdfcr bit 3)
eb0_trdoer1=1; //TRDIOB0 output disabled(trdoer1 bit 1)
ec0_trdoer1=1; //TRDIOC0 output disabled(trdoer1 bit 2)
ed0_trdoer1=1; //TRDIOD0 output disabled(trdoer1 bit 3)
ea1_trdoer1=1; //TRDIOA1 output disabled(trdoer1 bit 4)
eb1_trdoer1=1; //TRDIOB1 output disabled(trdoer1 bit 5)
ec1_trdoer1=1; //TRDIOC1 output disabled(trdoer1 bit 6)
ed1_trdoer1=1; //TRDIOD1 output disabled(trdoer1 bit 7)
trdcr0 = 0x06; /* Count source: f1 */
trdcr1 = 0x06; /* Count source: f1 */
trd0 = 30; /* Dead time: 1/fk*p = 3.6us */
trd1 = 0;
trdgra0 = 1240; /* Carrier frequency: 1/(1/fk*(m+2-p)*2) = 15kHz */
trdgrb0 = DutyCycle; /* -----------------PWM duty cycle----------------------*/
trdgra1 = DutyCycle; /* Active level width of normal-phase: 1/fk*(m-n-p+1)*2 */
trdgrb1 = DutyCycle; /* Active level width of counter-phase: 1/fk*(n+1-p)*2*/
/* fk: Frequency of count source */
/* m:Value set in the TRDGRA0 register */
/* n:Value set in the TRDGRB0 register (PWM1 output)*/
/* Value set in the TRDGRA1 register (PWM1 output)*/
/* Value set in the TRDGRB1 register (PWM1 output)*/
/* p:Value set in the TRD0 register (dead time) */
//trdgrd0 = DutyCycle; /* Load new duty cycle value in buffer registers */
//trdgrc1 = DutyCycle; /* New duty cycle value will be load from buffer */
//trdgrd1 = DutyCycle; /* registers to general registers at the compare match*/
/* between TRD0 and TRDGRA0 */
int0ic= 0x00; /* Disable INT0 Interrupt */
inten = 0x01; /* Enable INT0 input, one edge */
intf = 0x03; /* INT0 input filtered with f32 sampling */
trdoer2 = 0x80; /* Enable pulse output forced cutoff signal input INT0*/
int0ic= 0x07; /* Enable INT0 Interrupt, priority level: 7 */
//trdstr= 0x0F; /* Start timer RD */
//p2 = 0x11001000;
}
//**************************************
// ADC Setting
//**************************************
void ADC_Init(void)
{
//When using the repeat mode, use the undivided XIN clock as the CPU clock. Do not select the fOCO-F as ADC operating clock
//Note:For 8-bit resolution, when conversion finished, read AD result at AD register(00C0H).
//Note:For 10-bit resolution, when conversion finished, read AD result at AD register(00C0H,00C1H).
vcut=1;adgsel0=0;ch0=0;ch1=1;ch2=0; //Port P0 group: AN2 is selected(adcon0 bit 0-3)
md=0; //Repeat mode selected(adcon0 bit 3)
cks1=0; cks0=0; //f4 selected(adcon1 bit 4 and adcon0 bit 7)
bits=1; //8-bit mode selected(adcon1 bit 3)
smp=0; //Without sample and hold selected(adcon2 bit 0)
adst=1; //A/D conversion starts(adcon0 bit 6)
adic=0x04; //Set interrupt priority level 4(adic)
}
/**********************************************************************************/
/* Timer RA interrupt service routine
//t = trapre * tra /(Fosc/2) = 250 * 2 /(40 / 2) = 25us = 0.025ms
/**********************************************************************************/
#pragma INTERRUPT /B timer_ra
void timer_ra(void) //定时器A中断子程序
{
ClockTick++;
if (flag_on == 1)
{
if (SENSINPUT!=_Sens_Input())
{
sens_count++;
if (sens_count == 5)
{
sens_count = 0;
SENSINPUT = _Sens_Input();
State_Switch(SENSINPUT);
trdgrd0 = DutyCycle;
trdgrc1 = DutyCycle;
trdgrd1 = DutyCycle;
}
}
if(motor_sts == MOTOR_OFF)
{
if (DutyCycle>tiaosu_ad)
{
CountTick++;
if (CountTick>=40)//2400ms = 620*n*25us
{
CountTick = 0;
DutyCycle--;
}
}
else
{
motor_sts = MOTOR_START;
}
}
if (motor_sts == MOTOR_START)//速度改变
{
if (DutyCycle>(tiaosu_ad-10))
{
DutyCycle = tiaosu_ad;
}
else
{
if (DutyCycle<(tiaosu_ad+10))
{
DutyCycle = tiaosu_ad;
}
}
}
}
else
{
if(motor_sts == MOTOR_START)
{
if (DutyCycle<1240)
{
CountTick++;
if (CountTick>=40)//2400ms = 620*n*25us
{
CountTick = 0;
DutyCycle++;
}
if (SENSINPUT!=_Sens_Input())
{
sens_count++;
if (sens_count == 5)
{
sens_count = 0;
SENSINPUT = _Sens_Input();
State_Switch(SENSINPUT);
trdgrd0 = DutyCycle;
trdgrc1 = DutyCycle;
trdgrd1 = DutyCycle;
}
}
}
else
{
motor_sts = MOTOR_OFF;
Timer_RD_Init();
DutyCycle = 0;
trdstr= 0;
p2 = 0b11001000;
}
}
}
//开机LED显示
if (flag_on == 1)
{
pLED = 0;
if (flag_TBU == 1)
{
pTBU = 0;
}
else
{
pTBU = 1;
}
}
else
{
pLED = 1;
if (flag_TBU == 1)
{
pTBU = 1;
}
}
}
/**********************************************************************************/
/* Timer RC interrupt service routine
/**********************************************************************************/
#pragma INTERRUPT /B trc_handler
void trc_handler(void)
{
}
/**********************************************************************************/
/* INT0 interrupt service routine
/**********************************************************************************/
#pragma INTERRUPT /B int0_handler
void int0_handler(void)
{
p2 = 0b11001000; /* Stop motor */
trdoer1 = 0xff; /* Disable Timer RD outputs */
trdstr= 0;//traic = 0; /* Disable Timer RC Interrupt */
ErrorFlag = 1; /* Indicate over current error occured */
flag_on = 0;
motor_sts = MOTOR_OFF;
DutyCycle = 1240;
Timer_RD_Init();
}
/**********************************************************************************/
/* ADC interrupt service routine
/**********************************************************************************/
#pragma INTERRUPT /B ADC_Interrupt
void ADC_Interrupt(void) //ADC中断子程序
{
ir_adic=0;
/*用户程序*/
if(ad_num == 0)//检测电机运行电流
{
ad_num = 1;
tiaosu_ad=ad;//0x00~0x3ff
tiaosu_ad = tiaosu_ad*1.22;
if(tiaosu_ad>1240)
{
tiaosu_ad = 0;
}
else
{
tiaosu_ad = 1240 - tiaosu_ad;
}
ch0=1;ch1=0;ch2=1;//P0_2 AN5
}
else//检测用户调速,速度
{
ad_num = 0;
dianliu_ad = ad;//0x00~0xff
ch0=0;ch1=1;ch2=0;//P0_5 AN2
if (dianliu_ad>700)//0.29V
{
p2 = 0b11001000; /* Stop motor */
trdoer1 = 0xff; /* Disable Timer RD outputs */
trdstr= 0;//traic = 0; /* Disable Timer RC Interrupt */
ErrorFlag = 1; /* Indicate over current error occured */
flag_on = 0;
motor_sts = MOTOR_OFF;
DutyCycle = 1240;
Timer_RD_Init();
}
}
adst = 1;
}
/**********************************************************************************/
/* Starting motor
/**********************************************************************************/
void Motor_Start (void)
{
}
/**********************************************************************************/
/* Switching to next state
/**********************************************************************************/
void State_Switch (unsigned char state)
{
switch (state) {
case SENSER_DEG0: /* State 1: UpVn*/
eb0_trdoer1=1;//HU -- p2_1 //TRDIOB0 output enabled(trdoer1 bit 1)
ec0_trdoer1=1;//TRDIOC0 output disabled(trdoer1 bit 2)
ed0_trdoer1=1; //TRDIOD0 output disabled(trdoer1 bit 3)
ea1_trdoer1=0;//HV -- p2_4 //TRDIOA1 output enabled(trdoer1 bit 4)
eb1_trdoer1=1;//HW -- p2_5//TRDIOB1 output enabled(trdoer1 bit 5)
ec1_trdoer1=1;//TRDIOC1 output disabled(trdoer1 bit 6)
ed1_trdoer1=1;//TRDIOD1 output disabled(trdoer1 bit 7)
//p2_3 = 0; //LU
//p2_6 = 1; //LV
//p2_7 = 1; //LW
p2 = 0b11000000;
break;
case SENSER_DEG60:/* State 2: UpWn*/
eb0_trdoer1=1;//HU -- p2_1 //TRDIOB0 output enabled(trdoer1 bit 1)
ec0_trdoer1=1;//TRDIOC0 output disabled(trdoer1 bit 2)
ed0_trdoer1=1; //TRDIOD0 output disabled(trdoer1 bit 3)
ea1_trdoer1=1;//HV -- p2_4 //TRDIOA1 output enabled(trdoer1 bit 4)
eb1_trdoer1=0;//HW -- p2_5//TRDIOB1 output enabled(trdoer1 bit 5)
ec1_trdoer1=1;//TRDIOC1 output disabled(trdoer1 bit 6)
ed1_trdoer1=1;//TRDIOD1 output disabled(trdoer1 bit 7)
//p2_3 = 0; //LU
//p2_6 = 1; //LV
//p2_7 = 1; //LW
p2 = 0b11000000;
break;
case SENSER_DEG120:/* State 3: VpWn*/
eb0_trdoer1=1;//HU -- p2_1 //TRDIOB0 output enabled(trdoer1 bit 1)
ec0_trdoer1=1;//TRDIOC0 output disabled(trdoer1 bit 2)
ed0_trdoer1=1; //TRDIOD0 output disabled(trdoer1 bit 3)
ea1_trdoer1=1;//HV -- p2_4 //TRDIOA1 output enabled(trdoer1 bit 4)
eb1_trdoer1=0;//HW -- p2_5//TRDIOB1 output enabled(trdoer1 bit 5)
ec1_trdoer1=1;//TRDIOC1 output disabled(trdoer1 bit 6)
ed1_trdoer1=1;//TRDIOD1 output disabled(trdoer1 bit 7)
//p2_3 = 1; //LU
//p2_6 = 0; //LV
//p2_7 = 1; //LW
p2 = 0b10001000;
break;
case SENSER_DEG180:/* State 4: VpUn*/
eb0_trdoer1=0;//HU -- p2_1 //TRDIOB0 output enabled(trdoer1 bit 1)
ec0_trdoer1=1;//TRDIOC0 output disabled(trdoer1 bit 2)
ed0_trdoer1=1; //TRDIOD0 output disabled(trdoer1 bit 3)
ea1_trdoer1=1;//HV -- p2_4 //TRDIOA1 output enabled(trdoer1 bit 4)
eb1_trdoer1=1;//HW -- p2_5//TRDIOB1 output enabled(trdoer1 bit 5)
ec1_trdoer1=1;//TRDIOC1 output disabled(trdoer1 bit 6)
ed1_trdoer1=1;//TRDIOD1 output disabled(trdoer1 bit 7)
//p2_3 = 1; //LU
//p2_6 = 0; //LV
//p2_7 = 1; //LW
p2 = 0b10001000;
break;
case SENSER_DEG240:/* State 5: WpUn*/
eb0_trdoer1=0;//HU -- p2_1 //TRDIOB0 output enabled(trdoer1 bit 1)
ec0_trdoer1=1;//TRDIOC0 output disabled(trdoer1 bit 2)
ed0_trdoer1=1; //TRDIOD0 output disabled(trdoer1 bit 3)
ea1_trdoer1=1;//HV -- p2_4 //TRDIOA1 output enabled(trdoer1 bit 4)
eb1_trdoer1=1;//HW -- p2_5//TRDIOB1 output enabled(trdoer1 bit 5)
ec1_trdoer1=1;//TRDIOC1 output disabled(trdoer1 bit 6)
ed1_trdoer1=1;//TRDIOD1 output disabled(trdoer1 bit 7)
//p2_3 = 1; //LU
//p2_6 = 1; //LV
//p2_7 = 0; //LW
p2 = 0b01001000;
break;
case SENSER_DEG300:/* State 6: WpVn*/
eb0_trdoer1=1;//HU -- p2_1 //TRDIOB0 output enabled(trdoer1 bit 1)
ec0_trdoer1=1;//TRDIOC0 output disabled(trdoer1 bit 2)
ed0_trdoer1=1; //TRDIOD0 output disabled(trdoer1 bit 3)
ea1_trdoer1=0;//HV -- p2_4 //TRDIOA1 output enabled(trdoer1 bit 4)
eb1_trdoer1=1;//HW -- p2_5//TRDIOB1 output enabled(trdoer1 bit 5)
ec1_trdoer1=1;//TRDIOC1 output disabled(trdoer1 bit 6)
ed1_trdoer1=1;//TRDIOD1 output disabled(trdoer1 bit 7)
//p2_3 = 1; //LU
//p2_6 = 1; //LV
//p2_7 = 0; //LW
p2 = 0b01001000;
break;
default:
break;
}
}
/**********************************************************************************/
/* _Sens_Input
/**********************************************************************************/
static u08 _Sens_Input ( void )
{
u08 work0,work1;
work0 = p2 & 0b00000101;
work1 = p1 & 0b10000000;
return (work0 |= work1);
}
/**********************************************************************************/
/* Delay n*10ms
/**********************************************************************************/
void Delay_10ms (unsigned char n)
{
ClockTick = 0;
while(ClockTick <= n);
}
/**********************************************************************************/
/* User's error processing routine
/**********************************************************************************/
void Error_Process (void)
{
}
void delay_ms(int ms)
{
while(ms--)
{
_asm("nop");
_asm("nop");
_asm("nop");
}
}
NOHALL_BLDCourdev_623338WBJDZ6.pdf(文件大小:65K) (原文件名:NOHALL_BLDC.pdf)
那位帮忙指点一下,谢谢! 启动不起来主要是启动阶段加速设计不合理,考虑使用S加速方式,加速度应该是小-大-小,这样可以保证稳定过渡到闭环。 楼主,超前相位30°是怎么解释的?在这电路中是怎么分析的,?谢谢! 芯片是瑞萨的R8C2K2L 0C062 回复【3楼】xuysh
-----------------------------------------------------------------------
做好了吗? BLDC mark 我的也是启动不起来,启动的时候电机抖动两下就停掉了,不知道咋回事 我用79F1211实现了启动,过流等,但是在用转把加速启动时,噪音似乎有点大,不知2楼的S加速方式,是如何实现的? 我的也是启动不起来,启动的时候电机抖动两下就停掉了 闭环控制失败
无霍尔的启动是最大的问题 加速过程估计设计的不太合适! 学习{:smile:} BLDC mark{:smile:} 等高手解决方案出炉 bldc make~~~~
BLDC mark
BLDC mark
页:
[1]