logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Jak podłączyć czujnik do AT90S2313 i zliczać impulsy w Bascom?

Pfemek 28 Paź 2004 19:24 7611 20
  • #1 944383
    Pfemek
    Poziom 24  
    Posty: 1038
    Pomógł: 83
    Ocena: 339
    Witam. Chciałbym zrobić predkościomierz na AT90S2313. Jestem początkujący w mikrokontolerach. Mam czujnik generujący impulsy (5V), chyba 6 na metr ale dla mnie to teraz nie jest najbardziej istotne. Chodzi mi głownie o to do której nóżki podpiąć sygnał z impulsami(Prosił bym o jakiś schemat) i jak je zliczać przez licznik mikrokontrolera. Chciałbym pisać program w bascomie...
  • #2 944508
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    Można podpiąć do którejkolwiek, ustawionej na wejście, jednak najwygodniej będzie na T0 lub T1, które będa wyzwalały liczniki wbudowane w tym procesorze. Natomiast inny licznik co jakiś czas wyzwala przerwanie, którego procedura obsługi odczytuje ile już naliczył ten pierwszy licznik, przelicza wynik pomiaru na np. m/s, zeruje go i "pcha" to np. na wyświetlacz, albo do drukarki... ;)
  • #3 944535
    Pfemek
    Poziom 24  
    Posty: 1038
    Pomógł: 83
    Ocena: 339
    A mozna prosić program w bascomnie jak to by wygladalo mniej wiecej? :)
  • #4 944572
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    Pfemek napisał:
    A mozna prosić program w bascomnie jak to by wygladalo mniej wiecej? :)

    Nie mam programu w Bascomie bo akurat w asm siedzę :). Poczytaj troszke helpa od Bascoma, przejrzyj archiwum, google pod kątem "predkościomierz" "szybkościomierz", "speedometer", będziesz wiedział więcej niżbym był w stanie tobie wytłumaczyć... :)
    Tu jest nota katalogowa, jedna spośród wielu o AVR, trochę przykladowych programów (ale raczej nie w Bascom, chociaż, jak przemyśleć sprawę, to da się przerobić) na stronie Atmela. Zajrzeć na http://www.avrfreaks.net/ to też niezła myśl.
    Oczywiście, jak któryś z kolegów ma czas i chęci, to pewnie podeśle jakiś przykład w Bascom... ;)
  • #5 944611
    Pfemek
    Poziom 24  
    Posty: 1038
    Pomógł: 83
    Ocena: 339
    Ok, dzięki :) Napewno cos wykombinuje. Ale gdybyś mogł to moze w asemblerze byś cos takiego podsunął..? Kiedyś pisałem na 8051 w asemblerze to moze cos zrozumiem :)
  • #6 944720
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    A gdybyś tak nam napisał co chcesz mierzyć,prędkość czy przebytą drogę :?:
    A może jedno i drugie :?:

    Pzdr.
    Piotrek Sz.

    UPSSS Zagapiłem się :oops:
  • #7 944780
    Pfemek
    Poziom 24  
    Posty: 1038
    Pomógł: 83
    Ocena: 339
    Chce mierzyc predkość :) nie musze wyswietlać jej wartosci tylko zebym ja miał zmierzona i umieszczona w jakims rejestrze zebym mogł ja dalej w programie wykozystac :)
  • #8 945280
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    No to coś napisałem na AVRStudio 4.05.0.181 (na kolanie) :) . Co prawda na ATmega8, ale przeportowanie to pestka(niektóre wektory przerwań do skasowania/zmiany nazwy i "2313def.inc" zamiast "m8def.inc", prędkość kwarcu Xtal też do poprawki...), raczej tu chyba nie ma rozkazów niezaimplementowanych w AT90S2313.
    ;included in next file - line ".device m8def.inc (ATmega8)" prohibits using of non-implemented instructions
    .include "m8def.inc"
    .cseg
    .org	$00
    	rjmp RESET		;Reset Handle
    .org	INT0addr
    	reti		;rjmp EXT_INT0;EXT_INT0; External Interrupt0 Handle
    .org	INT1addr
    	rjmp EXT_INT1		;reti;EXT_INT1; External Interrupt1 Handle
    .org	OC2addr
    	reti		;rjmp  	; Output Compare2 Interrupt Vector Address
    .org	OVF2addr
    	reti		;rjmp 	; Overflow2 Interrupt Vector Address
    .org	ICP1addr	; Input Capture1 Interrupt Vector Address
    	reti		;rjmp TIM1_CAPT ;Input Capture1 Interrupt Vector Address
    .org	OC1Aaddr
    	reti		;rjmp TIM1_COMPA ;Output Compare1A Interrupt Vector Address
    .org	OC1Baddr
    	reti		;rjmp TIM1_COMPB ;Output Compare1B Interrupt Vector Address
    .org	OVF1addr
    	reti		;rjmp TIM1_OVR	;OverflowTimer1 Interrupt Vector Address
    .org	OVF0addr
    	rjmp TIM0_OVR	;reti		;OverflowTimer0 Interrupt Vector Address
    .org	SPIaddr
    	reti		;rjmp SPI_STC ;SPI Interrupt Vector Address
    .org	URXCaddr
    	reti	;rjmp UART_RXC	;USART Receive Complete Interrupt Vector Address
    .org	UDREaddr
    	reti	;rjmp UART_DRE	;USART Data Register Empty Interrupt Vector Address
    .org	UTXCaddr
    	reti	;rjmp UART_TXC	;USART Transmit Complete Interrupt Vector Address
    .org	ADCCaddr
    	reti		;rjmp 	; ADC Interrupt Vector Address
    .org	ERDYaddr
    	reti		;rjmp 	; EEPROM Interrupt Vector Address
    .org	ACIaddr
    	reti		;rjmp ANA_COMP ;Analog Comparator Interrupt Vector Address
    .org    TWIaddr
    	reti		;rjmp     ; Irq. vector address for Two-Wire Interface
    .org	SPMRaddr
    	reti		;rjmp  	; SPM complete Interrupt Vector Address
    
    .equ	Xtal=16000000 ;16 MHz => ~62,5e-9 s ~=62,5ns clock tick
    .def	MemoByteLo =r0	;Used for EEPROM & Program Flash Memory access and Lo byte for result of multiply
    .def	MemoByteHi =r1	; Hi byte for result of multiply
    .def	IntSaveMemoByteLo =r2	;
    .def	IntSaveSREGByte =r3	;
    .def	IntSaveTempA =	r4	;
    .def	IntSaveTempB = r5
    .def	IntSaveDataByte =r6	;
    .def	IntSaveXLByte = r7
    .def	IntSaveXHByte = r8
    .def	IntSaveZLByte = r9
    .def	IntSaveZHByte = r10
    .def	StoreZL = r11
    .def	StoreZH = r12
    .def	ZeroByte =	r13	; Usefull in routines, where every cycle have gold meaning...
    .def	IntMul =	r14	;
    .def	DummyByte=r15	;used in decrement and increment X, Y, Z by (ld DummyByte, (-)X/Y/Z(+)
    .def	DataByte =r16	;
    .def	TempA =	r17	;
    .def	TempB =	r18	;
    .def	CountBtL =r19	;
    .def	CountBtH =r20	;
    .def	TempCInt =	r21	;
    .def	TL =	r22	;
    .def	TH =	r23	;
    .def	AddWordL =r24	;
    .def	AddWordH =r25	;
    .equ	IFlag=7
    .equ	TFlag=6
    .equ	HFlag=5
    .equ	SFlag=4
    .equ	VFlag=3
    .equ	NFlag=2
    .equ	ZFlag=1
    .equ	CFlag=0
    ;r26-r31 -> X, Y, Z
    ; ********** MACROS **********
    .macro SaveOnEnterInt
    	in IntSaveSREGByte, SREG	;save SREG
    	mov	IntSaveMemoByteLo, MemoByteLo	;save MemoByteLo
    	mov IntSaveTempA, TempA		;save TempA
    	mov IntSaveTempB, TempB		;save TempB
    	mov IntSaveDataByte, DataByte	;save DataByte
    	mov	IntSaveXLByte, XL		;save X
    	mov	IntSaveXHByte, XH
    	mov	IntSaveZLByte, ZL		;save Z
    	mov	IntSaveZHByte, ZH
    .endmacro
    
    .macro RestoreOnEndInt
    	mov	ZL, IntSaveZLByte
    	mov	ZH, IntSaveZHByte		;restore Z
    	mov	XL, IntSaveXLByte
    	mov	XH, IntSaveXHByte		;restore X
    	mov DataByte, IntSaveDataByte	;restore DataByte
    	mov TempB, IntSaveTempB		;restore TempB
    	mov TempA, IntSaveTempA		;restore TempA
    	mov	MemoByteLo, IntSaveMemoByteLo	;restore MemoByteLo
    	out SREG, IntSaveSREGByte	;restore SREG
    .endmacro
    
    ;Interrupts procedures
    EXT_INT1:	; External Int1 reqest routine
    .equ IRQ1MeterTicks = 6 ; number of Interrupts on 1 meter
    .dseg
    MeasureTime:
    .byte	0x02
    .cseg
    	SaveOnEnterInt
    ; Save time counter as measure result (multiplication of milisecond)
    	lds DataByte, TimeCnt
    	sts MeasureTime, DataByte
    	lds DataByte, TimeCnt+1
    	sts MeasureTime+1, DataByte
    ; Clear time counter
    	sts TimeCnt, ZeroByte
    	sts TimeCnt+1, ZeroByte
    ; reset BOOL Variables
    	sts bTimeCntOverflov, ZeroByte
    EXT_INT1End:
    	RestoreOnEndInt
    	reti
    
    TIM0_OVR: ;Timer0 Overflows ($FF -> $00)
    .dseg
    TimeCnt:
    .byte	0x02	; 2-Byte Time Counter
    bTimeCntOverflov: ; if INT0 ticks too slow
    .byte	0x01
    .cseg
    	SaveOnEnterInt
     	;**************************************************
    	;Reload timer 0 now to preserve accuracy
    	;**************************************************
    	ldi	TempA,T0cnt	;Reload early, avoid the latency
    	out	TCNT0,TempA	;
    ;********************************************************
    	lds DataByte, bTimeCntOverflov
    	sbrc DataByte, 0x00 ; Skip next instruction if bit0 in DataByte is cleared
    	rjmp IncTimeCntEnd ; counter will be skiped, untill INT1 not ocure.
    IncTimeCnt0:
    	lds DataByte, TimeCnt
    	inc DataByte
    	sts TimeCnt, DataByte
    	breq IncTimeCnt1
    	rjmp IncTimeCntEnd
    ;- - - - - - - - - - - - -
    IncTimeCnt1:
    	lds DataByte, TimeCnt+1
    	inc DataByte
    	sts TimeCnt+1, DataByte
    	brne IncTimeCntEnd
    ;Counter overflows
    	ldi DataByte, 0x01
    	sts bTimeCntOverflov, DataByte
    ;- - - - - - - - - - - - -
    IncTimeCntEnd:
    	RestoreOnEndInt
    	reti
    
    RESET:   
    ;Proc InitStack()
    InitStack:
    ; It mustn't to be a subroutine, because must
    ; be stack point initialised before call it
    ; Inicialise Stack Point - push decrement it, pop increment
    	cli ; it's more safetly to disable interrupts durring initialisation
    	clr ZeroByte
    	ldi TempA, high(RAMEND)
    	out SPH, TempA
    	mov XH, TempA
    	ldi TempA, low(RAMEND)
    	out SPL, TempA
    	mov XL, TempA
    InitSRAMClr:
    	st  -X, ZeroByte
    	cpi XH, high(RAMSTART-1)
    	brne InitSRAMClr
    	cpi XL, low(RAMSTART-1)
    	brne InitSRAMClr
    InitTim0:
    ;Proc InitTim0()
    .equ Trise=0x07
    .equ Tfall=0x06
    .equ Tdiv1024=0x05
    .equ Tdiv256=0x04
    .equ Tdiv64=0x03
    .equ Tdiv8=0x02 
    .equ Tdiv1=0x01
    .equ Tstop=0x00
    .equ T0div=Tdiv256
    .equ Prescale0=1024*(T0div==Tdiv1024)+256*(T0div==Tdiv256)+64*(T0div==Tdiv64)+8*(T0div==Tdiv8)+(T0div==Tdiv1)
    .equ T0IntusPulse = 1000/IRQ1MeterTicks; 1000/IRQ1MeterTicks microseconds - 1/IRQ1MeterTicks ms Int0Ovrfl pulse
    .equ usDiv = 1000000; microsecond divisor
    .equ	T0dly = ((T0IntusPulse*Xtal)/(usDiv*Prescale0))	
    .equ T0cnt=(0xFF-T0dly)
    ;Set timer0 running (p.70)
    	ldi	TempA,T0div
    	out	TCCR0,TempA	;Set the prescaler
    	ldi	TempA,T0cnt	;Define the reload value
    	out	TCNT0,TempA	;Put that in T0
    	ldi TempA,1<<TOV0
    	out TIFR,TempA ; Clear TOV0/ clear pending interrupts
    	ldi TempA,1<<TOIE0
    	out TIMSK,TempA ; Enable Timer/Counter0 Overflow Interrupt
    ;Proc InitIRQ1()
    InitIRQ1:
    .equ IntPort=PORTD
    .equ IntDirPort=DDRD
    .equ IRQ1IN = PD3
    	cbi IntDirPort, IRQ1IN	; INT1 pin in
    	sbi IntPort, 	IRQ1IN	; INT1 pin pull up
    	in TempA, GIMSK
    	sbr TempA, 1<< IRQ1IN
    	out GIMSK, TempA
    	;INT1 sense source :
    	; ISC10 clr, ISC11 clr - low level
    	; ISC10 clr, ISC11 set - falling edge
    	; ISC10 set, ISC11 set - rising edge
    	;the rest is in the silence ;-)
    	; Falling edge of INT1 generates an interupt request
    	in TempA, MCUCR
    	cbr TempA, 1<<ISC10
    	sbr TempA, 1<<ISC11
    	out MCUCR, TempA
    	sei ; end of initialisation, interrupts can to run ;)
    	rjmp MainProc    ; --> Main.asm
    

    Wejście podłączamy do INT1, jak wolisz do INT0, to trzeba zaczepić się o inny wektor i co innego inicjalizować w RESET, zmienić i/lub zamienić niektóre definicje i stałe.
    Odwrotność dwubajtowej zmiennej MeasureTime jest prędkością w metrach na milisekundę ;) Mnożąc ją razy 1000 otrzymamy prędkość w m/s(1000/MeasureTime). Jeżeli czujnik za wolno się kręci to mamy tam 0(co przy dzieleniu wypada nieszczególnie, trzeba do tego dołożyć korektę, jaki i do przekroczenia prędkości maksymalnej{1km/s - chcemy szybciej - trzeba zwiększyc rozdzielczość licznika TimeCnt i timerek musi "tykać częściej"}...). Jeżeli chcemy pomiar mniejszych prędkości, to albo zwiększamy rozdzielczość licznika do np. 32 bitów, albo zmieniamy czujnik na taki o większej ilości impulsów na metr.
    Stała IRQ1MeterTicks definiuje tutaj ilość impulsów na metr(wpisałem tak jak kolega podał - 6 ;) ). Procedurę dzielącą dla obliczeń można znaleźć w podanych wcześniej linkach do przykładów (polega w sumie na wielokrotnym odejmowaniu, póżniej dla części ułamkowej resztę mnożymy razy 10 i znów dzielimy itd.). Z tego co mi się kojarzy, po pewnych modyfikacjach pewnie też da się to użyć jako wstawki $asm do Bascom lub w C(#pragma asm)...
    Nie wykluczam też istnienie pewnych niezamierzonych pomyłek, które wyjdą w "praniu"(nie testowałem)... :)
    Życzymy udanych pomiarów... ;)
    P.S.
    Jak widać zmieniłem (Ach te nocne nasiadówki :) ) koncepcję podaną wcześniej aby licznik liczył impulsy, które w procedurze przerwania czasowego byłyby mierzone, wynik wtedy byłby bezpośrednio prędkością, ale to też nietrudno zmodyfikować.
    Pozdrawiam, LightI
  • #9 945855
    Pfemek
    Poziom 24  
    Posty: 1038
    Pomógł: 83
    Ocena: 339
    Dzieki za ten program ale niestety za slaby jestem jeszcze zeby go od razu zrozumiec :( Wiem ze bascom to niezbyt dobry jezyk ale jest dla mnie w miare zrozumialy i dobrze by bylo jednak gdybym ten licznik w nim pisał. Potrzebuje zeby mi ktos prosciej wytlumaczyl na czym ten pomiar dokladnie ma polegac? Narazie zrozumialem ze na pomiarze liczby impulsow zliczonych przez jeden z licznikow po zatrzymaniu go przez impuls z zewnatrz??? :)
  • #10 946038
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    Chcesz zrozumieć - pytaj, czasem kilkakrotne przeczytanie w różnych porach dnia danego tekstu też pomaga. W asm czasem kilka instrukcji tworzy logiczną całość (jak domek z LEGO), gdy tymczasem w innym miejscu pełnia podwójną lub potrójną rolę. Kompilator języka "wyższego" tłumacząc swoje instrukcje na kod maszynowy, tworzy takie sekwencje równoważne - zależnie od potrzeby od jednej do nawet kilkuset - instrukcji asemblera, jednak nie spotkałem się do tej pory aby sprowadzał elementy wspólne sąsiednich instrukcji "do jednego mianownika", raczej duplikuje nawet identyczne sekwencje, co czesto ma wpływ również na mniejszą szybkość wykonania kodu ( i tu producentom pamięci i coraz szybszych procesorów jest w graj... :) ). Absolutnie nie jestem negatywnie nastawiony do Bascoma, w tym języku też można tworzyć dobre programy (podobnie jak buble, również w asm :) ), tak jest i w C, czy w jakimkolwiek innym "Higher Level Programing Language", w asm mamy tylko większą efektywność i elastyczność. Żeby to zajeło w asemblerze tyle samo, lub niewiele więcej czasu co w HLPL, trzeba nabrać dużej wprawy, no i mieć parę takich "sekwencji" na dysku (biblioteki procedur [często bywają na stronach producenta procesorka i w wielu innych miejscach Internetu], własne, wcześniej napisane procedury), aby tylko wystarczyło zmienić kilka linijek lub za pomocą polecenia edytora "Znajdź i zamień" zamienić nazwę zmiennej we wklejonym właśnie z innego pliku tekscie jakiejś procedurki.
    Pfemek napisał:
    Potrzebuje zeby mi ktos prosciej wytlumaczyl na czym ten pomiar dokladnie ma polegac? Narazie zrozumialem ze na pomiarze liczby impulsow zliczonych przez jeden z licznikow po zatrzymaniu go przez impuls z zewnatrz??? :)

    Licznik nie jest zatrzymywany, tylko zerowany i liczy dalej (następny pomiar za jakiś czas też musi nastapić... :) ), ale zanim to nastepuje, stan licznika jest zapisywany i stanowi wynik pomiaru (predkości) do następnego impulsu. Pierwsza opcja natomiast polegała na liczeniu impusów zewnętrznych i co jakiś wygodny czas (dlatego mowa o drugim liczniku - liczącym czas) i zachowywaniu jej jako wynik pomiaru. Ten licznik impulsów też jest zerowany, aby móc je liczyć od nowa. Może teraz wyłożyłem to jaśniej... ;)
  • #11 946138
    Pfemek
    Poziom 24  
    Posty: 1038
    Pomógł: 83
    Ocena: 339
    Czyli, licznik sobie zaczyna liczyć, po podaniu jednej "szpilki" z czujnika wartosc jest zapisana, nastepuje zerowanie licznika i licznik zaczyna zliczac od zera az do nastepnego impulsu wejsciowego??? Jesli tak to z tego wynika ze wartosc z licznika wraz ze wzrostem predkosci samochodu czyli czestotliwosci impulsow wejsciowych bedzie malec? Sorki jesli wychodzi na to ze troche ciezko kapuje ale chcialbym wszystko zrozumiec od podstaw. :)
  • #12 946162
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    LightHouser napisał:
    Odwrotność dwubajtowej zmiennej MeasureTime jest prędkością w metrach na milisekundę ;) Mnożąc ją razy 1000 otrzymamy prędkość w m/s(1000/MeasureTime).

    Dlatego napisałem pod moją procedurą w asm, że jest to odwrotność prędkości(1/prędkość), natomiast ta pierwsza opcja (liczenie drogi[impulsy] w stałym czasie), do której nie napisałem procedury, jej wynikiem bedzie prędkość.
    LightHouser napisał:
    Jak widać zmieniłem (Ach te nocne nasiadówki :) ) koncepcję podaną wcześniej aby licznik liczył impulsy, które w procedurze przerwania czasowego byłyby mierzone, wynik wtedy byłby bezpośrednio prędkością, ale to też nietrudno zmodyfikować.
  • #13 946182
    Pfemek
    Poziom 24  
    Posty: 1038
    Pomógł: 83
    Ocena: 339
    Juz rozumiem te dwa sposoby :) Teraz zostaje mi to przeniesc do bascoma, jak znowu czegos nie bede wiedzial to bede pytał, narazie wielkie dzieki... :)
  • #14 946981
    ljmp
    Poziom 14  
    Posty: 116
    Pomógł: 6
    Ocena: 9
    Moim zdaniem to powinno wyglądać tak: po pierwsze wzór na prędkość V=s/t - czyli prędkość=droga/czas. Musisz mieć "coś" co mierzy przebyty dystans i podaje impulsy do procesora. Musisz wiedziec jaki dystans jest przebyty co każdy impuls. Cała filozofia polega na tym żeby zmierzyć czas trwania od impulsu do impulsu. Znając ten czas trwania i drogę, która jest pokonywana w czasie od impulsu do impulsu podstawiamy do wzoru V=s/t i obliczamy prędkość.
  • #15 947051
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    ljmp napisał:
    Moim zdaniem to powinno wyglądać tak: po pierwsze wzór na prędkość V=s/t - czyli prędkość=droga/czas. Musisz mieć "coś" co mierzy przebyty dystans i podaje impulsy do procesora. Musisz wiedziec jaki dystans jest przebyty co każdy impuls. Cała filozofia polega na tym żeby zmierzyć czas trwania od impulsu do impulsu. Znając ten czas trwania i drogę, która jest pokonywana w czasie od impulsu do impulsu podstawiamy do wzoru V=s/t i obliczamy prędkość.

    Wszystko się zgadza, ale :
    Jeżeli mierzymy ilość drogi co stały czas, to czas we wzorze V=s/t można pominąć, zastępując go współczynnikiem, nazwijmy go k. Jeśli mierzymy np. co 1/100s to k = 100 no nie ? i teraz V=k*s Jeżeli impuls mamy tak jak Pfemek napisał co 1/6m to V=100/6*n, gdzie n-ilość impulsów w przeciągu tych 1/100s, czyli V=(16 i 2/3)*n[m/s]. Jeżeli mierzymy co 1/60s, to jest jeszcze prościej, V=10*n[m/s], przy tych 6 impulsach na metr. Jak chcemy km/h to najprościej sprawdzać licznik impulsów co 1/216(6^3)s (m/s=6^2*1/10*km/h, impuls co 1/6 m), V=10*n[km/h]. Obliczenia można sobie upraszczać, licząc to co można, jeszcze przed kompilacją, albo za pomocą definicji stałych... ;) W procesorkach AVR zwykle mnożenie idzie łatwiej niż dzielenie, ponieważ jest tu zaimplementowany rozkaz mul, a div nie ma, i w związku z tym procedura dzieląca musi być rozbudowana i zajmuje dużo pamięci i czasu procesora(wielokrotne odejmowanie dążące do 0 z liczeniem to inaczej dzielenie), wiec metoda wykorzystująca mnożenie jest bardziej efektywna.
    Pomiar jednostek czasu co impuls jest za to najlepszy, co do określania częstotliwości.
    Pozdr. LightI
  • #16 956519
    Pfemek
    Poziom 24  
    Posty: 1038
    Pomógł: 83
    Ocena: 339
    Umiem juz zliczac imulsy za pomoca timerow :) Mam jeszcze problem z tym ze TIMER0 ustawiony jako Counter reagujacy na narastajace zbocze zlicza cos (jakies impulsy) w momencie kiedy na wejsciu T0 jest wysoki stan, przy niskim stanie nie zlicza. Przeciez ma reagować na zbocze a nie na ciągły stan? Dlaczego tak jest? Problem filtracji zasilania a moze trzeba jakis uklad dopasowujacy na wejsciu??? :)
  • #18 960848
    Pfemek
    Poziom 24  
    Posty: 1038
    Pomógł: 83
    Ocena: 339
    Czujnik jest magnetyczny. Generuje impulsy standardowo 5V. Dzisiaj założe 74HC14 i zobacze czy coś pomoze... :)
  • #19 960855
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    Indukcyjny, czy halotron ? Z tymi impulsami to były obserwowane na oscyloskopie ? Gdyby czujnik byłby indukcyjny, to może jako buforek lepiej byłoby dać wzmacniacz operacyjny z dodatnim sprzeżeniem zewrotnym (histereza) i odpowiednim zabezpieczeniem wejścia (dioda Zenera) ? no chyba, że czujnik jest zasilany i ma już jakis układ wbudowany, warto wtedy spróbować sie tam dobrać, co najmniej w sensie jakiegoś schemaciku, czy parametrów wyjściowych...
  • #20 961370
    Pfemek
    Poziom 24  
    Posty: 1038
    Pomógł: 83
    Ocena: 339
    Czujnik jest halotronowy tyle ze juz z nim grzebalem bo za nim zrobilem uklad to zdazylem go spalić. Halotron, o ile to jest jakis halotron, wstawilem z wentylatorka z procesora i czujnik orzył, napiecie na jego wyjsciu mierzyłem tylko miernikiem, niestety nie mam oscyloskopu, gdybym miał nie miał bym pewnie problemu :) Wstawiłem ten 7414 i chyba jest ok. Tak wogóle to caly moj układ nie jest predkościomierzem tylko tempomatem do samochodu. Nie wyświetlam predkości bo nie musze tylko ja mierze i porównuje z wczesniej zmierzonym wzorcem. Nie mam jeszcze w samochodzie zamontowanego ukladu wykonawczego ale juz niedlugo bedzie i mam nadzieje ze moj tempomat bedzie działal. Jak narazie na takim domowym modelu działa :) ale jesli sa jeszcze jakies sposoby dopasowania sygnałow zewnetrznych to bardzo prosze o przykłady. :)

    Pozdrawiam...
  • #21 1135395
    MACIEK_M
    Poziom 29  
    Posty: 1179
    Pomógł: 111
    Ocena: 461
    Jeśli ma to być tempomat to prędkość pojazdu nie jest Ci do niczego potrzebna, skup się na prędkości obrotowej silnika i ją stabilizuj. Prędkość zależy od biegu( a tego nie możesz zmieniać automatycznie, tylko jest stały 1,2,3,4 lub 5 ) i prędkości obrotowej silnika, której wartość odpowiada określonej prędkości.
    Pozdrawiam Maciek_M

