Sterownik wtrysku na atmega128 bascom


Witam

Proszę o wsparcie wiedzą i doświadczeniem przy programie na procesor atmega128.

Program ma sterować dodatkowym wtryskiem gazu w tym przypadku będzie to instalacja 5tej generacji LPG czyli fazy ciekłej.

Zasada działa nia jest bardzo prosta i wymaga:

Podłączenia sygnałów z 2 wtryskiwaczy (tyle wystarczy w 4 cylindrowym silniku) przez diody prostownicze i dzielniki napięcia do wejścia procesora.

Będzie to nasz TRIGER (to on będzie wyzwalał pętle programu )

Dodatkowo można dać if TRIGER >= by nie wzbudzał sie układ przypadkowo

potrzebujemy jeszcze informacji ciśnieniu w kolektorze dolotowym bo to silnik turbo wiec podamy na 2 wejście sygnał analogowy z mapsensora 0-5V

Nazwiemy te zmienną MAP

Ostatnią rzeczą potrzebna do dostrojenia układu dodatkowego wtryskiwacza jest zmienna X. Będzie to współczynnik ustawiany najlepiej potencjometrem za pomocą dzielnika napięcia na wejściu 3.

zmienna WYNIK to czas otwarcia dodatkowego wtrysku wyrażona w milisekundach podania napięcia na port Wyjściowy pod który będzie podłączony mosfet sterujący pracą dodatkowego wtrysku LPG

Pętla programu:

case MAP > 0,6 BAR ' gdy ciśnienie większe niż 0,6 bar

WYNIK= 5 * MAP*X ' gdzie 5 będzie nasza podstawą czasu 5 ms map będzie współczynnikiem zwiększającym czas wtrysku w zależności od ciśnienia, a nasze X da nam możliwość strojenia układu w aucie.

Zrobiłem juz prosty algorytm tego co potrzeba zrobić

link do algorytmu

i podzieliłem prace na 4 etapy:

1) wejścia adc dla map sensora ( zrobione Wink

2 wejście dla enkodera ( muszę zakupić jakiś impulsator i napisać parę linijek)

3 pomiar czasu pracy każdego z wtryskiwaczy. ( tu potrzebna jest pomoc) Zeby to było dobrze zrobione trzeba by to dać na jakiś przerwaniach i ustawić jakieś parametry wyeliminować zakłócenia. Np ustalić stan wysoki powyżej pewnego parametru. )

4 ) zebranie całego programu w całość i testowanie

Sterownik wtrysku na atmega128 bascom

Na razie mam to : czyli pomiar map sensora z wyświetlaniem średniej z 8 pomiarów oraz wkleiłem kawałek pożyczonego kodu od impulsatora.

$regfile = "m128def.dat"
$crystal = 16000000
$hwstack = 32
$swstack = 32
$framesize = 32
'-------------------------------------------------------------------------------
Dim Adc_data As Word
Dim S As Single
Dim Map As Long

Dim Text As String * 30

Dim I As Byte
'-------------------------------------------------------------------------------
Porta = &B00000000
Portc = &B00000000
Portd = &B11100000

Config Portf = &B1000000 ' wejscie map
Config Portc = &B1000000 ' wyjscie na wtryskiwacz
Config Portd = &B1110000 ' encoder, wejscia wtryskiwaczy

Config Adc = Single , Prescaler = Auto , Reference = Internal
Start Adc

Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Porta.4 , Db5 = Porta.5 , Db6 = Porta.6 , Db7 = Porta.7 , E = Porta.3 , Rs = Porta.2

'Zmienne impulsatora
Dim I1 As Bit
Dim I2 As Bit
Dim Le As Word

'Aliasy impulsatora 'pin 2 impulsatora podpięty pod mase (GND)
Pi1 Alias Pind.1 'pin 1 impulsatora
Pi2 Alias Pind.3 'pin 3 impulsatora
Sw Alias Pind.2 'swich impulsatora

' *** program główny ***

Le = 50 ' ustawia nam

' *** MAP sensor pomiar ***

Do
Map = 0
I = 0
For I = 0 To 8
Adc_data = Getadc(1)
Map = Map + Adc_data
Waitms 1
Next I

S = Map / 8
S = S * 0.7293532 'To trzeba dobrać by mieć 2.45V dla 0,7 bar
Map = Round(s)

' LCD wyswietlanie
Cursor Off
Cls
Text = Str(map)
Text = Format(text , " 0.0")
Locate 1 , 1
Lcd "MAP" ; Text ; " X" ; " " ; Le ; "%" ' Lcd ?wartosc : ? ; Licz 'wyswietlenie napisu i warto-sci zmiennej Licz

Lowerline
Lcd "tu bedzie czas"

' *** Podprogramy ***

