witam
prosze kogos o pomoc. mam napisane dwa programy pierwszy "obliczenia" drugi "wyswietlanie".
W czym mam problem: program "obliczenia" ma pobierac dwie sasiednie probki sygnalu (z przetwornika a/c) a nastepnie dzielic je przez czas miedzy tymi probkami i wysylac je do drugiego procesora ktory wyswietli te obliczenia plus liczbe zliczonych impulsow, czas miedzy kazda para probek jest zawsze ten sam ale wyniki z poszczegolnych obilczen sie roznia (przy tej samej czestotliwosci sygnalu podawanego na we przetwornika a/c i przy tym samym nachyleniu zbocza sygnalu). sygna ktory jest poddawany na wejscie przetornika to pilka, amplitud tego sygnalu wynosi 10V czyli zmienia sie od 0 do 10V, czas trwania jednego zabka 20ms.
prosze mnie poprawic jeslisie sie myle ale jezeli sa pobierane dwie sasiednie probki w tym samym czasie to roznica tych probek powinna byc stala ale tak nie jest i to wlasnie jest moj problem. w programie jest warunek ktory zapobiega pobraniu jednej probki z jednego zbocza i drugiej z drugiego tzn wystepuje taka sytuacja ale jezeli to jest wykryte to procesor nie dokonuje obliczen tylko pobiera kolejna pare probek: probka2-probka1>=0 (wieksza badz rowna bo jezeli jest podawany staly sygnal to wynik musi byc zero np jezeli podawane jes stala wartosc nam np 5V)- tak ten warunek wyglada. byc moze zle konfiguruje timer moze tu jest blad prosze zeby ktos przeanalizowal te programy i wskazal mi moje bledy. ja tak obliczam zawartosc licznika ktora mam wpiac do niego: zastosowany kwarc to 24Mhz wiec 24/12=2000000 impulsow procesor moze zliczyc na sekunde. chcialbym aby probki byly pobierane co 5ms tzn czas miedzy pierwsza a druga probka byl tyle rowny wiec dalej tak to obliczam 1s=1000ms a 5ms to jest 1/200 sekundy wiec dalej 2000000/200=10000 a nastepnie 65536-10000=55536 i tyle wpisuje do timera. moze tu robie blad i czas jest inny niz chcialem osiagnac. tylko nie dodalem czasu trwania instrukcji potrzebnych na zaladowanie timera i prosil bym o rade jak to dokladnie okreslic. czas od pary do pary probek moze byc rowniez rowny 5ms ale nie koniecznie bo zeby procesor wyrobil sie z obliczeniami i wyslaniem danych. naj wazniejze aby czas miedzy probka 1 a 2 byl jednakowy.
wiec wynik=(probka2-probka1)/0.005 to powininienem otrzymac. mialem rowniez problem z konfiguracja uart wiec wykorzystalem transmisje za pomoca shiftout shiftin w tej transmisji nie moge przesylac zmiennoprzecinkowych wiec musze dokonywac pseldokonwersji na zmienna long wiec trace troche danych, przetwornik jest 8bitowy wynikiem liczba 2bajtowa bo wynikiem moze byc nawet 3000, wynik musze rowniez wysylac na konwerter z i2c n 8bitow rownolegle wiec musze jakos wynik skalowac (choc konwerter to mozna zastosowac i 16 bitowy wiec to nie byl by problem ale przetwornik jest 8bitowy pcf8591) jak nie tracic danych podczas transmisji z jednego do drugirgo kontrolera i podczas wysylania na przetwornik c/a ktory jet 8bitowy no tu to moze byc nie mozliwe. jezeli ktos zna jakis uklad przetwornika a/c i c/a 16bitowego to prosze o pomoc najlepiej zeby tez byly oba w jednej obudowie no i komunikacja za pomoca magistarli I2C.
"OBICZENIA"
Config Lcd = 16 * 2
Config Timer0 = Timer , Mode = 1 , Gate = Internal 'konfiguracja TIMERA1
On Timer0 Odczyt 'wywloanie procedury obslugi przerwania od T0
Counter0 = 55536 'wpisanie do TIMERA1 wartości 45537 dziesietnie
Enable Interrupts 'zezwolenie globalne na przerwania
Enable Timer0 'zezwolenie na przerwanie od T1
Dim Dana As Byte
Dim Ulamek As Byte
Dim Wyslij As Byte
Dim Wynik As Byte
Dim I As Byte
Dim J As Byte
Dim Odczyt(2) As Byte 'deklaracja tablicy dwuelementowej typu bajtowego
Dim Wynik1 As Single
Dim Tab(5) As Long
Dim Wynik2 As Long
Dim Z As Byte
I = 0
J = 0
Start Timer0 'uruchomienie zliczania przez T0
Do 'poczatek petli programu glównego
Loop 'koniec pętli programu glównego
Odczyt: 'procedura odczytu z przetworika A/C
Counter0 = 55536
Start Timer0
Incr I 'inkrementowanie zmiennnej 'I'
I2cstart 'inicjalizacja magistrali I2C
I2cwbyte 144 'wyslanie adresu zapisu przetwornika A/C
I2cwbyte 64 'wyslanie bajtu konfiguracyjnego do przetwornika A/C
I2cstart 'ponowna inicjalizacja magistrali I2C
I2cwbyte 145 'wyslanie adresu odczytu przetwornika A/C
I2crbyte Dana , Nack 'odczyt wartości z przetwornika A/C bez potwierdzenia odbioru (NACK)
I2cstop 'koniec transmisji magistralą I2C
Odczyt(i) = Dana 'zapis odczytanej wartości do tablicy odczyt(2)'
If I = 2 Then
Wynik = Odczyt(2) - Odczyt(1) 'różnica wartosci "poprzedniej" i "obecnej"
If Wynik >= 0 Then
Wynik1 = Wynik / 0.005
gosub wyslij
I = 0
End If
End If
Return
Wyslij:
Wyslij = Wynik2 'pseldokonwersja do long
Reset P3.2 'uzywany do wywolania przerwania z INT0 w drugim procesorze
Shiftout P3.7 , P3.4 , Wynik2 , 1 'transmisja do drugiego kontrolera
Set P3.2
I2cstart
I2cwbyte 144
I2cwbyte 64 transmisja do przetwornika C/A
I2cwbyte Wyslij
I2cstop
I2csend 64 , Wyslij 'wyslanie obliczonej wartości do konwerera PCF8574
Return
"WYSWIETLANIE"
$crystal = 24000000
Config Timer1 = Counter , Mode = 1 , Gate = Internal
Enable Interrupts
Enable Timer1
Config Lcd = 16 * 2
Dim Inkr As Word
Dim Th As Byte
Dim Tl As Byte
Dim Konter1 As Long
Dim T1_wynik As Long
Dim Pcf8591 As Long
On Int0 Odczyt 'wywolanie procedury obslugi przerwania od int0
On Timer1 Ink 'wywolanie procedury obslugi przerwania od timer1
Cls
Cursor Off
Cls : Locate 1 , 2 : Lcd "PLEAES WAIT..."
Lowerline
Locate 2 , 3
Lcd "PREPARATION"
Wait 1
Enable Int0 'zezwolenie na przerwanie zewnetrzne INT0
Start Timer1 'zezwolenie na przerwanie od TIMERA1
Do : Loop
Odczyt: 'procedura odbioru danych z pierwszego kontrolera
Shiftin P3.7 , P3.4 , Pcf8591 , 4 '"odbieranie" danych
Gosub Wyswietl 'skok do podprogramu "wyswietl"
Return
Ink: 'procedura obslugi przerwania 'timer1'
Incr Inkr
Return
Wyswietl:
$asm
mov {tl}, tl1 'przenies zawartosc mlodszej czesci rejestru timer1 do zmienej 'tl'
mov {konter1},th1 'przenies zawartosc starzszej czesci rejestru timer1 do zmienej 'konter1'
$end Asm
Shift Konter1 , Left , 8 'przesun zawrtosc 'konter1' binarni o 8 w lewoe
Konter1 = Konter1 + Tl 'do zmienej 'konter' dodaj zawartosc zmienej 'tl'
T1_wynik = Inkr * 65536 'obliczenie wywolan przerwania od licznika T1
T1_wynik = T1_wynik + Konter1 'zsumowanie liczby wystapien przerwan z zawartoscia licznika
Cls
Lcd T1_wynik ;" obr"
Lowerline
Lcd Pcf8591 ; " rad/s"
Konter1 = 0
Return
Prosze o pomoc bardzo pilne!!!
Aby odstepy czasowe były jednokowe licznik musi pracować w trybie autoprzeładowania
[ Dodano: 24-04-2006, 00:09 ]
I licznik wystatowany liczy cały czas bez powtażania Start timer
[ Dodano: 24-04-2006, 01:02 ]
Ten pcf8.. zaczyna konwersje w momencie rozpoczecia odczytu więc w obsłudze przerwania od licznika musisz zaczynać odczyt
[ Dodano: 24-04-2006, 01:05 ]
Konfiguracje pcf8.. wykonujesz tylko raz i to wystarczy
[ Dodano: 24-04-2006, 00:09 ]
I licznik wystatowany liczy cały czas bez powtażania Start timer
[ Dodano: 24-04-2006, 01:02 ]
Ten pcf8.. zaczyna konwersje w momencie rozpoczecia odczytu więc w obsłudze przerwania od licznika musisz zaczynać odczyt
[ Dodano: 24-04-2006, 01:05 ]
Konfiguracje pcf8.. wykonujesz tylko raz i to wystarczy
Tak jest w asem start i kręci do stop Nie znam twojgo języka ale start u Ciebie może powodować wpisanie wertości początkowej do licznika w bliżej nie określomym momencie.
I ustaw koniecznie tryb pracy z autoprzeładowaniem ,generuje przerwanie (robisz odczyt w obsłudze a przetwornik robi konwersje )i ne gubi zliczania.
Inną sprawą jest czs konwersji i co jak w trakcie konwersji zbocze zamiast narastać linowo nagle opadnie ( układ pamiętający na wejściu sygnału lub przetwornik flash) walcz dalej!!!
I ustaw koniecznie tryb pracy z autoprzeładowaniem ,generuje przerwanie (robisz odczyt w obsłudze a przetwornik robi konwersje )i ne gubi zliczania.
Inną sprawą jest czs konwersji i co jak w trakcie konwersji zbocze zamiast narastać linowo nagle opadnie ( układ pamiętający na wejściu sygnału lub przetwornik flash) walcz dalej!!!
- Tranzystor
- Użytkownik
- Posty: 889
- Rejestracja: 28 sie 2005, 19:19
- Lokalizacja: Świętochłowice
- Kontakt:
Ja mam pytanie do czego Ci to potrzebne i co to ma dokładnie robić może da się na jakiś innych podzespołach zrobić. Wiesz z programowaniem jest kłopot, ponieważ wystarczy jeden błąd w programie i nic nie działa. Sprawdź jeszcze raz od początku powoli ten program, a potem pomyśl czy cały program ma jakiś sens, czyli czy zrobiłeś prawidłowe obliczenia. Jest też taki problem, że rezonatory kwarcowe nie są aż tak stabilne więc wynik może się o troche różnić od poprzedniego, ale może też to zależeć od przetwornika z jaką prędkością zareaguje na twoje wysłane do niego polecenie. Ty potrzebujesz bardzo stabilny rezonator i przetwornik z średnią szybkością, żeby reagował prawie tak samo. Jeżeli u Ciebie wynik różni się o 0,1 Volta to to nie jest dużo. Gożej jeżeli wynik poprzedni był 9V, a przy drugim pomiarze też powinno być 9V, a wyszło 5V. To wtedy masz mały problem. Jeżeli masz taki problem to wtedy możesz zastosować inny mikroprocesor z wbudowanym przetwornikiem A/C będzie stabilniejszy, np.: ATMEGA8 z rezonatorem 16MHz. Nie wiem czy wiesz jak się programuje w BASCOM AVR, ale podobnie jak w BASCOM '51. Nie wiem ile kosztował twój przetwornik z procesorem, ale ATMEGA8 kosztuje ok. 8zł. Jedna uwaga nie daj się wpuścić w maliny gdy kupujesz mikroprocesory AVR, bo są zwykłe ATMEGA8, który może mieć maks. rezonator kwarcowy 16MHz, ale też są ATMEGA8L on ma wtedy maks. rezonator 8MHz.
Powodzenia
Powodzenia