Przetwornik DAC do zasilacza
- Michał6201
- Posty: 127
- Rejestracja: 03 paź 2015, 20:07
Przetwornik DAC do zasilacza
Witam
Pomiar napięcia i natężenia (dwa przetworniki ADC ADS1110) w moim zasilaczu ogarnąłem dzięki pomocy Bartka, wszystko działa tak jak chciałem.
Ogólnie cały zasilacz już działa.
Teraz regulacja napięcia i prądu odbywa się w tym zasilaczu za pomocą 2 potencjometrów wieloobrotowych.
I tak sobie pomyślałem, że mógłbym spróbować zrobić regulację za pomocą dwóch enkoderów i przetwornika cyfrowo analogowego.
Wstępnie znalazłem dwa przetworniki DAC:
jeden 12 bitowy MCP4822 (dwa kanały, bo tyle potrzeba), komunikacja przez SPI
https://ww1.microchip.com/downloads/en/ ... 02249B.pdf
drugi 16 bitowy AD5667 (dwa kanały) komunikacja przez I2C
https://www.analog.com/media/en/technic ... 7_5667.pdf
I teraz mam pytanie który będzie lepszy? Jeśli użyję tego z komunikacją po I2C, to czy procek wyrobi się obsługą tego wszystkiego na raz?
Da się to jakoś w miarę prosto ogarnąć programowo w bascomie?
I drugie pytanie pojawiło mi się - czy takie napięcie na wyjściu tego DAC muszę mierzyć dodatkowo cały czas osobnym przetwornikiem adc, a czy to programowo wędzie widoczna cały czas ta wartość (U_SET)?
Pomiar napięcia i natężenia (dwa przetworniki ADC ADS1110) w moim zasilaczu ogarnąłem dzięki pomocy Bartka, wszystko działa tak jak chciałem.
Ogólnie cały zasilacz już działa.
Teraz regulacja napięcia i prądu odbywa się w tym zasilaczu za pomocą 2 potencjometrów wieloobrotowych.
I tak sobie pomyślałem, że mógłbym spróbować zrobić regulację za pomocą dwóch enkoderów i przetwornika cyfrowo analogowego.
Wstępnie znalazłem dwa przetworniki DAC:
jeden 12 bitowy MCP4822 (dwa kanały, bo tyle potrzeba), komunikacja przez SPI
https://ww1.microchip.com/downloads/en/ ... 02249B.pdf
drugi 16 bitowy AD5667 (dwa kanały) komunikacja przez I2C
https://www.analog.com/media/en/technic ... 7_5667.pdf
I teraz mam pytanie który będzie lepszy? Jeśli użyję tego z komunikacją po I2C, to czy procek wyrobi się obsługą tego wszystkiego na raz?
Da się to jakoś w miarę prosto ogarnąć programowo w bascomie?
I drugie pytanie pojawiło mi się - czy takie napięcie na wyjściu tego DAC muszę mierzyć dodatkowo cały czas osobnym przetwornikiem adc, a czy to programowo wędzie widoczna cały czas ta wartość (U_SET)?
- niveasoft
- Posty: 1239
- Rejestracja: 17 sie 2015, 12:13
- Kontakt:
Re: Przetwornik DAC do zasilacza
Chyba bym tych wszystkich interfejsów nie mieszał bo szkoda pinów uC/ścieżek. Skoro masz I2C a została stworzona by adresować wiele układów w jednym urządzeniu to weź I2C.
Osobiście tego Twojego nie znam, ale to chyba nie problem. W swoim urządzeniu wykorzystuję pojedynczy 12bit MCP4726.
Taki DAC ma od 0 do 5V na wyjściu (albo max tyle czym go zasilisz) Nie trzeba tego mierzyć. Bierzesz 5V i dzielisz przez 4096. Wychodzi 0,001220703125 na krok.
Teraz chcesz mieć 2V na wyjściu. Jak 2 podzielisz przez 0,001220703125 to wyjdzie chyba 1638,4. Chyba, że może jeszcze śpię po wczorajszej nocce przy kompie
Wbijasz te 1638 i powinno być 2V.
To Ciebie może jednak nie urządzać tak jak mnie bo potrzebowałem 0V-20V. Dlatego za DAC wsadziłem OP-AMP. Stary, poczciwy, LM358 z przekładnią 1/4.
Z 2V na DAC zrobi 8V a z 5V powinno wyjść 20V. Sprzężenie z ADC i powinno grać.
Osobiście tego Twojego nie znam, ale to chyba nie problem. W swoim urządzeniu wykorzystuję pojedynczy 12bit MCP4726.
Taki DAC ma od 0 do 5V na wyjściu (albo max tyle czym go zasilisz) Nie trzeba tego mierzyć. Bierzesz 5V i dzielisz przez 4096. Wychodzi 0,001220703125 na krok.
Teraz chcesz mieć 2V na wyjściu. Jak 2 podzielisz przez 0,001220703125 to wyjdzie chyba 1638,4. Chyba, że może jeszcze śpię po wczorajszej nocce przy kompie
Wbijasz te 1638 i powinno być 2V.
To Ciebie może jednak nie urządzać tak jak mnie bo potrzebowałem 0V-20V. Dlatego za DAC wsadziłem OP-AMP. Stary, poczciwy, LM358 z przekładnią 1/4.
Z 2V na DAC zrobi 8V a z 5V powinno wyjść 20V. Sprzężenie z ADC i powinno grać.
- Michał6201
- Posty: 127
- Rejestracja: 03 paź 2015, 20:07
Re: Przetwornik DAC do zasilacza
Wybrałem przetwornik DAC AD5667R
U mnie wygląda to tak:
Regulacja napięcia wyjściowego, to: 0 - 5V, co mi daje na wyjściu zasilacza napięcie: 0 - 20V
Regulacja ograniczenia prądowego, to 0 - 150mV, co mi daje na wyjściu zasilacza 0 - 3A
Przetwornik AD5667R daje na wyjściu 0 - 5V przy napięciu referencyjnym wewnętrznym 2,5V
Więc pasuje to idealnie do sterowania napięciem wyjściowym, jak i ograniczeniem prądowym
Znalazłem w necie program do obsługi tego przetwornika DAC AD5667:
Do sterowania tym przetwornikiem potrzebujemy kodu 0 - 65536, (co odpowiada napięciu wyjściowemu 0 - 5V)
Czyli do DAC trzeba wysyłać wartość 0 - 65536.
A wartość ustawiona x 4 da nam wartość napięcia wyjściowego i tym samym wartość wyświetloną na LCD.
Przeszukując Twoją stronę Bartku, znalazłem kod do obsługi enkodera, (ten z kondensatorami 22n pomiędzy A i B a GND), który na lcd daje właśnie kod 0 - 65536.
Załadowałem go do mojego procka i działa pięknie, tylko jak zrobić wybór napięcia na wyświetlaczy lcd, np.: 12,445V?
Wiem już, jak przekształcić wartość wyświetlana na wyświetlaczu na kod 0 - 65536, który trzeba wysłać do DAC.
Zmienną Ib = od 0 do 65536 wysyłamy do DAC.
Bo używając samego kodu z enkodera musiałbym przekręcić od 0 do 65536 impulsów żeby dojść od zera do 20V. To bez sensu byłoby i zajęłoby z 10 minut.
Pomyślałem, że możnaby to zrobić w ten sposób, że wybieram switchem enkodera po kolei poszczególne pozycje wartości napięcia, np.: 5,555V, to najpierw ustawiam wartość tysięcznych volta, potem setnych volta, dziesiętne i jedności, po czym kolejne kliknięcie switch enkodera ładuje to napięcie za pomocą kodu 0 -65536 do przetwornika DAC.
Myślę, że to byłoby najlepsze rozwiązanie. Ale nie wiem jak utworzyć taką wartość na lcd, by móc po kolei zmieniać poszczególne wartości 0 - 9.
U mnie wygląda to tak:
Regulacja napięcia wyjściowego, to: 0 - 5V, co mi daje na wyjściu zasilacza napięcie: 0 - 20V
Regulacja ograniczenia prądowego, to 0 - 150mV, co mi daje na wyjściu zasilacza 0 - 3A
Przetwornik AD5667R daje na wyjściu 0 - 5V przy napięciu referencyjnym wewnętrznym 2,5V
Więc pasuje to idealnie do sterowania napięciem wyjściowym, jak i ograniczeniem prądowym
Znalazłem w necie program do obsługi tego przetwornika DAC AD5667:
Code: [Zaznacz cały] [Rozwiń/Zwiń]
- ' Obsługa przetwornika cyfrowo analogowego AD5667R
- ' Wersja testowa
- $regfile = "m32def.dat"
- $crystal = 11059200
- ' Konfiguracja LCD 2X16
- Config Lcdpin = Pin , E = PortA.3 , Rs = PortA.2 , Db7 = PortA.7 , Db6 = PortA.6 , Db5 = PortA.5 , Db4 = PortA.4
- Config Lcd = 16x2
- Cursor Off
- Cls
- ' Konfiguracja I2C
- $lib "i2c_twi.lbx"
- Config Scl = Portc.0
- Config Sda = Portc.1
- I2cinit
- Config Twi = 100000
- '-------------------------------------------------------------------------------
- '-------------------------------------------------------------------------------
- ' 2 Channel AD5667R 16 Bit I2c DAC
- '-------------------------------------------------------------------------------
- ' 2-kanałowy przetwornik cyfrowo-analogowy AD5667 16-bitowy I2c z wbudowanym precyzyjnym napięciem odniesienia
- ' do sterowania zasilaczem z analogowymi portami zdalnego sterowania 0-5 V
- ' Opis interfejsu I2C
- ' AD5667R wymaga dwóch bajtów danych dla DAC i bajtu polecenia, który kontroluje różne funkcje DAC.
- ' Dlatego w przetworniku cyfrowo-analogowym muszą zostać zapisane trzy bajty danych,
- ' bajt polecenia, po którym następuje najbardziej znaczący bajt danych i najmniej znaczący bajt danych.
- ' Opis Bajtu
- '
- ' 1 [Command Data Byte ]
- ' 2 [Most Significant Data Byte ]
- ' 3 [Least Significant Data Byte]
- ' [ Command Data Byte ] [ Most Significant Data Byte ] [ Least Significant Data Byte ]
- ' [R S C2 C1 C0 A2 A1 A0] [D7 D6 D5 D4 D3 D2 D1 D0] [D7 D6 D5 D4 D3 D2 D1 D0]
- ' Inicjalizacja DAC
- ' [0 0 1 0 1 0 0 0] [ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0] SOFTWARE RESET
- ' [0 0 1 1 1 0 0 0] [ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 1] INTERNAL REFERENCE ON
- ' [0 0 1 0 0 0 0 0] [ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 1 1] POWER UP BOTH DACS
- ' SET DACS
- ' [0 0 0 1 1 0 0 0] [ X X X X X X X X] [X X X X X X X X] SET DAC A
- ' [0 0 0 1 1 0 0 1] [ X X X X X X X X] [X X X X X X X X] SET DAC B
- 'Implemet each I2c command
- Declare Sub Dac_reset()
- Declare Sub Dac_ref_on()
- Declare Sub Dac_ldac_async()
- Declare Sub Dac_power_on()
- Declare Sub Dac_set_a(value As Word)
- Declare Sub Dac_set_b(value As Word)
- Declare Sub Init_dac()
- 'Define the Hardware SCL and SDA port pins
- $lib "i2c_twi.lbx"
- Config Scl = Portc.0
- Config Sda = Portc.1
- I2cinit
- Config Twi = 100000
- 'Define the DAC address
- Dim Dac_addr As Byte
- Dac_addr = &B00011110 ' shift left 1 for hardware i2c (DONT KNOW WHY!)
- 'xxxxxxxxxxxx
- Dim Napiecie As Single
- Dim Voltages As String * 10
- 'xxxxxxxxxxxxxxxxxx
- Dim Dachigh As Byte
- Dim Daclow As Byte
- Dim Daccommand(3) As Byte
- Dim Length As Byte
- Dim Ia As Word
- Dim Ib As Word
- Dim Amp as Single
- Dim Ampi As Single
- Enable Interrupts
- Call Dac_reset()
- Call Dac_ref_on()
- Call Dac_ldac_async()
- Call Dac_power_on()
- Do
- For Ia = 0 To 65535 ' Na wyjściu DAC VOUTA napięcie 0 - 5V
- ' Ib = 32768 ' Na wyjściu DAC VOUTB ustawiłem na sztywno wartość 32768 = 2,5V
- Amp = 2.5
- Ampi = Amp / 5
- Ampi = Ampi * 65536
- Ib = Ampi
- Call Dac_set_a(ia)
- Call Dac_set_b(ib)
- Next Ia
- Loop
- End
- 'Reset DAC
- Sub Dac_reset
- ' [ Slave Address ] [ Command Data Byte ] [ Most Significant Data Byte ] [ Least Significant Data Byte ]
- ' [A7 A6 A5 A4 A3 A2 A1 A0] [R S C2 C1 C0 A2 A1 A0] [D7 D6 D5 D4 D3 D2 D1 D0] [D7 D6 D5 D4 D3 D2 D1 D0]
- ' [ 0 0 1 1 1 1 0 0] [0 0 1 0 1 0 0 0] [ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0] SOFTWARE RESET
- Length = 3
- Daccommand(1) = &B00101000 ' Command Byte
- Daccommand(2) = &B00000000 ' MSB
- Daccommand(3) = &B00000000 ' LSB
- I2csend Dac_addr , Daccommand(1) , Length
- Locate 1 , 1
- Lcd "Reset Dac " ; Err
- End Sub
- 'Internal voltage reference on
- Sub Dac_ref_on()
- ' [ Slave Address ] [ Command Data Byte ] [ Most Significant Data Byte ] [ Least Significant Data Byte ]
- ' [A7 A6 A5 A4 A3 A2 A1 A0] [R S C2 C1 C0 A2 A1 A0] [D7 D6 D5 D4 D3 D2 D1 D0] [D7 D6 D5 D4 D3 D2 D1 D0]
- ' [ 0 0 1 1 1 1 0 0] [0 0 1 1 1 0 0 0] [ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 1] INTERNAL REFERENCE ON
- Length = 3
- Daccommand(1) = &B00111000 ' Command Byte
- Daccommand(2) = &B00000000 ' MSB
- Daccommand(3) = &B00000001 ' LSB
- I2csend Dac_addr , Daccommand(1) , Length
- Locate 1 , 1
- Lcd "Dac Ref on " ; Err
- End Sub
- 'LDAC register set for asynchronous mode
- Sub Dac_ldac_async()
- ' [ Slave Address ] [ Command Data Byte ] [ Most Significant Data Byte ] [ Least Significant Data Byte ]
- ' [A7 A6 A5 A4 A3 A2 A1 A0] [R S C2 C1 C0 A2 A1 A0] [D7 D6 D5 D4 D3 D2 D1 D0] [D7 D6 D5 D4 D3 D2 D1 D0]
- ' [ 0 0 1 1 1 1 0 0] [0 0 1 1 0 0 0 0] [ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 1 1] INTERNAL REFERENCE ON
- Length = 3
- Daccommand(1) = &B00110000 ' Command Byte
- Daccommand(2) = &B00000000 ' MSB
- Daccommand(3) = &B00000011 ' LSB
- I2csend Dac_addr , Daccommand(1) , Length
- Locate 1 , 1
- Lcd "Dac Async " ; Err
- End Sub
- 'Power up both DAC channels
- Sub Dac_power_on()
- ' [ Slave Address ] [ Command Data Byte ] [ Most Significant Data Byte ] [ Least Significant Data Byte ]
- ' [A7 A6 A5 A4 A3 A2 A1 A0] [R S C2 C1 C0 A2 A1 A0] [D7 D6 D5 D4 D3 D2 D1 D0] [D7 D6 D5 D4 D3 D2 D1 D0]
- ' [ 0 0 1 1 1 1 0 0] [0 0 1 0 0 0 0 0] [ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 1 1] POWER UP BOTH DACS
- Length = 3
- Daccommand(1) = &B00100000 ' Command Byte
- Daccommand(2) = &B00000000 ' MSB
- Daccommand(3) = &B00000011 ' LSB
- I2csend Dac_addr , Daccommand(1) , Length
- Locate 1 , 1
- Lcd "Dac Power " ; Err
- End Sub
- 'Set DAC channel A
- Sub Dac_set_a(value As Word)
- ' [ Slave Address ] [ Command Data Byte ] [ Most Significant Data Byte ] [ Least Significant Data Byte ]
- ' [A7 A6 A5 A4 A3 A2 A1 A0] [R S C2 C1 C0 A2 A1 A0] [D7 D6 D5 D4 D3 D2 D1 D0] [D7 D6 D5 D4 D3 D2 D1 D0]
- ' [ 0 0 1 1 1 1 0 0] [0 0 0 1 1 0 0 0] [ X X X X X X X X] [X X X X X X X X] SET DAC A
- Length = 3
- Dachigh = High(value)
- Daclow = Low(value)
- Daccommand(1) = &B00011000 ' Command Byte
- Daccommand(2) = Dachigh ' MSB
- Daccommand(3) = Daclow ' LSB
- I2csend Dac_addr , Daccommand(1) , Length
- Locate 1 , 1
- Lcd "Set Dac A " ; Value ; " " ; Err
- End Sub
- 'Set DAC channel B
- Sub Dac_set_b(value As Word)
- ' [ Slave Address ] [ Command Data Byte ] [ Most Significant Data Byte ] [ Least Significant Data Byte ]
- ' [A7 A6 A5 A4 A3 A2 A1 A0] [R S C2 C1 C0 A2 A1 A0] [D7 D6 D5 D4 D3 D2 D1 D0] [D7 D6 D5 D4 D3 D2 D1 D0]
- ' [ 0 0 1 1 1 1 0 0] [0 0 0 1 1 0 0 1] [ X X X X X X X X] [X X X X X X X X] SET DAC B
- Length = 3
- Dachigh = High(value)
- Daclow = Low(value)
- Daccommand(1) = &B00011001 ' Command Byte
- Daccommand(2) = Dachigh ' MSB
- Daccommand(3) = Daclow ' LSB
- I2csend Dac_addr , Daccommand(1) , Length
- ' Przekształcenie wartości Ib = 0 - 65535 na napięcie wyświetlane na LCD
- Napiecie = Ib / 65536
- Napiecie = Napiecie * 5
- '
- Locate 2 , 1
- Voltages = Fusing(napiecie , "&&.&&&")
- Lcd "Set Dac B " ; Voltages
- End Sub
Czyli do DAC trzeba wysyłać wartość 0 - 65536.
A wartość ustawiona x 4 da nam wartość napięcia wyjściowego i tym samym wartość wyświetloną na LCD.
Przeszukując Twoją stronę Bartku, znalazłem kod do obsługi enkodera, (ten z kondensatorami 22n pomiędzy A i B a GND), który na lcd daje właśnie kod 0 - 65536.
Załadowałem go do mojego procka i działa pięknie, tylko jak zrobić wybór napięcia na wyświetlaczy lcd, np.: 12,445V?
Wiem już, jak przekształcić wartość wyświetlana na wyświetlaczu na kod 0 - 65536, który trzeba wysłać do DAC.
Zmienną Ib = od 0 do 65536 wysyłamy do DAC.
Code: [Zaznacz cały] [Rozwiń/Zwiń]
- Amp = 2.5 ' wartość napięcia na wyświetlaczu
- Ampi = Amp / 5
- Ampi = Ampi * 65536
- Ib = Ampi
Bo używając samego kodu z enkodera musiałbym przekręcić od 0 do 65536 impulsów żeby dojść od zera do 20V. To bez sensu byłoby i zajęłoby z 10 minut.
Pomyślałem, że możnaby to zrobić w ten sposób, że wybieram switchem enkodera po kolei poszczególne pozycje wartości napięcia, np.: 5,555V, to najpierw ustawiam wartość tysięcznych volta, potem setnych volta, dziesiętne i jedności, po czym kolejne kliknięcie switch enkodera ładuje to napięcie za pomocą kodu 0 -65536 do przetwornika DAC.
Myślę, że to byłoby najlepsze rozwiązanie. Ale nie wiem jak utworzyć taką wartość na lcd, by móc po kolei zmieniać poszczególne wartości 0 - 9.
- niveasoft
- Posty: 1239
- Rejestracja: 17 sie 2015, 12:13
- Kontakt:
Re: Przetwornik DAC do zasilacza
To jest proste jak świński ogon. Napisałem to zanim wypiłem kubek kawy.
Zwiększaj całą zmienną z blokadą przekroczenia zakresu. Np. If Zmienna > 5000 then Zmienna = 5000.
Kolejne naciśnięcia przycisku zwiększają zmienną Pos która wskazuje na literkę w stringu. Ta wybrana miga. Pomijana jest kropka.
Ta sama zmienna Pos steruje aktualnym mnożnikiem Enkodera.
Testowane w symulatorze.
Teraz trzeba dopisać czasówkę by migało tylko przez jakiś czas po naciśnięciu, ale tu już sobie chyba poradzisz
Może jeszcze trzeba to rozbudować o miganie dwoma cyframi w przypadku > 9V z przodu czyli 10V-20V
Zwiększaj całą zmienną z blokadą przekroczenia zakresu. Np. If Zmienna > 5000 then Zmienna = 5000.
Kolejne naciśnięcia przycisku zwiększają zmienną Pos która wskazuje na literkę w stringu. Ta wybrana miga. Pomijana jest kropka.
Ta sama zmienna Pos steruje aktualnym mnożnikiem Enkodera.
Testowane w symulatorze.
Teraz trzeba dopisać czasówkę by migało tylko przez jakiś czas po naciśnięciu, ale tu już sobie chyba poradzisz
Może jeszcze trzeba to rozbudować o miganie dwoma cyframi w przypadku > 9V z przodu czyli 10V-20V
Code: [Zaznacz cały] [Rozwiń/Zwiń]
- $regfile = "m328pdef.dat"
- $crystal = 16000000
- $hwstack = 128
- $swstack = 128
- $framesize = 255
- $baud = 115200
- $sim 'symulator
- Dim Pos As Byte , Mig As Byte , Mnoznik As Word
- Dim Volt_str As String * 10 , Temp_str As String * 10
- Volt_str = "5.555V"
- Enc_sw Alias Pinc.5 : Set Portc.5
- Do
- If Enc_sw = 0 Then
- Incr Pos : If Pos > 5 Then Pos = 1
- If Pos = 2 Then Pos = 3 'przeskocz kropkę
- End If
- If Mig = 0 Then
- Mig = 1
- Temp_str = Volt_str
- Else
- Mig = 0
- Mid(temp_str , Pos) = " " 'wstaw spację w miejscu pos (migaj)
- End If
- Locate 1 , 1 : Lcd Temp_str
- Select Case Pos
- Case 1
- Mnoznik = 1000
- Case 3
- Mnoznik = 100
- Case 4
- Mnoznik = 10
- Case 5
- Mnoznik = 1
- End Select
- Wait 1
- Loop
- Michał6201
- Posty: 127
- Rejestracja: 03 paź 2015, 20:07
Re: Przetwornik DAC do zasilacza
Niestety enkoder nie zmienia wartości poszczególnych pozycji.
Jedyne co robi, to zmienia po kolei migające pozycje za pomocą przycisku Enc_sw.
A powinny zmieniać się pozycja jedności od 0 do 20
Natomiast po przecinku pozostałe pozycje od 0 do 9
Nie da się zapisać Incr Temp_str, wywala błąd.
Jedyne co robi, to zmienia po kolei migające pozycje za pomocą przycisku Enc_sw.
A powinny zmieniać się pozycja jedności od 0 do 20
Natomiast po przecinku pozostałe pozycje od 0 do 9
Nie da się zapisać Incr Temp_str, wywala błąd.
Code: [Zaznacz cały] [Rozwiń/Zwiń]
- $regfile = "m32def.dat"
- $crystal = 11059200
- ' Konfiguracja LCD 2X16
- Config Lcdpin = Pin , E = PortA.3 , Rs = PortA.2 , Db7 = PortA.7 , Db6 = PortA.6 , Db5 = PortA.5 , Db4 = PortA.4
- Config Lcd = 16x2
- Cursor Off
- Cls
- Dim Pos As Byte , Mig As Byte , Mnoznik As Word
- Dim Volt_str As String * 10
- Dim Temp_str As String * 10
- ' config for encoder
- Config Portd.2 = Input : Portd.2 = 1 : Encoder_a Alias Pind.2
- Config Portd.3 = Input : Portd.3 = 1 : Encoder_b Alias Pind.3 'to też pin INT1
- Config PORTD.7 = Input : PORTD.7 = 1 : Enc_sw Alias PIND.7
- Config Int1 = Rising 'przerwanie generować będzie rosnące zbocze
- Enable Int1 : On Int1 Encoder_isr Nosave
- Dim Encoder_turn_left As Byte , Encoder_turn_right As Byte
- '-------------------------------------------
- Dim Zmienna As Word
- Enable Interrupts
- Volt_str = "0.000V"
- Do
- If Enc_sw = 0 Then
- Incr Pos : If Pos > 5 Then Pos = 1
- If Pos = 2 Then Pos = 3 'przeskocz kropkę
- End If
- If Mig = 0 Then
- Mig = 1
- Temp_str = Volt_str
- Else
- Mig = 0
- Mid(temp_str , Pos) = " " 'wstaw spację w miejscu pos (migaj)
- End If
- Locate 1 , 1 : Lcd Temp_str
- Select Case Pos
- Case 1
- Mnoznik = 1000
- Case 3
- Mnoznik = 100
- Case 4
- Mnoznik = 10
- Case 5
- Mnoznik = 1
- End Select
- Wait 1
- '##### encoder turns left ######
- If 0 < Encoder_turn_left Then
- Decr Encoder_turn_left
- 'tutaj Twój kod -
- Decr Temp_str
- 'Locate 1 , 10 : Lcd Zmienna1 ; " "
- Gifr.intf1 = 1 'dla Mega8, M32 itp
- Enable Int1
- End If
- ' #### encoder turns right ######
- If 0 < Encoder_turn_right Then
- Decr Encoder_turn_right
- 'tutaj Twój kod +
- Incr Temp_str
- 'Locate 1 , 10 : Lcd Zmienna1 ; " "
- Gifr.intf1 = 1 'dla Mega8, M32 itp
- Enable Int1
- end if
- Loop
- End
- 'tutaj obsługa przerwania zewnetrznego z enkodera
- Encoder_isr:
- $asm
- PUSH R23
- PUSH R24
- PUSH R26
- PUSH R27
- !in R24, sreg
- PUSH R24
- $end asm
- Disable Int1
- If Encoder_a = 1 Then
- Incr Encoder_turn_right
- Else
- Incr Encoder_turn_left
- End If
- ' Tuned with NoSave Tool
- $asm
- POP R24
- !out sreg, r24
- POP R27
- POP R26
- POP R24
- POP R23
- $end asm
- Return
- Michał6201
- Posty: 127
- Rejestracja: 03 paź 2015, 20:07
Re: Przetwornik DAC do zasilacza
Jeszcze dopisałem do każdej pozycji inną zmienną ale to bez sensu działa, bo znikają ustawione wartości i nijak nie da się tego wysłać do DAC.
Bardzo proszę o pomoc, jak to poprawnie napisać.
Bardzo proszę o pomoc, jak to poprawnie napisać.
Code: [Zaznacz cały] [Rozwiń/Zwiń]
- ' OBSŁUGA ENCODERA
- $regfile = "m32def.dat"
- $crystal = 11059200
- ' Konfiguracja LCD 2X16
- Config Lcdpin = Pin , E = PortA.3 , Rs = PortA.2 , Db7 = PortA.7 , Db6 = PortA.6 , Db5 = PortA.5 , Db4 = PortA.4
- Config Lcd = 16x2
- Cursor Off
- Cls
- Dim Pos As Byte , Mig As Byte , Mnoznik As Word
- Dim Volt_str As String * 10
- Dim Temp_str As String * 10
- Dim Temp As Byte
- ' config for encoder
- Config Portd.2 = Input : Portd.2 = 1 : Encoder_a Alias Pind.2
- Config Portd.3 = Input : Portd.3 = 1 : Encoder_b Alias Pind.3 'to też pin INT1
- Config PORTD.7 = Input : PORTD.7 = 1 : Enc_sw Alias PIND.7
- Config Int1 = Rising 'przerwanie generować będzie rosnące zbocze
- Enable Int1 : On Int1 Encoder_isr Nosave
- Dim Encoder_turn_left As Byte , Encoder_turn_right As Byte
- '-------------------------------------------
- Dim Zmienna1 As Word
- Dim Zmienna2 As Word
- Dim Zmienna3 As Word
- Dim Zmienna4 As Word
- Enable Interrupts
- Volt_str = " . V"
- Do
- If Enc_sw = 0 Then
- Incr Pos : If Pos > 5 Then Pos = 1
- If Pos = 2 Then Pos = 3 'przeskocz kropkę
- End If
- If Mig = 0 Then
- Mig = 1
- Temp_str = Volt_str
- Else
- Mig = 0
- Mid(Temp_str , Pos) = " " 'wstaw spację w miejscu pos (migaj)
- End If
- Locate 1 , 1 : Lcd Temp_str
- Select Case Pos
- Case 1
- Mnoznik = 1000
- Locate 1 , 1 : Lcd Zmienna1 ; "."
- Case 3
- Mnoznik = 100
- Locate 1 , 3 : Lcd Zmienna2
- Case 4
- Mnoznik = 10
- Locate 1 , 4 : Lcd Zmienna3
- Case 5
- Mnoznik = 1
- Locate 1 , 5 : Lcd Zmienna4
- End Select
- Wait 1
- '##### encoder turns left ######
- If 0 < Encoder_turn_left Then
- Decr Encoder_turn_left
- 'tutaj Twój kod -
- Decr Zmienna1
- Decr Zmienna2
- Decr Zmienna3
- Decr Zmienna4
- Gifr.intf1 = 1 'dla Mega8, M32 itp
- Enable Int1
- End If
- ' #### encoder turns right ######
- If 0 < Encoder_turn_right Then
- Decr Encoder_turn_right
- 'tutaj Twój kod +
- Incr Zmienna1
- Incr Zmienna2
- Incr Zmienna3
- Incr Zmienna4
- Gifr.intf1 = 1 'dla Mega8, M32 itp
- Enable Int1
- end if
- Loop
- End
- 'tutaj obsługa przerwania zewnetrznego z enkodera
- Encoder_isr:
- $asm
- PUSH R23
- PUSH R24
- PUSH R26
- PUSH R27
- !in R24, sreg
- PUSH R24
- $end asm
- Disable Int1
- If Encoder_a = 1 Then
- Incr Encoder_turn_right
- Else
- Incr Encoder_turn_left
- End If
- ' Tuned with NoSave Tool
- $asm
- POP R24
- !out sreg, r24
- POP R27
- POP R26
- POP R24
- POP R23
- $end asm
- Return
- Michał6201
- Posty: 127
- Rejestracja: 03 paź 2015, 20:07
Re: Przetwornik DAC do zasilacza
Zrobiłem coś takiego. Niby działa i mogę zmieniać poszczególne cyferki w wartości napięcia na LCD, ale:
- nie miga wybrana pozycja
- czasami zamiast zwiększać wartość o jeden, to zmniejsza, tak jakby się mylił
- przy przejściu do następnej pozycji przenosi wartość cyfry, więc ustawiając części dziesiąte i przechodząc do jedności można przenieść np cyfrę 6 i tym samym nagle dać na wyjściu DAC 6V. To dyskwalifikuje to rozwiązanie w zasilaczu. Tu nie może być błędów tego typu.
A kod wygląda tak:
Czy ktoś z Wam pomoże mi poprawić ten kod, aby nie robił takich błędów?
- nie miga wybrana pozycja
- czasami zamiast zwiększać wartość o jeden, to zmniejsza, tak jakby się mylił
- przy przejściu do następnej pozycji przenosi wartość cyfry, więc ustawiając części dziesiąte i przechodząc do jedności można przenieść np cyfrę 6 i tym samym nagle dać na wyjściu DAC 6V. To dyskwalifikuje to rozwiązanie w zasilaczu. Tu nie może być błędów tego typu.
A kod wygląda tak:
Code: [Zaznacz cały] [Rozwiń/Zwiń]
- ' OBSŁUGA ENCODERA
- $regfile = "m32def.dat"
- $crystal = 11059200
- ' Konfiguracja LCD 2X16
- Config Lcdpin = Pin , E = PortA.3 , Rs = PortA.2 , Db7 = PortA.7 , Db6 = PortA.6 , Db5 = PortA.5 , Db4 = PortA.4
- Config Lcd = 16x2
- Cursor Off
- Cls
- Dim Pos As Byte , Mig As Byte , Mnoznik As Word
- Dim Volt_str As String * 10
- Dim Temp_str As String * 10
- Dim Temp As Byte
- ' config for encoder
- Config Portd.2 = Input : Portd.2 = 1 : Encoder_a Alias Pind.2
- Config Portd.3 = Input : Portd.3 = 1 : Encoder_b Alias Pind.3 'to też pin INT1
- Config PORTD.7 = Input : PORTD.7 = 1 : Enc_sw Alias PIND.7
- Config Int1 = Rising 'przerwanie generować będzie rosnące zbocze
- Enable Int1 : On Int1 Encoder_isr Nosave
- Dim Encoder_turn_left As Byte , Encoder_turn_right As Byte
- '-------------------------------------------
- Dim Zmienna1 As Word
- Dim Napiecie As Single
- Dim Voltages As String * 10
- Enable Interrupts
- Volt_str = "5.555V"
- Do
- If Enc_sw = 0 Then
- Incr Pos : If Pos > 5 Then Pos = 1
- If Pos = 2 Then Pos = 3 'przeskocz kropkę
- End If
- If Mig = 0 Then
- Mig = 1
- Temp_str = Volt_str
- Else
- Mig = 0
- Mid(Temp_str , Pos) = " " 'wstaw spację w miejscu pos (migaj)
- End If
- Temp_str = Fusing(Napiecie ,"&&.&&&")
- Locate 1 , 1 : Lcd Temp_str ; "V "
- Select Case Pos
- Case 1
- Mnoznik = 1000
- Case 3
- Mnoznik = 100
- Case 4
- Mnoznik = 10
- Case 5
- Mnoznik = 1
- End Select
- Wait 1
- '##### encoder turns left ######
- If 0 < Encoder_turn_left Then
- Decr Encoder_turn_left
- 'tutaj Twój kod -
- Decr Zmienna1
- Napiecie = Zmienna1 / Mnoznik
- If Napiecie < 0 Then Napiecie = 0
- Gifr.intf1 = 1 'dla Mega8, M32 itp
- Enable Int1
- End If
- ' #### encoder turns right ######
- If 0 < Encoder_turn_right Then
- Decr Encoder_turn_right
- 'tutaj Twój kod +
- Incr Zmienna1
- Napiecie = Zmienna1 / Mnoznik
- If Napiecie > 20 Then Napiecie = 20
- Gifr.intf1 = 1 'dla Mega8, M32 itp
- Enable Int1
- end if
- Loop
- End
- 'tutaj obsługa przerwania zewnetrznego z enkodera
- Encoder_isr:
- $asm
- PUSH R23
- PUSH R24
- PUSH R26
- PUSH R27
- !in R24, sreg
- PUSH R24
- $end asm
- Disable Int1
- If Encoder_a = 1 Then
- Incr Encoder_turn_right
- Else
- Incr Encoder_turn_left
- End If
- ' Tuned with NoSave Tool
- $asm
- POP R24
- !out sreg, r24
- POP R27
- POP R26
- POP R24
- POP R23
- $end asm
- Return
- niveasoft
- Posty: 1239
- Rejestracja: 17 sie 2015, 12:13
- Kontakt:
Re: Przetwornik DAC do zasilacza
Moment. Muszę wyjechać około ósmej, ale tu roboty najwięcej jest chyba z połączeniem tego do testu na płytce
- niveasoft
- Posty: 1239
- Rejestracja: 17 sie 2015, 12:13
- Kontakt:
Re: Przetwornik DAC do zasilacza
Dobra. Tyle zrobiłem w pół godziny. Chyba wszystko działa.
Teraz spadam.
Teraz spadam.
Code: [Zaznacz cały] [Rozwiń/Zwiń]
- $regfile = "m32def.dat"
- $crystal = 11059200
- $hwstack = 64
- $swstack = 16
- $framesize = 64
- Const Timeout_time = 8 'x500ms
- Config Submode = New
- ' config LCD 2X16
- Config Lcdpin = Pin , Rs = Porta.2 , E = Porta.3 , Db4 = Porta.4 , Db5 = Porta.5 , Db6 = Porta.6 , Db7 = Porta.7
- Config Lcd = 16x2
- Cursor Off
- Cls
- '-------------------------------------------
- ' config for encoder
- Config Portd.2 = Input : Portd.2 = 1 : Encoder_a Alias Pind.2
- Config Portd.3 = Input : Portd.3 = 1 : Encoder_b Alias Pind.3 'to też pin INT1
- Config Portd.7 = Input : Portd.7 = 1 : Enc_sw Alias Pind.7
- Config Int1 = Rising 'przerwanie generować będzie rosnące zbocze
- Enable Int1 : On Int1 Encoder_isr Nosave
- Dim Encoder_turn_left As Byte , Encoder_turn_right As Byte
- '-------------------------------------------
- ' config Timer2
- Config Timer2 = Timer , Prescale = 1024 , Clear_timer = 1
- Compare2 = 107 '10ms @11MHz/1024
- 'settings
- Dim 500ms As Byte , Mig As Byte , Timeout As Byte
- Dim Napiecie As Single , Napiecie_ee As Eram Single
- Dim Pos As Byte , Pos_ee As Eram Byte
- Dim Mnoznik As Word
- Dim Volt_str As String * 10
- Dim Temp_str As String * 10
- Enable Interrupts
- Sub Show_voltage
- Temp_str = Fusing(napiecie , "#.&&&")
- Volt_str = Format(temp_str , " ") 'dwa znaki+kropka+trzy znaki
- If Mig = 1 Then
- Select Case Pos
- Case 1
- Mid(volt_str , 1) = " " 'wstaw spację w miejscu pos (migaj)
- Case 2
- Mid(volt_str , 4) = " "
- Case 3
- Mid(volt_str , 5) = " "
- Case 4
- Mid(volt_str , 6) = " "
- End Select
- End If
- Locate 1 , 1 : Lcd Volt_str
- End Sub
- Sub Set_dac
- 'przelicz Single Napiecie i wyslij do DAC
- End Sub
- ' eeprom reading
- '------------------------------
- Pos = Pos_ee
- If Pos > 4 Then
- Pos = 4 : Pos_ee = Pos
- Napiecie_ee = 0
- End If
- Napiecie = Napiecie_ee
- '------------------------------
- Call Show_voltage()
- Call Set_dac()
- Do
- Debounce Enc_sw , 0 , Enc_sw_sub , Sub
- '##### encoder turns left ######
- If 0 < Encoder_turn_left Then
- Decr Encoder_turn_left
- 'tutaj Twój kod -
- If Timeout > 0 Then
- Select Case Pos
- Case 1
- Napiecie = Napiecie - 1.0
- Case 2
- Napiecie = Napiecie - 0.1
- Case 3
- Napiecie = Napiecie - 0.01
- Case 4
- Napiecie = Napiecie - 0.001
- End Select
- If Napiecie < 0 Then Napiecie = 0
- Mig = 0 : Call Show_voltage
- End If
- Timeout = Timeout_time 'przedłuzaj/uruchamiaj timeout przy kazdym kliku
- Gifr.intf1 = 1 'dla Mega8, M32 itp
- Enable Int1
- End If
- ' #### encoder turns right ######
- If 0 < Encoder_turn_right Then
- Decr Encoder_turn_right
- 'tutaj Twój kod +
- If Timeout > 0 Then
- Select Case Pos
- Case 1
- Napiecie = Napiecie + 1
- Case 2
- Napiecie = Napiecie + 0.1
- Case 3
- Napiecie = Napiecie + 0.01
- Case 4
- Napiecie = Napiecie + 0.001
- End Select
- If Napiecie > 20.0 Then Napiecie = 20.0
- Mig = 0 : Call Show_voltage
- End If
- Timeout = Timeout_time 'przedłuzaj/uruchamiaj timeout przy kazdym kliku
- Gifr.intf1 = 1 'dla Mega8, M32 itp
- Enable Int1
- End If
- If Tifr.ocf2 = 1 Then '10ms
- Tifr.ocf2 = 1
- If 500ms < 49 Then
- Incr 500ms
- Else
- 500ms = 0
- If Mig = 0 Then Mig = 1 Else Mig = 0
- If Timeout > 0 Then
- Decr Timeout
- If Timeout = 0 Then
- 'wyślij do DAC
- Mig = 0
- Napiecie_ee = Napiecie 'zapamietaj dopiero po Timeoucie
- Call Set_dac
- End If
- Call Show_voltage()
- End If
- End If
- End If
- Loop
- End
- Enc_sw_sub:
- If Timeout > 0 Then
- Incr Pos : If Pos > 4 Then Pos = 1
- Pos_ee = Pos
- End If
- Timeout = Timeout_time 'przedłuzaj/uruchamiaj timeout przy kazdym kliku
- Return
- 'tutaj obsługa przerwania zewnetrznego z enkodera
- Encoder_isr:
- $asm
- PUSH R23
- PUSH R24
- PUSH R26
- PUSH R27
- !in R24, sreg
- PUSH R24
- $end Asm
- Disable Int1
- If Encoder_a = 1 Then
- Incr Encoder_turn_right
- Else
- Incr Encoder_turn_left
- End If
- ' Tuned with NoSave Tool
- $asm
- POP R24
- !out sreg, r24
- POP R27
- POP R26
- POP R24
- POP R23
- $end Asm
- Return
- Michał6201
- Posty: 127
- Rejestracja: 03 paź 2015, 20:07
Re: Przetwornik DAC do zasilacza
Dziękuję Ci bardzo. W życiu bym tego nie ogarnął.
Teraz sobie zrobiłem ten kod na dwa enkodery, Jeden służy do ustawiana napięcia, a drugi do ustawienia ograniczenia prądowego.
Jedn enkoder działa na INT1, a drugi na INT0
Teraz sobie zrobiłem ten kod na dwa enkodery, Jeden służy do ustawiana napięcia, a drugi do ustawienia ograniczenia prądowego.
Jedn enkoder działa na INT1, a drugi na INT0