Impulsator:
Do
If Pi1 = 0 And Pi2 = 0 Then
I1 = 0
I2 = 0
End If

If Pi1 = 1 And Pi2 = 1 Then
I1 = 1
I2 = 0
End If

If I2 = 0 Then
If Pi1 <> I1 Then
Waitms 2
If Pi1 <> I1 Then

Gosub Plus ' Incr Le
I2 = 1
End If
End If

If Pi2 <> I1 Then
Waitus 2
If Pi2 <> I1 Then

Gosub Minus ' Decr Le
I2 = 1
End If
End If
End If
Return

'podprogramy obrotu w lewo i prawo

Plus:
Incr Le 'Zwiększa zmienna "Le"
Return

Minus:
Decr Le 'Zmiejsza zmienną"Le"
Return

Loop

Loop
'-------------------------------------------------------------------------------




Portret użytkownika rxr2

teraz pasowało by dać jakieś

teraz pasowało by dać jakieś przerwanie na LCD żeby odświeżał co 100ms bo strasznie pulsuje..

ale nie bardzo jeszcze ogarniam przerwania..

może ktoś ma pomysł na przerwania i pomiar czasu sygnału dla wejść z 4 wtryskiwaczy.

Portret użytkownika Grzeniu 73

a wiec przerwania masz tu w

a wiec przerwania masz tu w projektach prawie w każdym programie.Druga sprawa nie daje sie CLS w pętli dlatego mruga.Cos mi sie wydaje ,ze będziesz musiał to wszystko jeszcze raz napisać.Do obliczania czasu otwarcia wtrysku musisz skonfigurować timer jako licznik który będzie sie włączał na stan wysoki i wyłączał jak będzie niski.Poczytaj w helpie i szukaj haslo komputery samochodowe.Tam zazwyczaj sa dyskusje o tym.Zeby to wszystko ogarnąć musisz sporo poczytać.To o co teraz prosisz to praktycznie caly kod.A w trzech linijkach nie da sie tego napisać.Na początek przenieś CLS i cursor off przed pętle i nie będzie mrugać.Przy wyświetlaniu puste miejsca nadpisuj spacjami.Nie będę tutaj wklejał przykładów bo naprawdę przejrzyj projekty i poczytaj opisy Mirleya.Będziesz mierzył krótkie okresy czasu i dlatego zapomnij o takim czymś jak wait.Do tego projektu musisz timery miec w jednym palcu.

Portret użytkownika rxr2

wiec nie ma co zabieram się

wiec nie ma co zabieram się do nauki...

kto by pomyślał, że po 12 latach wrócę do nauki programowania...

Portret użytkownika rxr2

dlaczego to nie liczy czasu :(

$regfile = "m128def.dat"
$crystal = 16000000
$hwstack = 32
$swstack = 32
$framesize = 32

Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Porta.4 , Db5 = Porta.5 , Db6 = Porta.6 , Db7 = Porta.7 , E = Porta.3 , Rs = Porta.2
Config Portc = Output
Config Porte = Input
Portd = &B11111111
Porte = &B11111111

Enable Interrupts
Config Timer0 = Timer , Prescale = 256
Enable Timer0

Config Int4 = Rising ' PE4 wejscie sygnału z wtryskiwacza zbocze rosnace
Enable Int4

On Timer0 Czas_1ms
On Int4 Pomiar1

Dim Czas As Integer
Dim T1 As Byte

Initlcd
Cls
Cursor Off

Do

Loop

End

Czas_1ms:

Timer0 = 193

Return

Pomiar1:
Disable Interrupts
Start Timer0
Incr Czas
If Pine.4 = 0 Then

Stop Timer0
End If

Czas = T1

Lcd "czas " ; T1 ; " "
Lowerline
Lcd " "

Enable Interrupts
Return

Portret użytkownika rxr2

a czy tak bedzie ok ?

$regfile = "m128def.dat"
$crystal = 16000000
$hwstack = 32
$swstack = 32
$framesize = 32

Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Porta.4 , Db5 = Porta.5 , Db6 = Porta.6 , Db7 = Porta.7 , E = Porta.3 , Rs = Porta.2
Config Portc = Output
Config Porte = Input
Portd = &B11111111
Porte = &B11111111

Enable Interrupts
Config Timer0 = Timer , Prescale = 256
Enable Timer0

Config Int4 = Change ' PE4 wejscie sygnału z wtryskiwacza zbocze rosnace
Enable Int4

On Timer0 1ms

On Int4 Pomiar1

Dim Czas As Integer

Dim Timer_val As Word

Initlcd
Cls
Cursor Off

Timer0 = 193
Do

Loop

End

1ms:

Incr Czas

Return

Pomiar1:

Timer_val = Czas

Lcd "czas " ; Timer_val ; " "
Lowerline
Lcd " "

Czas = 0

Return

Portret użytkownika gosc

jak policzyc ile razy wystopiło on time0 ?

$regfile = "m128def.dat"
$crystal = 16000000
$hwstack = 32
$swstack = 32
$framesize = 32

Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Porta.4 , Db5 = Porta.5 , Db6 = Porta.6 , Db7 = Porta.7 , E = Porta.3 , Rs = Porta.2
Config Portc = Output
Config Porte = Input
Portd = &B11111111
Porte = &B11111111

Enable Interrupts
Config Timer0 = Timer , Prescale = 1024
Enable Timer0

Config Int4 = Falling ' PE4 wejscie sygnału z wtryskiwacza zbocze rosnace
Enable Int4

Timer0 = 193

Start Timer0
On Timer0 1ms
On Int4 Pomiar1

Dim Czas As Word

Dim Timer_val As Word

Initlcd
Cls
Cursor Off

Do

Loop

End

'*****************przerwania programy***********************

1ms:

Incr Czas

Return

Pomiar1:

Czas = 0
Timer_val = 0

While Pine.4 = 0

' JAK POLICZYĆ PRZEPEŁNIENIA LICZNIKA TIMER0?

Wend

Lcd "czas " ; Timer_val ; " "
Lowerline
Lcd " "

Return

Portret użytkownika Grzeniu 73

ściągnij sobie program

ściągnij sobie program "pomocnik AVR" i zapomnisz o takich problemach:)Wpisujesz tam jaki timer i taktowanie a wynik sie wyświetli w okienku.Proste i bezbolesne.W tym konkretnym przypadku masz 4,0320ms.Zeby miec 1ms musisz ustawic prescale =64 i załadować do Timera0=6. Będziesz mial idealnie 1ms