Podsumowanie tematu

✨ Dyskusja dotyczy podłączenia czujnika impulsów do mikrokontrolera AT90S2313 oraz zliczania impulsów w języku Bascom w celu realizacji prędkościomierza lub tempomatu samochodowego. Zalecane jest podłączenie sygnału impulsowego do wejścia licznika T0 lub T1, które wyzwalają wbudowane liczniki mikrokontrolera. Impulsy generowane przez czujnik (np. magnetyczny halotronowy, 5V, około 6 impulsów na metr) są zliczane przez timer ustawiony jako licznik reagujący na narastające zbocze sygnału. Pomiar prędkości opiera się na wzorze V = s/t, gdzie s to droga przypadająca na impuls, a t to czas między impulsami. Można mierzyć prędkość jako odwrotność czasu między impulsami lub liczyć impulsy w stałym czasie i przeliczać na prędkość. Wskazano, że w mikrokontrolerach AVR mnożenie jest prostsze niż dzielenie, co warto uwzględnić w obliczeniach. Do stabilizacji i poprawy jakości sygnału z czujnika zalecane jest zastosowanie układu buforującego, np. 74HC14. W przypadku tempomatu bardziej istotna jest prędkość obrotowa silnika niż prędkość pojazdu, ze względu na stałe przełożenia biegów. Przykładowy kod w asemblerze dla ATmega8 został udostępniony jako punkt wyjścia do przeniesienia na AT90S2313 i Bascom. Omówiono także podstawy działania liczników i przerwań w mikrokontrolerze oraz sposoby interpretacji sygnału impulsowego.
Podsumowanie wygenerowane przez AI na podstawie treści dyskusji.
REKLAMA