La idea u objetivo
del proyecto es controlar un motor de un automóvil, para después de ponerlo en
funcionamiento, poder controlar
diferentes reacciones. Para ello hemos creado una CPU o Unidad de control que
controle diferentes parámetros. También se conoce como centralita y su función
es controlar varios parámetros para poder dar respuesta a las peticiones del
usuario. El motor es de la marca OPEL, tiene 4 cilindros y en cada cilindro
tiene un inyector y una bujía para poder crear la combustión necesaria para su funcionamiento.
La CPU o Unidad de
control debe controlar los siguientes parámetros:
- Cantidad de masa de
aire de entrada al motor en porcentajes (%0, %5, %25, %50, %75, %100).
- Tiempo de inyección
de gasolina en milisegundos (de 0ms a 16ms).
- Angulo de avance
del salto de chispa respecto al PMS (Punto muerto superior) y PMI (Punto
muerto inferior). También conocido como ángulo Dwell.
Para
poder controla todos estos parametros tendremos una señal situada en el motor.
Esta
señal nos la proporcionara un sensor inductivo situado en el bolante motor.
Interpretando esta señal y conociendo los diferentes parámetros debemos dar
respuesta a las peticiones del usuario.
Tiempo de inyeccion y angulo Dwell
(Alimentacion, etapa de control y etapa de potencia)
Medidor de masa de aire
(Etapa de control )
(Etapa de potencia; puente en H)
PROGRAMA
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*********************************************************************
*********************************************************************
AUTOAREN CPU OPEL 2000 16v
MOTOREAN PROBATZEKO BERTSIOA
********************************************************************
OPEL: Sensor Inductivo: 57+1 Dientes=58 flanko positibo
Tiempo inyeccion+Angulo Dwell
*********************************************************************/
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <16F877.H> //16F877 PIC-a erabiliko dugu Inyekzioa eta txispa kontrolatzeko
#device ADC=10 //Bihurgailu analogiko/digitalak 10 byte edukiko ditu//1024
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4M) //4MHz-tako kristal harria
#use RS232(baud=19200, xmit=PIN_C6, rcv=PIN_C7,DISABLE_INTS)//Serie Portua
#include <math.h> //19200Abiadura//Pin C6 datuak bidaltzeko
//Disable_Ints Etendurak desabilitatzen ditu RS232 Serie Portutik datuak bidaltzerakoan
int1 k=0; //RPM-ak kalkulatzeko agindua
float t1=0; //Hortzen arteko oraingo denbora
float t2=0; //Hortzen arteko aurreko denbora
int8 kont_dient=0; //Bira batean hortz kopurua
float aux_rpm=0; //Abiadura RPM-tan
int16 rpm; //Abiadura RPM-tan
int16 t_grado; //Gradu bat igarotzeko behar den denbora
int16 pot_iny; //Inyekzio denbora; Potentziometroa balio digitala
int16 pot_av; //Angulo Avance; Potentziometroa balio digitala
int16 VDmax=1024; //Balio digital maximoa;ADC=10(byte) bada->1024/ADC=8(byte) bada->255
int8 Tmax=17; //Inyekzio denbora maximoa
int8 T=0; //Inyekzio denbora
int8 Gmax=43; //Gradu maximoa ez errealak;24 gradu negatibo+18 gradu positibo=42 gradu guztira
int8 G=0; //Graduak ez errealak; 0 gradutik 43 gradu arte
signed int8 Gr=0; //Gradu errealak; Gradu ez errealak-24
float a=0; //Hortzetik hortzera dagoen denbora segunduetan, hau da t1-etik t2-ra dagoen denbora
float b=0; //1 bira zenbat segundu diren kalkulatzeko;1 bira = 360º = 58 flanko positibo = 60 hortz
int8 i;
char bidali[7]; //Portu serietik bidaltzeko datuak;
//rpm (2 digitu)/angelu (zeinua + 2 digitu)/inyekzio (2 digitu)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/********************************************************************
Interrupcion TIMER 2 Etendura
Inyekzioa mozteko erabiliko dugu
********************************************************************/
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#int_timer2
void tiempo2(void)
{
output_low(PIN_C2); //Inyektorea itzali
output_low(PIN_C3); //Inyektorea itzali
disable_interrupts(INT_TIMER2); //Timer 2 Etendura desaktibatu
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**********************************************************************
Kampoko Etendura PIN_B0
Birak kontatzeko erabiliko dugu
***********************************************************************/
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#int_ext
void birak(void)
{
t1=get_timer1(); //2 hortzen harteko denbora hartu//get timer-aren bidez momentuan timerraren akumulagailuan dagoen balioa artuko du
set_timer1(0); //Timer1 Hasieratu, momentu honetan timer-a kontatzen hasiko da
if((t1>1.5*t2)||(kont_dient>=58)) //Oraingo denbora, aurreko denbora baino andiagoa bada
{ //PMS -ean dagoela esan nahi du beraz kontaketa hasi
kont_dient=1;
}
else
{
kont_dient ++; //Kont_dient inkrementatu
if((kont_dient==5)||(kont_dient==34)) //Gasolina inyektatu
{
output_high(PIN_C2); //Inyectar
output_high(PIN_C3); //Inyectar
setup_timer_2 ( T2_DIV_BY_16,pot_iny/4,4 ); //Timer 2 konfiguratu//Inkrementu bakoitzak 16uS,potentziometroaren bidez kargatu behar dugun balioa artuko du.
set_timer2(0); //Timer2 Hasieratu//etendura abilitatu bezahin laster asiko da kontaketa gainezka egin arte, timer-ak gainezka egitean etendurara joango da eta inyektoreak itzali egingo ditu
enable_interrupts(INT_TIMER2); //Timer 2 Etendura aktibatu
}
if(kont_dient==10) //RPM-ak kalkulatzeko
{
k=1;
}
}
t2=t1; //Oraingo denbora aurreko bezala gorde
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**********************************************************************
Funtzio Nagusia
**********************************************************************/
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void main(void)
{
delay_ms(2000);
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_1 ); //Timer 1 konfiguratu//Inkrementu bakoitzak 1uS
set_timer1(0); //Timer1 Hasieratu
//setup_timer_0 ( RTCC_INTERNAL | RTCC_DIV_64 ); //Timer 0//0-16,320ms//Inkrementu bakoitzak 64uS
//set_rtcc(0); //Timer0 hasieratu
setup_timer_2 ( T2_DIV_BY_16,0xff,4 ); //Timer 2 konfiguratu//Inkrementu bakoitzak 16uS
set_timer2(0); //Timer2 Hasieratu
enable_interrupts(INT_TIMER2); //Timer 2 Etendura aktibatu
enable_interrupts(GLOBAL); //Etendura guztiak aktibatu
enable_interrupts(INT_EXT); //Kampoko etendura aktibatu B0 portua, B0 portuan kanpoko seinale bat jasotzean programa nagusia utzi eta programa zati zehatz batetara joaten da
ext_int_edge(H_TO_L); //Kampoko etendura aktibatu LtoH(goranzko flankoa), hau da 0v-tik 5v-rako aldaketa somatzen duenean exekutatzen hari den programa utzi eta int_ext etendurara joango da bertan dauden aginduak exekutatzeko
setup_adc_ports(AN0_AN1_AN3); //PIN A0,A1 eta A3 Analogiko bezala konfiguratu, hau da pin hauetan balio analogiko bat sartuko dugu eta pic-ak balio hau digital bihurtuko du//ADC=10 bada 10 byteraino hau da 1024 arteko balio tartea// ADC=8 bada 8 byterain, hau da 255 arteko balio tartea.
setup_adc(adc_clock_internal); //CAD Konfiguratu
while(1)
{
//RPM//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if(k==1)
{
a=((t1/1000.0)/1000.0); //Hortzetik hortzera dagoen denbora microsegundutatik segundutara pasatu //3300uS = 0,0033s
b=a*58.0; //1 bira zenbat segundu diren kalkulatzeko// Motorrean 58 hortz
aux_rpm=60.0/b; //Bira kopurua minutuko RPM //60/0,2=300rpm
rpm=aux_rpm; //aux_rpm:float/rpm:int16
k=0; //RPM-ak kalkulatzeko balioa 0-an jarri
}
//TIEMPO INYECCION/////////////////////////////////////////////////////////////////////////////////////////////////////
set_adc_channel(0); //A0 kanala aktibatu
delay_us(10);
pot_iny=read_adc(); //A0-tik sartutako balioa irakurri
T=pot_iny*Tmax/VDmax; //Inyekzio denbora milisegundutan
//ANGULO AVANCE////////////////////////////////////////////////////////////////////////////////////////////////////////
set_adc_channel(1); //A1 kanala aktibatu
delay_us(10);
pot_av=read_adc(); //A1-etik sartutako balioa irakurri
G=pot_av*Gmax/VDmax; //Angulo avance gradutan
Gr=G-24;
//DATUAK EGOKITU///////////////////////////////////////////////////////////////////////////////////////////////////////
bidali[0]=rpm/1000; bidali[0]=bidali[0]+0x30;//RPM; Milakoak kalkulatu eta ASCII kodera pasa
bidali[1]=(rpm%1000)/100; bidali[1]=bidali[1]+0x30;//RPM; Ehunekoak kalkulatu eta ASCII kodera pasa
if(Gr<0) //Angulo de Avance negatiboa
bidali[2]='-';
else //Angulo de Avance positiboa
bidali[2]='+';
bidali[3]=fabs(Gr)/10; bidali[3]=bidali[3]+0x30;//Angulo de Avance; Hamarrekoa kalkulatu eta ASCII kodera pasa
bidali[4]=fabs(Gr)%10; bidali[4]=bidali[4]+0x30;//Angulo de Avance; Batekoak kalkulatu eta ASCII kodera pasa
bidali[5]=T/10; bidali[5]=bidali[5]+0x30;//Inyekzioa: Hamarrekoak kalkulatu eta ASCII kodera pasa
bidali[6]=T%10; bidali[6]=bidali[6]+0x30;//Inyekzioa; Batekoak kalkulatu eta ASCII kodera pasa
//PORTU SERIEA RS232////////////////////////////////////////////////////////////////////////////////////////////////////
disable_interrupts(global); //Etendurak desaktibatu
putc('Z'); //Komunikazioa hasteko marka
for(i=0;i<7;i++)
putc(bidali[i]); //Datuak bidali portu serietik
enable_interrupts(global); //Etendurak aktibatu
//BUJIAK////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if((Gr<=18)&&(Gr>12)) //18º
{
while(kont_dient!=3)
{
output_high(PIN_C0); //Bujias 1-4 kargatu
output_high(PIN_C1); //Bujias 2-3 kargatu
}
output_low(PIN_C0); //Bujias 1-4 Deskargatu!!¡!¡!
delay_us(500);
while(kont_dient!=32)
{
output_high(PIN_C0); //Bujias 1-4 kargatu
output_high(PIN_C1); //Bujias 2-3 kargatu
}
output_low(PIN_C1); //Bujias 2-3 Deskargatu!!¡!¡!
delay_us(500);
}
else if((Gr<=12)&&(Gr>6)) //12º
{
while(kont_dient!=2)
{
output_high(PIN_C0); //Bujias 1-4 kargatu
output_high(PIN_C1); //Bujias 2-3 kargatu
}
output_low(PIN_C0); //Bujias 1-4 Deskargatu!!¡!¡!
delay_us(500);
while(kont_dient!=31)
{
output_high(PIN_C0); //Bujias 1-4 kargatu
output_high(PIN_C1); //Bujias 2-3 kargatu
}
output_low(PIN_C1); //Bujias 2-3 Deskargatu!!¡!¡!
delay_us(500);
}
else if((Gr<=6)&&(Gr>0)) //6º
{
while(kont_dient!=1)
{
output_high(PIN_C0); //Bujias 1-4 kargatu
output_high(PIN_C1); //Bujias 2-3 kargatu
}
output_low(PIN_C0); //Bujias 1-4 Deskargatu!!¡!¡!
delay_us(500);
while(kont_dient!=30)
{
output_high(PIN_C0); //Bujias 1-4 kargatu
output_high(PIN_C1); //Bujias 2-3 kargatu
}
output_low(PIN_C1); //Bujias 2-3 Deskargatu!!¡!¡!
delay_us(500);
}
else if((Gr<=2)&&(Gr>=-2)) //0º
{
while(kont_dient!=58)//PMS//
{
output_high(PIN_C0); //Bujias 1-4 kargatu
output_high(PIN_C1); //Bujias 2-3 kargatu
}
output_low(PIN_C0); //Bujias 1-4 Deskargatu!!¡!¡!
delay_us(500);
while(kont_dient!=29)//Erdia PMI//
{
output_high(PIN_C0); //Bujias 1-4 kargatu
output_high(PIN_C1); //Bujias 2-3 kargatu
}
output_low(PIN_C1); //Bujias 2-3 Deskargatu!!¡!¡!
delay_us(500);
}
else if((Gr<0)&&(Gr>=-6)) //-6º
{
while(kont_dient!=57)
{
output_high(PIN_C0); //Bujias 1-4 kargatu
output_high(PIN_C1); //Bujias 2-3 kargatu
}
output_low(PIN_C0); //Bujias 1-4 Deskargatu!!¡!¡!
delay_us(500);
while(kont_dient!=28)
{
output_high(PIN_C0); //Bujias 1-4 kargatu
output_high(PIN_C1); //Bujias 2-3 kargatu
}
output_low(PIN_C1); //Bujias 2-3 Deskargatu!!¡!¡!
delay_us(500);
}
else if((Gr<-6)&&(Gr>=-12)) //-12º
{
while(kont_dient!=56)
{
output_high(PIN_C0); //Bujias 1-4 kargatu
output_high(PIN_C1); //Bujias 2-3 kargatu
}
output_low(PIN_C0); //Bujias 1-4 Deskargatu!!¡!¡!
delay_us(500);
while(kont_dient!=27)
{
output_high(PIN_C0); //Bujias 1-4 kargatu
output_high(PIN_C1); //Bujias 2-3 kargatu
}
output_low(PIN_C1); //Bujias 2-3 Deskargatu!!¡!¡!
delay_us(500);
}
else if((Gr<-12)&&(Gr>=-18)) //-18º
{
while(kont_dient!=55)
{
output_high(PIN_C0); //Bujias 1-4 kargatu
output_high(PIN_C1); //Bujias 2-3 kargatu
}
output_low(PIN_C0); //Bujias 1-4 Deskargatu!!¡!¡!
delay_us(500);
while(kont_dient!=26)
{
output_high(PIN_C0); //Bujias 1-4 kargatu
output_high(PIN_C1); //Bujias 2-3 kargatu
}
output_low(PIN_C1); //Bujias 2-3 Deskargatu!!¡!¡!
delay_us(500);
}
else if((Gr<-18)&&(Gr>=-24)) //-24º
{
while(kont_dient!=54)
{
output_high(PIN_C0); //Bujias 1-4 kargatu
output_high(PIN_C1); //Bujias 2-3 kargatu
}
output_low(PIN_C0); //Bujias 1-4 Deskargatu!!¡!¡!
delay_us(500);
while(kont_dient!=25)
{
output_high(PIN_C0); //Bujias 1-4 kargatu
output_high(PIN_C1); //Bujias 2-3 kargatu
}
output_low(PIN_C1); //Bujias 2-3 Deskargatu!!¡!¡!
delay_us(500);
}
} //While(1)bukaera
} //main() bukaera
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*********************************************************************
**********************************************************************
AUTOAREN CPU OPEL 2000 16v
MOTOREAN PROBATZEKO BERTSIOA
**********************************************************************
LCD
**********************************************************************/
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <16F876.H>//16F876 PIC-a erabiliko dugu datuak jaso eta LCD-an pantailaratzeko
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4M)
#use RS232(baud=19200, xmit=PIN_C6, rcv=PIN_C7) //Portu seriea Pin C6 datuak jasotzeko
#include "LCD.c" //LCD-a erabiltzeko Programa gehigarria
char datuak[7];//Portu serietik jasotako datuak gordetzeko
int8 i;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/***********************************************************************
Funtzio Nagusia
************************************************************************/
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void main(void)
{
lcd_init(); //LCD Hasieratu
lcd_gotoxy(6,1); //Lehenengo lerroa,6.posizioa
printf(lcd_putc,"RPM");
lcd_gotoxy(4,2); //Bigarren lerroa, 5.posizioa
printf(lcd_putc,"ms");
lcd_gotoxy(12,2); //Bigarren lerroa, 11.posizioa
printf(lcd_putc,"Gradu");
while(1)
{
while(getc()!='Z'); //Itxaron datuak jasotzeko marka jaso arte
for(i=0;i<7;i++)
datuak[i]=getc(); //Portu serietik datuak jaso
for(i=0;i<7;i++)
write_eeprom(i,datuak[i]); //Eeprom memorian jasotako datuak gorde
//LCD RPM///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
lcd_gotoxy(1,1); //Lehenengo lerroa,1.posizioa
printf(lcd_putc,"%c",datuak[0]); //RPM; Milakoak
printf(lcd_putc,"%c",datuak[1]); //RPM; Ehunekoak
printf(lcd_putc,"00"); //RPM; Hamarrekoak eta Batekoak
//LCD ANGULO AVANCE///////////////////////////////////////////////////////////////////////////////////////////
lcd_gotoxy(8,2); //Bigarren lerroa,8.posizioa
printf(lcd_putc,"%c",datuak[2]); //Angulo Avance; Seinua +-
printf(lcd_putc,"%c",datuak[3]); //Angulo Avance; Hamarrekoa
printf(lcd_putc,"%c",datuak[4]); //Angulo Avance; Batekoa
//LCD TIEMPO INYECCION///////////////////////////////////////////////////////////////////////////////////////
lcd_gotoxy(1,2); //Bigarren lerroa, 1.posizioa
printf(lcd_putc,"%c",datuak[5]); //Inyekzioa; Hamarrekoa
printf(lcd_putc,"%c",datuak[6]); //Inyekzioa; Batekoa
}//while(1) bukara
}//main() bukaera
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*********************************************************************************************
VDO
Medidor masa de aire
**********************************************************************************************
output_high(PIN_c3);//1
output_low(PIN_c4);//0
delay_ms(5000);
output_low(PIN_c3);//0
output_low(PIN_c4);//0
delay_ms(5000);
output_low(PIN_c3);//0
output_high(PIN_c4);//1
delay_ms(5000);
output_high(PIN_c3);//1
output_high(PIN_c4);//1
***********************************************************************************************/
#include <16F876A.H>
#device ADC=10
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4M)
int16 a;
int1 b,c,d,e,f,g;
void main(void)
{
setup_adc_ports(AN0);
setup_adc(adc_clock_internal);
set_adc_channel(0);
while(1)
{
a=read_adc();
b=input(PIN_B1);//0%
c=input(PIN_B2);//punto muerto
d=input(PIN_B3);//25%
e=input(PIN_B4);//50%
f=input(PIN_B5);//75%
g=input(PIN_B6);//100%
if(b==0)
{
output_low(PIN_c4);//guztiz itxi
output_high(PIN_c3);
}
else if(c==0)
{
output_high(PIN_c4);//jetsi baina motorrak lagunduta
output_high(PIN_c3);//punto muerto
}
else if(d==0)
{
if(a>637)//50% 380
{
output_high(PIN_c4);//Ireki
output_low(PIN_c3);
}
else
{
output_high(PIN_c3);//jetsi baina motorrak lagunduta
output_high(PIN_c4);
}
}
else if(e==0)
{
if(a>515)//50% 380
{
output_high(PIN_c4);//Ireki
output_low(PIN_c3);
}
else
{
output_high(PIN_c3);//jetsi baina motorrak lagunduta
output_high(PIN_c4);
}
}
else if(f==0)
{
if(a>392)//50% 380
{
output_high(PIN_c4);//Ireki
output_low(PIN_c3);
}
else
{
output_high(PIN_c3);//jetsi baina motorrak lagunduta
output_high(PIN_c4);
}
}
else if(g==0)
{
if(a>392)//50% 380
{
output_high(PIN_c4);//Ireki
output_low(PIN_c3);
}
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
No hay comentarios:
Publicar un comentario