德国电调的程序问题
小弟打算在德国电调的基础上用Mega88替代Mega8,并加入换向延时脚,将BootLoader的通讯接口改为I2C,并用PC机串口模拟I2C进行程序烧录,目前已调试完成I2C BootLoader。接下来打算做电机控制,由于小弟以前没接触过无刷电机,德国电调的程序看不大懂,请大家赐教。1、在main.c里面main函数,开环启动后为什么要将PWM设为1,并且检测是检测比较起翻转,应该是当时相位需要检测的边沿才对啊。开环到闭环的转换是不是在接下来的20ms延时时间内完成,后面的300ms延时只是为了检测电流是否过大?
if(Anwerfen(10))
{
GRN_ON;
MotorGestoppt = 0;
Phase--;
PWM = 1;
SetPWM();
SENSE_TOGGLE_INT;
ENABLE_SENSE_INT;
MinUpmPulse = SetDelay(20);
while(!CheckDelay(MinUpmPulse)); // kurz Synchronisieren
PWM = 15;
SetPWM();
MinUpmPulse = SetDelay(300);
while(!CheckDelay(MinUpmPulse)) // kurz Durchstarten
{
if(Strom > LIMIT_STROM/2)
{
STEUER_OFF; // Abschalten wegen Kurzschluss
RotBlink(10);
MotorAnwerfen = 1;
}
}
// Drehzahlmessung wieder aufsetzen
DrehzahlMessTimer = SetDelay(50);
altPhase = 7;
}
2、BLMC.c里的SIGNAL(SIG_COMPARATOR)函数,进入中断后首先保存了比较器输出值,这里的do while循环我的理解是为了检测中断处理过程中是不是发生了下一个过零点,如果是的话进行换向,是不是这样呢?程序里if(sense)else段保持前一相位的MOS管输出,这又是为了什么呢?如果开环启动没有产生足够的反电动势,这里是怎么处理的呢?
SIGNAL(SIG_COMPARATOR)
//############################################################################
{
unsigned char sense = 0;
do
{
if(SENSE_H) sense = 1; else sense = 0;//SENSE_H:电压比零点低
switch(Phase)
{
case 0:
STEUER_A_H;
if(sense)
{
STEUER_C_L;
if(ZeitZumAdWandeln) AdConvert();
SENSE_FALLING_INT;
SENSE_B;
Phase++;
CntKommutierungen++;
}
else
{
STEUER_B_L;
}
break;
case 1:
STEUER_C_L;
if(!sense)
{
STEUER_B_H;
if(ZeitZumAdWandeln) AdConvert();
SENSE_A;
SENSE_RISING_INT;
Phase++;
CntKommutierungen++;
}
else
{
STEUER_A_H;
}
break;
case 2:
STEUER_B_H;
if(sense)
{
STEUER_A_L;
if(ZeitZumAdWandeln) AdConvert();
SENSE_C;
SENSE_FALLING_INT;
Phase++;
CntKommutierungen++;
}
else
{
STEUER_C_L;
}
break;
case 3:
STEUER_A_L;
if(!sense)
{
STEUER_C_H;
if(ZeitZumAdWandeln) AdConvert();
SENSE_B;
SENSE_RISING_INT;
Phase++;
CntKommutierungen++;
}
else
{
STEUER_B_H;
}
break;
case 4:
STEUER_C_H;
if(sense)
{
STEUER_B_L;
if(ZeitZumAdWandeln) AdConvert();
SENSE_A;
SENSE_FALLING_INT;
Phase++;
CntKommutierungen++;
}
else
{
STEUER_A_L;
}
break;
case 5:
STEUER_B_L;
if(!sense)
{
STEUER_A_H;
if(ZeitZumAdWandeln) AdConvert();
SENSE_C;
SENSE_RISING_INT;
Phase = 0;
CntKommutierungen++;
}
else
{
STEUER_C_H;
}
break;
}
}
while((SENSE_L && sense) || (SENSE_H && !sense));
ZeitZumAdWandeln = 0;
}
小弟第一次接触无刷电调,请大家指点迷津 自己顶起来,大家帮帮忙啊 现在按自己的想法把程序编好了,用光驱电机也能从开环转闭环了,闭环的中断程序如下,用模拟比较器触发ICP,用于以后换向延时角的测量,可是我始终搞不明白德国电调里的dowhile的功能,哪位大侠帮帮忙啊。
ISR(TIMER1_CAPT_vect)
{
static unsigned char cnt=0;
BLDC_flag = 2;
switch(phase)
{
case 0: SET_AH;
SET_BL;
SENSE_C;
SENSE_RISING;
phase = 1;
break;
case 1: SET_AH;
SET_CL;
SENSE_B;
SENSE_FALLING;
phase = 2;
break;
case 2: SET_BH;
SET_CL;
SENSE_A;
SENSE_RISING;
phase = 3;
break;
case 3: SET_BH;
SET_AL;
SENSE_C;
SENSE_FALLING;
phase = 4;
break;
case 4: SET_CH;
SET_AL;
SENSE_B;
SENSE_RISING;
phase = 5;
break;
case 5: SET_CH;
SET_BL;
SENSE_A;
SENSE_FALLING;
phase = 0;
break;
default:BLDC_OFF;
break;
}
if(cnt++==200)
{
LED_FLASH;
cnt=0;
}
} 最近也在看电调程序,我觉得那个do while 像是是在比较器中断里检测再发生一次发生过零。
为如果中断里没发生另一次过零的话这个循环是没用的。呵呵,自己分析的,错的话请指正。
另外,德国人的i2c从机接收程序中是这样写的
switch (TWSR & 0xF8)
{
case SR_SLA_ACK:
TWCR |= (1<<TWINT);
Byte_Counter=0;
return;
// Daten Empfangen
case SR_PREV_ACK:
I2C_RXBuffer = TWDR;
I2C_Timeout = 500;
TWCR |= (1<<TWINT);
return;
手到地址发出ack后只进行TWCR |= (1<<TWINT);而dataseet上写应该把TWEA也置一,是不是初始化的时候置一就可以了?
寒,研究程序在i2c这就卡住了,自己写的程序不能运行,检查好多遍都找不到错、楼主能否给我一段i2c主机发送的程序参考下? to 楼上 twi程序
master 可以从FC里面剥离
slave 就在电调程序里面 我没有飞控,I2C master是用PC串口的握手信号模拟的 回复楼主:BLMC.c程序的编写和电机的换相有关,建议你看一下电机的三相是怎么导通的,BLMC.c就是按导通顺序编写的。电机要不断的转动,当然要用到dowhile循环了,不然转一下就停下了啊 换向是在中断函数里实现的,函数SIGNAL(SIG_COMPARATOR){}在blmc.c里。 德国人的电调不像商业电调,建议先看看德国人的电路原理图再来看程序会很快搞明白的。不懂再问! mark mark 哪位大侠能不能简单说一下电调思路
按思路去看德国电调程序
理解更快点
我也是看了好久了
一头雾水 楼主capricorn你用MEGA88的话,能用MK-TOOLS这个工具进行调试吗?我记得MK-TOOLS这个工具德国人用的是MEGA8, 楼主你好,我刚好也在做这个东东,也是用的88,你能否给个QQ号,我们交流下? 嘎嘎,俺也在用MEGA88
页:
[1]