Evo primera neke jednostavne, ekstra brze, stejt masine na prostom 8 bit MCU. Iskomentarisao sam edukativno.
Možda nekom bude korisno...
Možda nekom bude korisno...
Code:
/*
Neki X primer ekstra brze stejt masine za pogon automatskog ili poluautomatskog rada neke jednostavnije
masine za brizganje plasticnih proizvoda. Ispisuje se samo brojac komada na displeju. I to u nekriticnom
trenutku.
Van ispisivanja brojaca stejt masina je ekstremno brza.
Na nekim mestima mora da se utrpa delay kada je nuzno potrebno da se uspori, jer se sve vrti sa desetinama
ili stotinama KHz sa obicnim 8-bit MCU na 40MHz takta.
Sva potrebna vremena, bilo WDT ili neki drugi tajmer, obavljaju se brojanjem nekog od interrupt tickera.
*/
void autom_rad(void)
{
if(op_status==autom){
lcd_clear();
lcd_puts("AUTOMATSKI RAD");
}
if(op_status==poluautom){
lcd_clear();
lcd_puts("POLUAUTOM. RAD");
}
///////////////////////////////PREDUSLOVI/////////////////////////////////////////
seq_no=0; seq_jump=0; //prekondicioniranje sekvence u koju se prvi put "uskace"
////////////////////////////WHILE AUTOMATSKI////////////////////////////////////////////////////
while((op_status==autom)||(op_status==poluautom)&&(!exit_autom)){ //uslovi koji drze neki mod rada
switch(seq_no){ //switch funkcija koja arbitrira sekvencama
case 0: //cekaj korpu, u ovoj sekvenci se nuzno ceka korpa. Potrebno da se uspori.
if(pauto_flag){ //uslov za poluautomatski rad u svakom ciklusu, za automatki samo prvi put.
while((!korpa)&&(!err_no)){ //testiranje prethodnog stanja sigurnosne korpe i potencijalne greske
if(esc_test())err_no=err_n_aus;//u slucaju da je sve-stop
}
while((korpa)&&(!err_no)){ //uredno zatvaranje sigurnosne korpe
if(esc_test())err_no=err_n_aus;
}
delay_ms(10); //namerno usporenje
seq_jump=1; seq_no=1;//skoci u prvu sekvencu i namesti uslov za jednokratni dogadjaj
}
else{ //automatski rad, obnavljanje ciklusa bez uslova korpe
seq_jump=1; seq_no=1;
}
break;
case 1: //zatvori alat
if(seq_jump){ //jednokratni dogadjaj
if(!izb_je_naz){ //kontrola pocetne pozicije
if(!al_je_otv){//kontrola pocetne pozicije
sysp=1; zatv_alat=1; izbijac=0;//aktiviranje potrebnih hidraulicnih ventila
}
else err_no=err_alat;//setovanje greske i njeno markiranje za info na displeju
}
else err_no=err_izbij; //setovanje greske i njeno markiranje za info na displeju
timer=100; timeout=0; // navijanje WDT i start isr tajmera
seq_jump=0; //ne ponovi
}
else{ //vrti se superbrzo ovde dok se ne steknu uslovi za neku drugu sekvencu ili err
if(korpa)err_no=err_korpa; //test sigurnosne korpe, abort
if(esc_test())err_no=err_n_aus; //test sigurnosne sve-stop "pecurke",abort
if(timeout)err_no=err_alat; //istekao WDT, dakle fizicka prepreka kretanju alata, abort
if(!al_je_zatv){ //uspesno zatvoren alat, idi dalje. Senzori sa invert. logikom
seq_jump=1; seq_no=3;
}
if(!osiguranje){ //prepreka na kraju hoda alata. Idi na akciju osiguraj
seq_jump=1; seq_no=2;
}
}
break;
case 2: //osiguraj
if(seq_jump){//jednokratno
sysp=1; zatv_alat=0; otv_alat=1;//potrebni ventili
timer=50; timeout=0; //navijanje WDT za otvaranje u slucaju osiguranja
seq_jump=0; //ne ponovi
}
else{ //vrti se superbrzo ovde dok se ne steknu uslovi za neku drugu sekvencu ili err
if(korpa)err_no=err_korpa;
if(esc_test())err_no=err_n_aus;
if(timeout)err_no=err_alat;//prepreka u otvaranju
if(!al_je_otv){ //ok, vrati se na pocetak da bi se pokiusalo opet
seq_jump=0; seq_no=0;
err_no=err_osigur; //info err
}
}
break;
case 3: //zabravi sa XX tona ako je sve uspesno proslo
if(seq_jump){
timer=5; timeout=0; //ostaju ventili iz seq 1, sada je ovo obican tajmer
seq_jump=0;
}
else{
if(korpa)err_no=err_korpa;
if(esc_test())err_no=err_n_aus;
if(timeout){ seq_jump=1; seq_no=4; } //istekao tajmer, idi dalje
}
break;
case 4: //primakni AGREGAT
if(seq_jump){
sysp=1; agr_napred=1;
timer=100; timeout=0;
seq_jump=0;
}
else{
if(korpa)err_no=err_korpa;
if(esc_test())err_no=err_n_aus;
if(timeout)err_no=err_agreg;
if(!agr_je_napr){
seq_jump=1; seq_no=5;
}
}
break;
case 5: //ekstrudiranje
if(seq_jump){
if(timer=params.holder.wparam[t_ekstr]>0){ //ukoliko je neko zadao vreme, inace ne.
sysp=0; doziraj=1;
timer=params.holder.wparam[t_ekstr]; timeout=0; //navij tajmer na zadato vreme
seq_jump=0;
}
else{ seq_jump=1; seq_no=6; } //ako nije zadato vreme skoci ovde
}
else{ //inace se brzo vrti ovde dok se ne steknu uslovi za dalje
if(korpa)err_no=err_korpa;
if(esc_test())err_no=err_n_aus;
if(timeout){seq_jump=1; seq_no=6; }
}
break;
case 6: //brizgaj
if(seq_jump){
doziraj=0; brizgaj=1; sysp=1;
timer=300; timeout=0;
seq_jump=0;
}
else{
if(korpa)err_no=err_korpa;
if(esc_test())err_no=err_n_aus;
if(timeout)err_no=err_brizg; //ovde WDT
if(!naknadni){ seq_jump=1; seq_no=7; }
}
break;
case 7: //naknadni
if(seq_jump){
naknadni=1;
timer=params.holder.wparam[t_nakn]; timeout=0;
seq_jump=0;
}
else{
if(korpa)err_no=err_korpa;
if(esc_test())err_no=err_n_aus;
if(timeout){ //ovde samo tajmer i tako dalje bla bla
seq_jump=1; seq_no=8;
}
}
break;
case 8: //doziraj
if(seq_jump){
sysp=0; brizgaj=0; naknadni=0; doziraj=1;
timer=600; timeout=0;int_temp=0;
seq_jump=0;
}
else{
if(korpa)err_no=err_korpa;
if(esc_test())err_no=err_n_aus;
if(timeout)err_no=err_dozir;
if(kraj_doziranja){
doziraj=0;
seq_jump=1; seq_no=9;
}
}
break;
case 9: //vakuum
if(seq_jump){
if(timer=params.holder.wparam[t_vak]>0){
sysp=1; vakuum=1;
timer=params.holder.wparam[t_vak]; timeout=0;
seq_jump=0;
}
else{ seq_jump=1; seq_no=10; }
}
else{
if(korpa)err_no=err_korpa;
if(esc_test())err_no=err_n_aus;
if(timeout){ seq_jump=1; seq_no=10; }
}
break;
case 10: //hladi
if(seq_jump){
sysp=0; vakuum=0; zatv_alat=0;
timer=params.holder.wparam[t_hladj]; timeout=0;
seq_jump=0;
}
else{
if(korpa)err_no=err_korpa;
if(esc_test())err_no=err_n_aus;
if(timeout){seq_jump=1; seq_no=11; }
}
break;
case 11: //otvori alat
if(seq_jump){
sysp=1;zatv_alat=0; otv_alat=1;
timer=200; timeout=0;
seq_jump=0;
}
else{
if(korpa)err_no=err_korpa;
if(esc_test())err_no=err_n_aus;
if(timeout)err_no=err_alat;
if(!al_je_otv){
sysp=0; otv_alat=0;
seq_jump=1; seq_no=12;
}
}
break;
case 12: //IZBIJ
if(seq_jump){
flag_endizb=0;
delay_ms(100); //uspori sve dok opadnu pritisci
mp_izbij(); //spoljna funkcija visestrukog rada izbijaca
seq_jump=0;
}
else{
if(flag_endizb){ //spoljna funkcija obavila posao
seq_jump=1; seq_no=13;
}
}
break;
case 13://pauziraj i izbroj kom
if(seq_jump){ //jednokratno
sysp=0;
brojac_vars.cuvar_br.brojac_l++;
if(brojac_vars.cuvar_br.brojac_l>9999){
brojac_vars.cuvar_br.brojac_l=0;
brojac_vars.cuvar_br.brojac_h++;n++;//brojac sa 9 cifara + brojac za potencijalne neplatise
}
disp_brojac(); //pljucni ga jednokratno na displej
if(op_status==autom){
timer=timer=params.holder.wparam[t_pauze]; timeout=0;//navij pauzu ako je automatski
pauto_flag=0; //daj dozvolu za samostalno obnavljanje celog ciklusa
}
else {pauto_flag=1; timer=5; timeout=0; }//stavi uslov korpe za poluautom. i neku malenu pauzicu
seq_jump=0; //ne ponovi
}
else{ //vrti se ovde dok ne isteknu mala ili velika pauza, potom idi na pocetak
if(korpa)err_no=err_korpa;
if(esc_test())err_no=err_n_aus;
if(timeout){ seq_jump=0; seq_no=0; }
}
break;
} //////////////////end switch autom/////////////////////////////
if(err_no){ //err test u svakom prolazu (dosta KHz je u pitanju kad je bitno).
exit_autom=1; //ponisti uslov za auto ili poluauto
memo_brojac(PISI); //memorisi broj komada u EEPROM
op_status=bazni; //namesti status masine u bazni
if(err_no==err_n_aus)iskljuci_izlaze(urgent);
else iskljuci_izlaze(normal);
}
} //end while autom. rada
////////////////////////////////////////END WHILE AUTOMATSKI///////////////////////////////////
//vrati se odakle si i dosao, kao Lesi :-)
}