1、代码
#include "extern.h"
#define HALL_R() pa.5
#define UN_H() pa.7 = 1
#define UN_L() pa.7 = 0
#define UP_H() pa.4 = 1
#define UP_L() pa.4 = 0
#define VN_H() pa.6 = 1
#define VN_L() pa.6 = 0
#define VP_H() pa.3 = 1
#define VP_L() pa.3 = 0
#define PWM_R() pa.0
#define MIN_START_PWM 3
#define MAX_WAIT_TIME 50000
#define MIN_WAIT_TIME 5000
byte g_Pwm = 0;
byte g_PwmCtl = MIN_START_PWM;
byte g_MotorFlg= 0; // 0正常转 1堵转
byte g_SmoothFlg = 0; //是否平滑 0 启动平滑
byte g_TurnCnt = 0;
byte g_MaxPwm = 100;
word g_MaxWaitTime = MAX_WAIT_TIME;
void Hall_Init()
{
paph.5 = 0;
pac.5 = 0;
}
void Motor_Stop()
{
UN_L();
UP_L();
VN_L();
VP_L();
}
void Motor_Init()
{
paph.3 = 0;
pac.3 = 1;
paph.4 = 0;
pac.4 = 1;
paph.6 = 0;
pac.6 = 1;
paph.7 = 0;
pac.7 = 1;
Motor_Stop();
pwmgclk = 0B10010000; //2M
pwmgcubl = 0B10000000;
pwmgcubh = 0B00001100;
pwmg1c = 0B00000000; //pwmg1c = 0B00000110; //PA4
pwmg1dtl = 0B10000000;
pwmg1dth = 0B00001100;
pwmg2c = 0B00000000; //pwmg2c = 0B00000110; //PA3
pwmg2dtl = 0B10000000;
pwmg2dth = 0B00001100;
}
void Motor_Task()
{
word wait = 0;
if(0 == g_Pwm)
{
Motor_Stop();
g_PwmCtl = MIN_START_PWM;
g_SmoothFlg = 0;
}else
{
g_MotorFlg = 0;
UN_H();
VP_H();
pwmg2dtl = (g_PwmCtl&0x07)<<5;
pwmg2dth = (g_PwmCtl&0xf8)>>3;
pwmg2c = 0B00000110; //PA3
wait = 0;
while(!HALL_R())
{
.Delay 4*20; //这个地方减小有利于降低震动
wait++;
if(wait > g_MaxWaitTime)
{
g_MotorFlg = 1; //堵转
break;
}
}
pwmg2c = 0B00000000;
VP_L();
.Delay 4*60; //启动放电
UN_L();
if (g_MotorFlg == 1)
{
return;
}
VN_H();
UP_H();
pwmg1dtl = (g_PwmCtl&0x07)<<5;
pwmg1dth = (g_PwmCtl&0xf8)>>3;
pwmg1c = 0B00000110; //PA4
wait = 0;
while(HALL_R())
{
.Delay 4*20;
wait++;
if(wait > g_MaxWaitTime)
{
g_MotorFlg = 1; //堵转
break;
}
}
pwmg1c = 0B00000000;
UP_L();
.Delay 4*60; //启动放电
VN_L();
g_TurnCnt += 1;
}
}
/*
void Motor_Restart()
{
word wait = 0;
if(g_MotorFlg == 1)
{
g_PwmCtl = 0;
g_SmoothFlg = 0; //再次启动采用平滑启动
g_MotorFlg = 0;
wait = 0;
if(!HALL_R())
{
VN_H();
UP_H();
pwmg1dtl = (30&0x07)<<5;
pwmg1dth = (30&0xf8)>>3;
pwmg1c = 0B00000110; //PA4
while(!HALL_R())
{
.Delay 4*100;
wait++;
if(wait > 10000)
{
g_MotorFlg = 1;
break;
}
}
pwmg1c = 0B00000000;
UP_L();
.Delay 4*20;
VN_L();
}else
{
UN_H();
VP_H();
pwmg2dtl = (30&0x07)<<5;
pwmg2dth = (30&0xf8)>>3;
pwmg2c = 0B00000110; //PA3
while(HALL_R())
{
.Delay 4*100;
wait++;
if(wait > 10000)
{
g_MotorFlg = 1;
break;
}
}
pwmg2c = 0B00000000;
VP_L();
.Delay 4*20;
UN_L();
}
Motor_Stop();
}
}
*/
void Pwm_Init()
{
paph.0 = 0;
pac.0 = 0;
padier = 0B1111_1000;
adcrgc = 0B0_0000000;
//adcm = 0B0000_0100;
$ ADCM /8;
adcc = 0B10_1010_00;
}
#if 0
void Pwm_Task()
{
#if 0
byte cnt = 8;
word Ad = 0;
while(cnt--)
{
AD_START = 1;
while(!AD_DONE)
{
}
Ad += ADCR;
}
Ad >>= 3;
#endif
word Ad = 0;
AD_START = 1;
while(!AD_DONE)
{
}
Ad += ADCR;
Ad >>= 1;
if(Ad > 12)
{
g_Pwm = Ad - 12;
if(g_Pwm < 20)
{
g_Pwm = 20;
}
if(g_Pwm > 100)
{
g_Pwm = g_MaxPwm;
}
}else
{
g_Pwm = 0;
g_MotorFlg = 0;
}
}
#endif
void t16_init(void)
{
t16m = 0B100_11_111; //262ms
inten.T16 = 1;
}
void Pwm_Ctrl(void)
{
if(0 != g_Pwm
&& 0 == g_MotorFlg)
{
//平滑启动
if(0 == g_SmoothFlg)
{
g_PwmCtl += 4;
if(g_PwmCtl < MIN_START_PWM)
{
g_PwmCtl = MIN_START_PWM;
}
if(g_PwmCtl >= g_Pwm)
{
g_PwmCtl = g_Pwm;
g_SmoothFlg = 1;
g_MaxWaitTime = MIN_WAIT_TIME;
}
}else
{
g_PwmCtl = g_Pwm;
}
}
}
void FPPA0 (void)
{
.ADJUST_IC SYSCLK=IHRC/4 // SYSCLK=IHRC/2
// Insert Initial Code
Hall_Init();
Motor_Init();
Pwm_Init();
t16_init();
ENGINT;
g_Pwm = g_MaxPwm; //不用调速
while (1)
{
// ...
// wdreset;
if(g_MotorFlg == 0)
{
Motor_Task();
}else if(g_MotorFlg == 1)
{
.Delay 4*1000*3000;
g_MaxWaitTime = MAX_WAIT_TIME;
g_PwmCtl = MIN_START_PWM; //堵转启动速度
g_SmoothFlg = 0;
Motor_Task();
//Motor_Restart();
}
//Pwm_Task();
}
}
static byte g_1SCnt = 5;
void Interrupt (void)
{
pushaf;
if (Intrq.T16)
{ // T16 Trig
// User can add code
Intrq.T16 = 0;
//...
Pwm_Ctrl();
g_1SCnt += 1;
if(g_1SCnt >= 4) {
g_1SCnt = 0;
//Pwm_Task();
#if 1
if(g_TurnCnt > 105) {
g_MaxPwm -= 3;
g_Pwm = g_MaxPwm; //不用调速
} else if(g_TurnCnt < 100) {
g_MaxPwm += 3;
if (g_MaxPwm >= 100) {
g_MaxPwm = 100;
}
g_Pwm = g_MaxPwm; //不用调速
}
g_TurnCnt = 0;
#endif
}
}
popaf;
}
2、总结
1)两相在切换的时候,需要稍微延时来将电机上的电流损耗掉,避免转相产生大的毛刺。这个可以看电机线上的波形来判断是不是有毛刺或者尖峰。
2)电机要做堵转检测。
3)电机从静止启动要做平滑升速。
4)电机要做过压超速检测。这个可以根据转相的频率来计算。