采用AVR8位单片机实现模拟发动机曲轴及凸轮轴信号
[复制链接]
在现代发动机技术中,大量的采用了发动机电控技术,为了达到对发动机点火的精确控制,需要获得准确的发动机曲轴、凸轮轴相位和转速,由此ECU才能控制发动机的正确运转,这个过程在发动机控制中称为同步。在通常情况下,我们需要将ECU连接上发动机才能进行同步的调试。BOSCH有一个发动机模拟器,可以进行发动机各种信号的模拟,但很庞大,并且费用高,由此在了解发动机同步信号要求的情况下,结合实际发动机的不同需求,设计了一个发动机曲轴、凸轮轴同步信号产生装置。此装置可以实现曲轴信号模拟;凸轮轴信号模拟;多种类型(单齿、3齿、5齿、7齿)凸轮轴信号的模拟;任意凸轮轴和曲轴信号间的相位差设置。
此装置电路分为三个部分:1、时序信号产生电路;2、单片机曲轴、凸轮轴信号产生电路;3、信号变换电路。三部分电路的功能分别如下:
1、 时序电路:由于发动机曲轴和凸轮轴之间的相位一但确定,在运转中是不会改变的,因此要求曲轴和凸轮轴之间的触发脉冲有较高的同步性,最好用同一个脉冲去触发。另一方面本电路需要适应不同曲轴和凸轮轴相位的情况,由此设计时序电路,一方面保证使用同一个脉冲触发两个信号,又可以对两路信号相位差实施控制。信号发生采用了CD4046的压控频率发生电路。电路中,开关1按下后,曲轴和凸轮轴的触发信号同时禁止,此时通过拨码开关设定凸轮轴和曲轴相位差脉冲数,1个脉冲0.5度曲轴转角。开关1释放,启动时序技术,当凸轮轴时序计数达到设定之后,才开始向单片机提供触发脉冲,由此实现相位差的调整;
2、 单片机曲轴、凸轮轴信号电路:单片机接受到曲轴和凸轮轴的触发信号后,进行序列计数,将触发信号转变为实际的曲轴和凸轮轴转速,使用了720个脉冲曲轴转动1圈,这样曲轴转角分辨率为0.5度。单片机采用了ATmeag8,工作在8M情况,使用了timer0和timer1的计数中断,保证较高的同步性。
3、 信号变换电路:ECU在连接传感器时,有磁电式传感器和霍尔式传感器,为了能够将单片机的高低电平同时适应磁电式信号,高低电平进行转换,转为磁电信号采用RS485芯片,将高低电平对应为正电平和负电平。
电路在protues7.8下进行了模拟,可以正常运转,还未做实际电路的测试。发帖能以望够得到指点!
以下是源代码:
#include
#include
const int Cam1[2]={240,1200,};
const int Cam2[6]={96,264,352,112,248,368,};
const int Cam3[10]={16,74,16,344,16,344,16,344,16,254,};
const int Cam4[12]={16,56,16,272,16,272,16,272,16,272,16,200,};
const int Cam5[14]={16,44,16,224,16,224,16,224,16,224,16,224,16,164,};
const int Cam6[18]={16,32,16,164,16,164,16,164,16,164,16,164,16,164,16,164,16,116,};
//const int Crs[3]={4,8,32,};
int Crs_n,Cas_n;
int Cas[18],Crs;
ISR(TIMER0_COMPA_vect)
{
OCR0A=Crs;
Crs_n=Crs_n+1;
if (Crs==4) Crs=8;
else Crs=4;
if (Crs_n==114 && Crs==8) Crs=32;
}
ISR(TIMER1_COMPA_vect)
{
OCR1A=Cas[Cas_n];
Cas_n=Cas_n+1;
}
void init_devices(void) //meag48 init register
{
cli(); //disable all interrupts
// LCD_init();
DDRB = 0x06; //端口初始化
PORTB = 0x00;
DDRC= 0x00;
PORTC=0x00;
DDRD=0x40;
PORTD=0x8c;
TCCR0A=0x42;
TCCR0B=0x07;
TIMSK0=0x02; //Timer0初始化
TCCR1A=0x40;
TCCR1B=0x0f; /*Timer1初始化*/
TCCR1C=0x00;
TIMSK1=0x02;
// sei(); //re-enable interrupts
}
int main(void)
{
int Cas_tot,n;
char singa_typ;
init_devices();
singa_typ=PIND & 0b10001100;
switch (singa_typ)
{
case 0x88:
Cas_tot=6; //3齿凸轮
for(n=0;n<6;n++)
{
Cas[n]=Cam2[n];
}
break;
case 0x84:
Cas_tot=10; //5齿凸轮
for(n=0;n<10;n++)
{
Cas[n]=Cam3[n];
}
break;
case 0x80:
Cas_tot=12; //6齿凸轮
for(n=0;n<12;n++)
{
Cas[n]=Cam4[n];
}
break;
case 0x0c:
Cas_tot=14; //7齿凸轮
for(n=0;n<14;n++)
{
Cas[n]=Cam5[n];
}
break;
case 0x08:
Cas_tot=18; //9齿凸轮
for(n=0;n<18;n++)
{
Cas[n]=Cam6[n];
}
break;
default:
Cas_tot=2; //单齿凸轮
for(n=0;n<2;n++)
{
Cas[n]=Cam1[n];
}
}
Crs=4;
Crs_n=1;
Cas_n=0;
OCR0A=8 ;
OCR1A=Cas[Cas_n];
Cas_n=Cas_n+1;
TCNT0=0x00;
TCNT1L=0x00;
TCNT1H=0x00;
sei();
PORTB=0b00000100; //计数脉冲输入使能
while(1)
{
if (Cas_n==Cas_tot) Cas_n=0;
if (Crs_n==116) Crs_n=0;
}
}
赞赏
2
查看全部赞赏