Portret użytkownika rxr2

udało sie :) pomiar czasu ogarniety ... teraz tylko poskładać..

$regfile = "m128def.dat"
$crystal = 16000000
$hwstack = 32
$swstack = 32
$framesize = 32

Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Porta.4 , Db5 = Porta.5 , Db6 = Porta.6 , Db7 = Porta.7 , E = Porta.3 , Rs = Porta.2
Config Portc = Output
Config Portd = Input
Config Porte = Input
Portd = &B11111111
Porte = &B11111111

Enable Interrupts
Config Timer0 = Timer , Prescale = 1024
Enable Timer0

Config Int4 = Change
Enable Int4
Config Int5 = Change
Enable Int5
Config Int6 = Change
Enable Int6
Config Int7 = Change
Enable Int7

Led1 Alias Portc.1
Led2 Alias Portc.2
Led3 Alias Portc.3
Led4 Alias Portc.4

Sw1 Alias Pind.4
Sw2 Alias Pind.5
Sw3 Alias Pind.6
Sw4 Alias Pind.7

Timer0 = 240
Start Timer0

On Timer0 1ms
On Int4 Int_start1
On Int5 Int_start2
On Int6 Int_start3
On Int7 Int_start4

Dim Start1 As Byte
Dim Start2 As Byte
Dim Start3 As Byte
Dim Start4 As Byte
Dim Czas_start1 As Word
Dim Czas_start2 As Word
Dim Czas_start3 As Word
Dim Czas_start4 As Word
Dim Czas_led As Word

Czas_led = 0

Initlcd

Cursor Off

Do
Cls

Lcd "czas " ; Czas_start1
Lowerline
Lcd ""

Waitms 100

Loop

End

'*****************przerwania programy***********************

1ms:

If Start1 = 1 Then ' program wywoływany przepełnieniem sie timer0 ustawionym na 1ms
Incr Czas_start1 ' uruchamia liczniki gdy spełnione sa warunki w programie dla przerwań int4-7
End If

Incr Czas_led
If Czas_led > 100 Then

Czas_led = 0

Toggle Led1
End If

Return

Int_start1: ' program przerwanie dla wtrysku 1 uruchamiany zmianą zbocza int4 na pinE.4
' gdy pojawia sie stan 0 włacza zliczanie w progamie 1ms przez zmienna star1
If Pine.4 = 0 Then
Start1 = 1 ' dodatkowo włacza led w ramach sygnalizacji ;)
Czas_start1 = 0
Led2 = 1

End If

If Pine.4 = 1 Then
Start1 = 0
Led2 = 0
End If

Return

Int_start2:
Return
Int_start3:
Return
Int_start4:
Return

Portret użytkownika Grzeniu 73

napisałem Ci wcześniej jak

napisałem Ci wcześniej jak musi być timer0 ustawiony aby mies 1ms.Teraz masz 1,0240.I te Twoje obliczenie psu w budę ida.Pozbądź sie tez tego waitms zrób to również na timerze.I usuń to CLS z pętli,juz Ci o tym pisałem.No ,ale dobrze Ci idzie ta nauka jeszcze parę dni i skończysz.