Strona 1 z 1

ATmega644A nie działa program napisanym pod ATmega32

: 30 maja 2021, 16:02
autor: Michał6201
Witam
Jak w temacie - próba skompilowania programy napisanego pod ATmega32 dla ATmega644 kończy się błędami.

Oczywiście na początku programu jest:
  1. $regfile = "m644def.dat"
A problem dotyczy:
  1. Compare2 = 107 '10ms @11MHz/1024
oraz
  1. Gifr.intf0 = 1
Przypuszczam, że jakieś rejestry timera może sa inne w atmega644?
To jest ten program do mojego zasilacza. Działa poprawnie z ATmega32, natomiast na zapas chciałem wstawić większy procek ATmega644, aby w przyszłości można było rozbudowywać program, bez ograniczeń co do wielkości pamięci flash.

No i utknąłem na kompilacji :(

Re: ATmega644A nie działa program napisanym pod ATmega32

: 30 maja 2021, 18:18
autor: niveasoft
Nie rób się kaczką :D Otwórz datasheet. Najprawdopodobniej jest tam Compare2a, Compare2b itd...
GIFR to General Interrupt Flags Register. Musi mieć swój odpowiednik w tym uC..

Re: ATmega644A nie działa program napisanym pod ATmega32

: 30 maja 2021, 22:35
autor: Michał6201
Chyba znalazłem te rejestry i skompilowało się w bascomie.
Ale nie działa ta atmega644. Nie da się załadować wsadu do niej. Żadnego. Już nawet napisałem prosty program wyświetlający tylko napis "test atmega644" aby wykluczyć błąd programu i lipa.
Ten sam program działa na atmega32, atmega16. Więc wykluczam błąd programu, zwłaszcza że to tylko jedna linijka kodu.

ATmega644 kupiłem już dawno temu w TME i tak leżała nigdy nie używana w ich oryginalnym opakowaniu, więc raczej powinna być sprawna.

Wsady ładuję do procków przez mk avr calculator. Program rozpoznaje tą atmegę.

Re: ATmega644A nie działa program napisanym pod ATmega32

: 30 maja 2021, 23:05
autor: Jacek
Michał a masz pełna wersję MK AVR?
pozdrawiam Jacek

Re: ATmega644A nie działa program napisanym pod ATmega32

: 30 maja 2021, 23:41
autor: Michał6201
Tak, to pełna wersja. Chyba w 2015r dostałem ją do kupionego programatorka usbasp.

Re: ATmega644A nie działa program napisanym pod ATmega32

: 31 maja 2021, 1:29
autor: Michał6201
Rozwiązałem problem :)
Problemem był programator, którego używałem do tej pory.
Podłączyłem teraz inny programator usbasp i działa procek :D

Nic z tej ATmegi644 nie będzie. Nie jest w stanie przyjąć wsadu, który bez problemu wchodzi do ATmegi32. Wiesza się avr calculator i nic z tym nie można zrobić oprócz restartu komputera. Żenada jakaś ten procek.

Re: ATmega644A nie działa program napisanym pod ATmega32

: 31 maja 2021, 9:14
autor: niveasoft
Procesor jak procesor. Mega644 akurat bardzo lubię ze względu na dwa USART`y. Można sobie coś oprogramować na ESP czy BT a drugim COM debugować.
Ja prawie wszystko programuję bezpośrednio z Bascom`a. Kalkulatora używam tylko do fusów bo jakoś mi wygodniej i szybciej :D
Sprawdź czy czasem nie masz dalej włączonego CKDIV8 albo inne taktowanie. Spróbuj podłączyć kwarc albo weź drugą, dowolną megę i z niej wygeneruj sygnał zegara i podłącz go do pinu XTAL1 (albo XTAL2 - nie pamiętam).
Chodzi o to, że czasem programator jak ma problemy to potrafi przestawić fusy.

Re: ATmega644A nie działa program napisanym pod ATmega32

: 03 cze 2021, 12:04
autor: Michał6201
Ta Atmega644 chyba jest uszkodzona.
Spróbowałem ją zaprogramować bezpośrednio z bascoma i wywala błąd jakiś: Chip differs at bytes addres: 00002, [3E]-[2A]
I tylko przy tej atmedze taki błąd jest. Inne atmegi programują się bez problemu bezpośrednio z bascoma.

Ten sam błąd wyskakuje przy ustawionym wewnętrznym oscylatorze, jak i zewnętrznym.
CKDIV8 jest wyłączony.

Re: ATmega644A nie działa program napisanym pod ATmega32

: 20 cze 2021, 23:40
autor: Michał6201
Witam ponownie
Po uporaniu się z programatorem, zająłem się przesiadką z atmega32 na atmega644p. Zamieniłem rejestry:

COMPARE2 na COMPARE2A
Gifr.intf0 na Eifr.intf0
Gifr.intf1 na Eifr.intf1
Tifr.ocf2 na Tifr2.ocf2A


Niestety nie działa tak płynnie program na atmega644p jak w atmega32. Zmiana enkoderami wartości nie działa płynnie, gubi cyfry czasami lub schodzi w dół zamiast w górę.
Nie działa też Debounce w przyciskach.

Co zrobiłem źle?

W załączeniu kod dla atmega32:
  1. ' ##############################
  2. ' ####   DC POWER SUPPLY    ####
  3. ' ####       M32 16PU       ####
  4. ' ##############################
  5.  
  6. $regfile = "m32def.dat"
  7. $crystal = 11059200
  8. $hwstack = 64
  9. $swstack = 64
  10. $framesize = 64
  11.  
  12. Const Timeout_time = 8 'x500ms
  13. Config Submode = New
  14.  
  15. ' config LCD 2X16
  16. Config Lcdpin = Pin , Rs = Porta.0 , E = Porta.1 , Db4 = Porta.2 , Db5 = Porta.3 , Db6 = Porta.4 , Db7 = Porta.5
  17. Config Lcd = 20x4
  18. Cursor Off
  19. Cls
  20.  
  21. Const Error = " ERROR"
  22. Const Info = "Press  switch On/Off"
  23. Const Frame_long = "--------------------"
  24.  
  25. 'Konfiguracja 1-WIRE dla DS18B20
  26. Config 1wire = Portc.6
  27.  
  28. ' Zmienne pomiar temperatury
  29. Dim Ds1(8) As Byte
  30. Dim Temperatura As Byte
  31. Dim Temperatura_str As String * 5
  32. Dim Ts As Integer
  33. Dim Wew(9) As Byte
  34. Dim T_heatsink As Integer
  35.  
  36.  ' ID Ds1 (HEX) 28E731CB010000FD czujnik temperatury głównego radiatora
  37. Ds1(1) = &H28
  38. Ds1(2) = &HE7
  39. Ds1(3) = &H31
  40. Ds1(4) = &HCB
  41. Ds1(5) = &H01
  42. Ds1(6) = &H00
  43. Ds1(7) = &H00
  44. Ds1(8) = &HFD
  45.  
  46. Declare Sub Temperature()
  47. Declare Sub Show_temperature()
  48.  
  49. ' Konfiguracja i/o
  50. Config POrTC.3 = Input : PORTC.3 = 1 : output_sw Alias PINC.3 ' switch OUTPUT ON/OFF
  51. Config Portc.5 = Output : Portc.5 = 0 : relay Alias Portc.5 ' Przekaźnik OUTPUT ON/OFF
  52. Config PortC.4 = Output : PortC.4 = 0 : output_led Alias PortC.4 'Led OUTPUT ON/0FF
  53. Config PortD.4 = Output : PortD.4 = 0 : buzzer Alias PortD.4 'Buzzer
  54. Config POrTA.7 = Input : PORTA.7 = 1 : cv Alias PINA.7 ' constant voltage
  55. Config POrTC.7 = Input : PORTC.7 = 1 : cc Alias PINC.7 ' constant current
  56. Config POrTB.0 = Input : PORTB.0 = 1 : ovp_sw Alias PINB.0 ' switch OVP
  57. Config POrTB.1 = Input : PORTB.1 = 1 : ocp_sw Alias PINB.1 ' switch OCP
  58. Config POrTB.3 = Input : PORTB.3 = 1 : sw1 Alias PINB.3 ' switch 1
  59. Config POrTB.2 = Input : PORTB.2 = 1 : sw2 Alias PINB.2 ' switch 2
  60. Config POrTB.4 = Input : PORTB.4 = 1 : sw3 Alias PINB.4 ' switch 3
  61.  
  62. Dim ovp As Single
  63. Dim ocp As Single
  64. Dim ov As Bit ' zmienna pomocnicza dla OVP
  65. Dim oc As Bit ' zmienna pomocnicza dla OCP
  66. Dim ot As Bit ' zmienna pomocnicza dla OTP
  67. Dim S As Bit
  68. ov = 0
  69. oc = 0
  70. ot = 0
  71. S = 0
  72.  
  73. Dim Pulses As Word  'Zmienna długości dźwięku
  74. Dim Periods As Word ' Zmienna barwy dźwięku
  75.  
  76. ' Symbole na LCD
  77. Deflcdchar 0,17,17,17,10,4,32,32,32' (volt)
  78. Deflcdchar 1,14,17,17,31,17,32,32,32' (amper)
  79. Deflcdchar 2,17,17,21,21,10,32,32,32' (wat)
  80. Deflcdchar 3,14,17,17,14,32,32,32,32' (stopień celcjusza)
  81.  
  82. ' Zmienne do zapisu danych w eeprom 24C02
  83. Dim N As Byte
  84. Dim Napiecie_ee As Single
  85. Dim Buf1(20) As Byte At Napiecie_ee Overlay
  86. Dim Pos_ee As Single
  87. Dim Buf2(20) As Byte At Pos_ee Overlay
  88. Dim Prad_ee As Single
  89. Dim Buf3(20) As Byte At Prad_ee Overlay
  90. Dim Pos2_ee As Single
  91. Dim Buf4(20) As Byte At Pos2_ee Overlay
  92.  
  93. ' Define the 24C02 EEPROM address
  94. Const Addressw_ee = 168
  95. Const Addressr_ee = 169
  96.  
  97. ' Konfiguracja I2C
  98. $lib "i2c_twi.lbx"
  99. Config Scl = Portc.0
  100. Config Sda = Portc.1
  101. I2cinit
  102. Config Twi = 100000
  103.  
  104. '#######################   Config for encoders  #########################################
  105.  
  106. ' ENCODER U_SET
  107. Config PortD.5 = Input : PortD.5 = 1 : Encoder1_a Alias PinD.5      'ENKODER1A
  108. Config Portd.3 = Input : Portd.3 = 1 : Encoder1_b Alias Pind.3      'ENKODER1B, INT1
  109. Config PortD.7 = Input : PortD.7 = 1 : Enc_sw1 Alias PinD.7         ' Przycisk Enkoder1
  110.  
  111. ' ENCODER I_SET
  112. Config PortD.6 = Input : PortD.6 = 1 : Encoder2_a Alias PinD.6      'ENKODER2A
  113. Config Portd.2 = Input : Portd.2 = 1 : Encoder2_b Alias Pind.2      'ENKODER2B, INT0
  114. Config PortC.2 = Input : PortC.2 = 1 : Enc_sw2 Alias PinC.2         ' Przycisk Enkoder2
  115.  
  116. Config Int1 = Rising 'przerwanie  generować będzie rosnące zbocze
  117. Enable Int1 : On Int1 Encoder1_isr Nosave
  118.  
  119. Config Int0 = Rising 'przerwanie  generować będzie rosnące zbocze
  120. Enable Int0 : On Int0 Encoder2_isr Nosave
  121.  
  122. Dim Encoder1_turn_left As Byte , Encoder1_turn_right As Byte
  123. Dim Encoder2_turn_left As Byte , Encoder2_turn_right As Byte
  124. '#######################################################################################
  125.  
  126. ' Config Timer2
  127. Config Timer2 = Timer , Prescale = 1024 , Clear_timer = 1
  128. Compare2 = 107 '10ms @11MHz/1024
  129.  
  130. ' Settings
  131. Dim 500ms As Byte , Mig As Byte , Timeout As Byte , Mig1 As Byte , Timeout1 As Byte
  132.  
  133. 'Zmienne dla encodera prądu
  134. Dim Prad As Single
  135. Dim Pos2 As Byte
  136. Dim Current_str As String * 10
  137. Dim Temp_str As String * 10
  138.  
  139. 'Zmienne dla encodera napięcia
  140. Dim Napiecie As Single
  141. Dim Pos As Byte
  142. Dim Volt_str As String * 10
  143. Dim Temp_str1 As String * 10
  144.  
  145. '================== Zmienne ADC ADS1110 ====================
  146.  
  147. ' Konfiguracj zmiennych ADS (158) - Pomiar prądu pobieranego I_OUT
  148. Dim Current As Single
  149. Dim Addressw As Byte
  150. Dim Addressr As Byte
  151. Dim Pomiarh As Byte
  152. Dim Pomiarl As Byte
  153. Dim Current_out As String * 10
  154. Dim ADC_current As Integer
  155. Dim I_str As String * 10
  156.  
  157. ' Konfiguracj zmiennych ADS1 (150) - Pomiar napięcia wyjściowego U_OUT
  158. Dim Voltage As Single
  159. Dim Addressw1 As Byte
  160. Dim Addressr1 As Byte
  161. Dim Pomiarh1 As Byte
  162. Dim Pomiarl1 As Byte
  163. Dim Voltage_out As String * 10
  164. Dim ADC_voltage As Integer
  165. Dim U_str As String * 10
  166.  
  167. Dim Moc AS Single
  168. Dim Moc_out As String * 10
  169. Dim Moc_str AS String * 10
  170.  
  171. 'Define the ADC address
  172. Addressw = &B10011110 '158; adres zapizu danych dla [ED7]
  173. Addressr = &B10011111 '159; adres odczytu danych dla [ED7]
  174.  
  175. Addressw1 = &B10010110 '150; adres zapizu danych dla [ED3]
  176. Addressr1 = &B10010111 '151; adres odczytu danych dla [ED3]
  177.  
  178. Declare Sub Measure()
  179. Declare Sub Show_measure()
  180. '============== Zmienne DAC AD5667 =======================
  181.  
  182. 'Implemet each I2c command
  183. Declare Sub Dac_reset()
  184. Declare Sub Dac_ref_on()
  185. Declare Sub Dac_ldac_async()
  186. Declare Sub Dac_power_on()
  187. Declare Sub Dac_set_a(value As Word)
  188. Declare Sub Dac_set_b(value As Word)
  189. Declare Sub Init_dac()
  190.  
  191. 'Define the DAC address
  192. Dim Dac_addr As Byte
  193. Dac_addr = &B00011110 ' shift left 1 for hardware i2c === ADRR podłączone do GND
  194.  
  195. 'zmienne dla przekształcenia prądu I_SET
  196. Dim Amp as Single
  197. Dim Ampi As Single
  198. Dim i_set As Single
  199. 'zmienna dla przekształcenia napięcia U_SET
  200. Dim Vol as Single
  201. Dim Voli As Single
  202. Dim u_set As Single
  203.  
  204. Dim Dachigh As Byte
  205. Dim Daclow As Byte
  206.  
  207. Dim Daccommand(3) As Byte
  208. Dim Length As Byte
  209.  
  210. Dim Ia As Word  'przyjmuje wartość 0 - 65535 wysłana do DAC (channel A)
  211. Dim Ib As Word  'przyjmuje wartość 0 - 65535 wysłana do DAC (channel B)
  212.  
  213. Enable Interrupts
  214.  
  215. Call Dac_reset()
  216. Call Dac_ref_on()
  217. Call Dac_ldac_async()
  218. Call Dac_power_on()
  219.  
  220. ' ======================= Koniec zmiennych DAC ===========================
  221.  
  222. output_led = 1
  223. Waitms 900
  224. output_led = 0
  225. Locate 1 , 1 : Lcd "  DC Power Supply   "   ' Headline
  226. Locate 2 , 1 : Lcd "   0 - 20V / 3A     "
  227. Locate 3 , 1 : Lcd "  ATmega32  16PU    "
  228. Waitms 3000
  229. Buzzer = 1
  230. Waitms 50
  231. Buzzer = 0
  232. cls
  233.  
  234. ' Procedura wyświetlania napięcia U_SET
  235. Sub Show_voltage
  236.  
  237. Temp_str1 = Fusing(napiecie , "#.&&&")
  238. Volt_str = Format(temp_str1 , "      ") 'dwa znaki+kropka+trzy znaki
  239.  
  240. If Mig1 = 1 Then
  241. Select Case Pos
  242. Case 1
  243. Mid(volt_str , 1) = "  " 'wstaw spację w miejscu pos (migaj)
  244. Case 2
  245. Mid(volt_str , 4) = " "
  246. Case 3
  247. Mid(volt_str , 5) = " "
  248. Case 4
  249. Mid(volt_str , 6) = " "
  250. End Select
  251. End If
  252. Locate 1 , 1 : Lcd "SET " ; Volt_str ; Chr(0) ' Wyświetlenie na LCD napięcia ustawionego U_SET
  253. End Sub
  254.  
  255. ' Procedura wyświetlania prądu I_SET
  256. Sub Show_current
  257.  
  258. Temp_str = Fusing(prad , "#.&&&")
  259. Current_str = Format(temp_str , "      ") 'dwa znaki+kropka+trzy znaki
  260.  
  261. If Mig = 1 Then
  262. Select Case Pos2
  263. Case 1
  264. Mid(current_str , 1) = "  " 'wstaw spację w miejscu pos (migaj)
  265. Case 2
  266. Mid(current_str , 4) = " "
  267. Case 3
  268. Mid(current_str , 5) = " "
  269. Case 4
  270. Mid(current_str , 6) = " "
  271. End Select
  272. End If
  273. Locate 1 , 14 : Lcd Current_str ; Chr(1) ' Wyświetlenie na LCD ograniczenia prądowego I_SET
  274. End Sub
  275.  
  276. ' Przekształcenie zmiennych "prad" oraz "napiecie" wyświetlanych na lcd na kod 0 - 65536 i wysłanie do DAC
  277. Sub Set_dac
  278.  
  279. u_set = napiecie / 4
  280. Vol = u_set  'zmienna Vol to napięcie wyrażone w voltach podany z ENCODER1, przyjmuje wartość 0 - 5V
  281. Voli = Vol / 5
  282. Voli = Voli * 65535
  283. Ia = Voli
  284.  
  285. i_set = prad / 20
  286. Amp = i_set  'zmienna Amp to prąd wyrażony w amperach podany z ENCODER2, przyjmuje wartość 0 - 150mV
  287. Ampi = Amp / 5
  288. Ampi = Ampi * 65535
  289. Ib = Ampi
  290.  
  291. Call Dac_set_a(ia) 'U_SET
  292. Call Dac_set_b(ib) 'I_SET
  293. End Sub
  294.  
  295. 'sub zapisuje Eeprom wartością pod podanym adresem
  296. Sub Write_eeprom(byval Adres As Byte , Byval Value As Byte)
  297.     I2cstart
  298.     I2cwbyte Addressw_ee
  299.     I2cwbyte Adres
  300.     I2cwbyte Value
  301.     I2cstop
  302.     Waitms 5
  303. End Sub
  304.  
  305. 'funkcja zwraca wartosć bajtu pod podanym adresem w eepromie
  306. Function Read_eeprom(byval Adres As Byte )as Byte
  307.    I2cstart
  308.    I2cwbyte Addressw_ee
  309.    I2cwbyte Adres
  310.    I2cstart
  311.    I2cwbyte Addressr_ee
  312.    I2crbyte Read_eeprom , Nack
  313.    I2cstop
  314. End Function
  315.  
  316.  ' eeprom 24C02 reading U_SET
  317.         '------------------------------
  318. For N = 1 To 5
  319. Buf2(n) = Read_eeprom(n + 6)
  320. Next
  321. Pos = Pos_ee
  322. If Pos > 4 Then
  323. Pos = 4 : Pos_ee = Pos
  324. Napiecie_ee = 0
  325. end if
  326. ' ODCZYT WAROTOŚCI NAPIĘCIA Z 24C02
  327. For N = 1 To 5
  328. Buf1(n) = Read_eeprom(n + 1)
  329. Next
  330. Napiecie = Napiecie_ee
  331. Call Show_voltage()
  332. Call Set_dac()
  333.  
  334. ' eeprom 24C02 reading I_SET
  335.         '------------------------------
  336.         For N = 1 To 5
  337. Buf4(n) = Read_eeprom(n + 18)
  338. Next
  339. Pos2 = Pos2_ee
  340. If Pos2 > 4 Then
  341. Pos2 = 4 : Pos2_ee = Pos2
  342. Prad_ee = 0
  343. End If
  344. ' ODCZYT WAROTOŚCI PRĄDU Z 24C02
  345. For N = 1 To 5
  346. Buf3(n) = Read_eeprom(n + 12)
  347. Next
  348. Prad = Prad_ee
  349. Call Show_current()
  350. Call Set_dac()
  351.  
  352. relay = 0 ' Przekaźnik zawsze wyłączony po uruchomieniu zasilacza
  353. oc = 0
  354. ov = 0
  355. ' #######################################################################
  356. ' ########################## GŁÓWNA PĘTLA ###############################
  357. ' #######################################################################
  358.  
  359. Do
  360. ot = relay
  361. If relay = 0 Then
  362.    Locate 3 , 18 : Lcd "Off"
  363.                end if
  364. Debounce output_sw , 0 , Out_sw_sub , Sub 'switch output
  365. Debounce ovp_sw , 0 , Ovp_sw_sub , Sub 'switch ovp
  366. 'Obsługa funkcji OVP
  367. ovp = voltage
  368. If ov = 1 Then
  369. If ovp > napiecie Then gosub Overvoltage
  370. End if
  371.  
  372. Debounce ocp_sw , 0 , Ocp_sw_sub , Sub 'switch ocp
  373. 'Obsługa funkcji OCP
  374. ocp = current + 0.001
  375. If oc = 1 Then
  376. If ocp > prad Then gosub Overcurrent
  377. End if
  378.  
  379. '*************************** Obsługa encodera dla prądu
  380. Debounce Enc_sw2 , 0 , Enc_sw2_sub , Sub 'ENCODER I_SET
  381. '##### encoder turns left ######
  382. If 0 < Encoder2_turn_left Then
  383. Decr Encoder2_turn_left
  384.  
  385. If Timeout > 0 Then
  386. Select Case Pos2
  387. Case 1
  388. Prad = Prad - 1.0
  389. Case 2
  390. Prad = Prad - 0.1
  391. Case 3
  392. Prad = Prad - 0.01
  393. Case 4
  394. Prad = Prad - 0.001
  395. End Select
  396.  
  397. If Prad < 0 Then Prad = 0
  398. Mig = 0 : Call Show_current
  399. End If
  400.  
  401. Timeout = Timeout_time 'przedłuzaj/uruchamiaj timeout przy kazdym kliku
  402. Gifr.intf0 = 1
  403. Enable INT0
  404. End If
  405. ' #### encoder turns right ######
  406. If 0 < Encoder2_turn_right Then
  407. Decr Encoder2_turn_right
  408.  
  409. If Timeout > 0 Then
  410. Select Case Pos2
  411. Case 1
  412. Prad = Prad + 1
  413. Case 2
  414. Prad = Prad + 0.1
  415. Case 3
  416. Prad = Prad + 0.01
  417. Case 4
  418. Prad = Prad + 0.001
  419. End Select
  420.  
  421. If Prad > 3.0 Then Prad = 3.0
  422. Mig = 0 : Call Show_current
  423. End If
  424. Timeout = Timeout_time 'przedłuzaj/uruchamiaj timeout przy kazdym kliku
  425. Gifr.intf0 = 1
  426. Enable INT0
  427. End If
  428.  
  429. ' *********************** Obsługa encodera dla napięcia
  430. Debounce Enc_sw1 , 0 , Enc_sw1_sub , Sub 'ENCODER U_SET
  431. '##### encoder turns left ######
  432. If 0 < Encoder1_turn_left Then
  433. Decr Encoder1_turn_left
  434.  
  435. If Timeout1 > 0 Then
  436. Select Case Pos
  437. Case 1
  438. Napiecie = Napiecie - 1.0
  439. Case 2
  440. Napiecie = Napiecie - 0.1
  441. Case 3
  442. Napiecie = Napiecie - 0.01
  443. Case 4
  444. Napiecie = Napiecie - 0.001
  445. End Select
  446. If Napiecie < 0 Then Napiecie = 0
  447. Mig1 = 0 : Call Show_voltage
  448. End If
  449.  
  450. Timeout1 = Timeout_time 'przedłuzaj/uruchamiaj timeout przy kazdym kliku
  451. Gifr.intf1 = 1 'dla Mega8, M32 itp
  452. Enable Int1
  453. End If
  454.  
  455. ' #### encoder turns right ######
  456. If 0 < Encoder1_turn_right Then
  457. Decr Encoder1_turn_right
  458.  
  459. If Timeout1 > 0 Then
  460. Select Case Pos
  461. Case 1
  462. Napiecie = Napiecie + 1
  463. Case 2
  464. Napiecie = Napiecie + 0.1
  465. Case 3
  466. Napiecie = Napiecie + 0.01
  467. Case 4
  468. Napiecie = Napiecie + 0.001
  469. End Select
  470. If Napiecie > 20.0 Then Napiecie = 20.0
  471. Mig1 = 0 : Call Show_voltage
  472. End If
  473.  
  474. Timeout1 = Timeout_time 'przedłuzaj/uruchamiaj timeout przy kazdym kliku
  475. Gifr.intf1 = 1 'dla Mega8, M32 itp
  476. Enable Int1
  477. End If
  478.  
  479. If Tifr.ocf2 = 1 Then '10ms
  480. Tifr.ocf2 = 1
  481. If 500ms < 10 Then  ' 49 było
  482. Incr 500ms
  483. Else
  484. 500ms = 0
  485. If Mig = 0 Then Mig = 1 Else Mig = 0
  486.  
  487. If Timeout > 0 Then
  488. Decr Timeout
  489. If Timeout = 0 Then
  490. 'wyślij do DAC
  491. Mig = 0
  492.  
  493. ' Zapisz prąd i_set do eeprom dopiero po Timeout
  494. Prad_ee = Prad
  495. For N = 1 To 5
  496. Call Write_eeprom(n + 12 , Buf3(n))
  497. Next
  498.  
  499. Call Set_dac
  500. End If
  501.  
  502. Call Show_current()
  503. End If
  504.  
  505. If Mig1 = 0 Then Mig1 = 1 Else Mig1 = 0
  506.  
  507. If Timeout1 > 0 Then
  508. Decr Timeout1
  509. If Timeout1 = 0 Then
  510. 'wyślij do DAC
  511. Mig1 = 0
  512.  
  513. ' Zapisz napięcie u_set do eeprom dopiero po Timeout
  514. Napiecie_ee = Napiecie
  515. For N = 1 To 5
  516. Call Write_eeprom(n + 1 , Buf1(n))
  517. Next
  518.  
  519. Call Set_dac
  520. End If
  521. Call Show_voltage()
  522. End If
  523. End If
  524. End If
  525.  
  526. Call Measure           ' Pomiar napięcia i prądu na wujściu
  527. Call Show_measure      ' Wyświetlenie napięcia i prądu na wyjściu
  528.  
  529. Call Temperature       ' Pomiar temperatury
  530. Call Show_temperature  ' Wyświetlenie zmierzonej temperatury
  531.  
  532. Loop
  533. End
  534.  
  535. ' #################################### KONIEC GŁÓWNEJ PĘTLI ####################################
  536.  
  537. ' Obsługa przycisku Output on/off
  538. Out_sw_sub:
  539. gosub Beep
  540. If output_sw = 0 Then
  541. Toggle relay
  542.      end if
  543.       If relay = 1 Then
  544.    output_led = 1
  545.    Locate 3 , 18 : Lcd " On"
  546.    Else
  547.    If relay = 0 Then
  548.    Locate 3 , 18 : Lcd "Off"
  549.  output_led = 0
  550.   end if
  551.   end if
  552. Return
  553.  
  554. ' Obsługa przycisku Encoder1 U_SET
  555. Enc_sw1_sub:
  556. If Timeout1 > 0 Then
  557. Incr Pos : If Pos > 4 Then Pos = 1
  558.  
  559. Pos_ee = Pos 'Zapisz pozycję do eeprom
  560. For N = 1 To 5
  561. Call Write_eeprom(n + 6 , Buf2(n))
  562. Next
  563.  
  564. End If
  565. Timeout1 = Timeout_time 'przedłuzaj/uruchamiaj timeout przy kazdym kliku
  566. Return
  567.  
  568. ' Obsługa przycisku Encoder2 I_SET
  569. Enc_sw2_sub:
  570. If Timeout > 0 Then
  571. Incr Pos2 : If Pos2 > 4 Then Pos2 = 1
  572.  
  573. Pos2_ee = Pos2 ' Zapisz pozycję do eeprom
  574. For N = 1 To 5
  575. Call Write_eeprom(n + 18 , Buf4(n))
  576. Next
  577.  
  578. End If
  579. Timeout = Timeout_time 'przedłuzaj/uruchamiaj timeout przy kazdym kliku
  580. Return
  581.  
  582. 'obsługa przerwania zewnetrznego z encoder2
  583. Encoder2_isr:
  584.    $asm
  585.       PUSH R23
  586.       PUSH R24
  587.       PUSH R26
  588.       PUSH R27
  589.       !in R24, sreg
  590.       PUSH  R24
  591.    $end Asm
  592.  
  593.    Disable INT0
  594.  
  595.    If Encoder2_a = 1 Then
  596.       Incr Encoder2_turn_right
  597.    Else
  598.       Incr Encoder2_turn_left
  599.    End If
  600.  
  601. 'Tuned with NoSave Tool
  602.    $asm
  603.       POP  R24
  604.       !out sreg, r24
  605.       POP R27
  606.       POP R26
  607.       POP R24
  608.       POP R23
  609.    $end Asm
  610.  
  611. Return
  612.  
  613. 'obsługa przerwania zewnetrznego z encoder1
  614. Encoder1_isr:
  615.  
  616.    $asm
  617.       PUSH R23
  618.       PUSH R24
  619.       PUSH R26
  620.       PUSH R27
  621.       !in R24, sreg
  622.       PUSH  R24
  623.    $end Asm
  624.  
  625.    Disable Int1
  626.  
  627.    If Encoder1_a = 1 Then
  628.       Incr Encoder1_turn_right
  629.    Else
  630.       Incr Encoder1_turn_left
  631.    End If
  632.  
  633. 'Tuned with NoSave Tool
  634.  
  635.    $asm
  636.       POP  R24
  637.       !out sreg, r24
  638.       POP R27
  639.       POP R26
  640.       POP R24
  641.       POP R23
  642.    $end Asm
  643.  
  644. Return
  645.  
  646. ' ================== OBSŁUGA DAC =====================
  647.  
  648. 'Reset DAC
  649. Sub Dac_reset
  650. ' [ Slave Address ] [ Command Data Byte ] [ Most Significant Data Byte ] [ Least Significant Data Byte ]
  651. ' [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]
  652. ' [ 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
  653. Length = 3
  654. Daccommand(1) = &B00101000 ' Command Byte
  655. Daccommand(2) = &B00000000 ' MSB
  656. Daccommand(3) = &B00000000 ' LSB
  657. I2csend Dac_addr , Daccommand(1) , Length
  658. End Sub
  659.  
  660. 'Internal voltage reference off
  661. Sub Dac_ref_on()
  662. ' [ Slave Address ] [ Command Data Byte ] [ Most Significant Data Byte ] [ Least Significant Data Byte ]
  663. ' [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]
  664. ' [ 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
  665. Length = 3
  666. Daccommand(1) = &B00000000 ' Command Byte (00111000)internal ref off musi być
  667. Daccommand(2) = &B00000000 ' MSB
  668. Daccommand(3) = &B00000001 ' LSB
  669. I2csend Dac_addr , Daccommand(1) , Length
  670. End Sub
  671.  
  672. 'LDAC register set for asynchronous mode
  673. Sub Dac_ldac_async()
  674. ' [ Slave Address ] [ Command Data Byte ] [ Most Significant Data Byte ] [ Least Significant Data Byte ]
  675. ' [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]
  676. ' [ 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
  677. Length = 3
  678. Daccommand(1) = &B00110000 ' Command Byte
  679. Daccommand(2) = &B00000000 ' MSB
  680. Daccommand(3) = &B00000011 ' LSB
  681. I2csend Dac_addr , Daccommand(1) , Length
  682. End Sub
  683.  
  684. 'Power up both DAC channels
  685. Sub Dac_power_on()
  686. ' [ Slave Address ] [ Command Data Byte ] [ Most Significant Data Byte ] [ Least Significant Data Byte ]
  687. ' [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]
  688. ' [ 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
  689. Length = 3
  690. Daccommand(1) = &B00100000 ' Command Byte
  691. Daccommand(2) = &B00000000 ' MSB
  692. Daccommand(3) = &B00000011 ' LSB
  693. I2csend Dac_addr , Daccommand(1) , Length
  694. End Sub
  695.  
  696. 'Set DAC channel A
  697. Sub Dac_set_a(value As Word)
  698. ' [ Slave Address ] [ Command Data Byte ] [ Most Significant Data Byte ] [ Least Significant Data Byte ]
  699. ' [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]
  700. ' [ 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
  701. Length = 3
  702. Dachigh = High(value)
  703. Daclow = Low(value)
  704. Daccommand(1) = &B00011000 ' Command Byte
  705. Daccommand(2) = Dachigh ' MSB
  706. Daccommand(3) = Daclow ' LSB
  707. I2csend Dac_addr , Daccommand(1) , Length
  708. End Sub
  709.  
  710. 'Set DAC channel B
  711. Sub Dac_set_b(value As Word)
  712. ' [ Slave Address ] [ Command Data Byte ] [ Most Significant Data Byte ] [ Least Significant Data Byte ]
  713. ' [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]
  714. ' [ 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
  715. Length = 3
  716. Dachigh = High(value)
  717. Daclow = Low(value)
  718. Daccommand(1) = &B00011001 ' Command Byte
  719. Daccommand(2) = Dachigh ' MSB
  720. Daccommand(3) = Daclow ' LSB
  721. I2csend Dac_addr , Daccommand(1) , Length
  722. End Sub
  723.  
  724. ' ==================== KONIEC OBSŁUGI DAC ================================
  725.  
  726. ' ==================== OBSŁUGA ADC =======================================
  727. ' Pomiar U_OUT / I_OUT
  728. Sub Measure
  729.  
  730. ' I_OUT
  731. I2cstart
  732. I2cwbyte Addressr      'Adres Do Odczytu
  733. I2crbyte Pomiarh , Ack 'Odczyt Pomiaru
  734. I2crbyte Pomiarl , Nack
  735. I2cstop 'Bit Stopu
  736.  
  737. Const K = 2.048 / 32768
  738. ADC_current = Makeint(Pomiarl,Pomiarh)
  739. Current = ADC_current * K
  740. Current = Current + 0.001 ' Kalibracja
  741.  
  742. ' U_OUT
  743. I2cstart
  744. I2cwbyte Addressr1      'Adres Do Odczytu
  745. I2crbyte Pomiarh1 , Ack 'Odczyt Pomiaru
  746. I2crbyte Pomiarl1 , Nack
  747. I2cstop  'Bit Stopu
  748.  
  749. Const K = 2.048 / 32768
  750. ADC_voltage = Makeint(Pomiarl1,Pomiarh1)
  751. Voltage = ADC_voltage * K
  752. Voltage = Voltage * 10     ' Współczynnik K dla dzielnika rezystorowego
  753. Voltage = Voltage - 0.0250 ' Kalibracja
  754.  
  755. ' P_OUT
  756. Moc = voltage * current
  757.  
  758. End Sub
  759.  
  760. ' Wyświetlenie pomiarów U_OUT/I_OUT/P_OUT
  761. Sub Show_measure
  762.  
  763. Voltage_out = Fusing(voltage , "#.&&&")
  764. U_str = Format(voltage_out , "      ")
  765. Locate 2 , 1 : Lcd "OUT " ; U_str ; Chr(0)
  766.  
  767. Current_out = Fusing(current , "#.&&&")
  768. I_str = Format(current_out , "      ")
  769. Locate 2 , 14 : Lcd I_str ; Chr(1)
  770.  
  771. Moc_out = Fusing(moc , "#.&&&")
  772. Moc_str = Format(Moc_out , "      ")
  773. Locate 3 , 1 : Lcd Moc_str ; Chr(2)
  774.  
  775. If CC = 0 Then ' constant voltage
  776. Locate 3 , 10 : LCD "CC"
  777.   end if
  778. If CV = 0 Then ' constant current
  779. Locate 3 , 10 : LCD "CV"
  780. end if
  781.  
  782. End Sub
  783. ' ============================= KONIEC OBSŁUGI ADC ========================
  784.  
  785. ' Pomiar temperatury DS18B20
  786. Sub Temperature
  787. 1wreset
  788. 1wwrite &HCC
  789. 1wwrite &H44
  790. 1wverify Ds1(1)'1wreset i 1wwrite &H55 niepotrzebne bo 1wverify samo to przeprowadza
  791. 1wwrite &HBE
  792. Wew(1) = 1wread(9)
  793.  
  794. Ts = Makeint(wew(1) , Wew(2)) ' Obliczenie wartości teperatury
  795. Ts = Ts * 10
  796. Ts = Ts / 16
  797. T_heatsink = Ts / 10 ' obliczenie temperatury dla funkcji OTP (Over-temperature protection)
  798.  
  799. Temperatura_str = Str(ts)
  800. Temperatura_str = Format(temperatura_str , "0.0")
  801.  
  802. If T_heatsink > 30 Then ' Jeżeli temperatura głównego radiatora przekroczy 55 stC, to skok do procedury OTP
  803. If ot = 1 Then gosub Overtemperature
  804.         end if
  805. If ot = 1 Then
  806. If Err = 1 Then gosub Overtemperature ' Jeżeli błąd czujnika DS18B20 to skok do procedury OTP
  807. end if
  808. End Sub
  809.  
  810. ' Wyświetlenie temperatury DS18B20
  811. Sub Show_temperature
  812. If Err = 0 Then
  813. Locate 4 , 15 : Lcd Temperatura_str ; Chr(3) ; "C"
  814. else
  815. Locate 4 , 15 : Lcd Error
  816. End if
  817. End Sub
  818.  
  819. Beep:
  820. buzzer = 1
  821. waitms 50
  822. buzzer = 0
  823. Return
  824.  
  825. ' Obsługa przycisku OVP
  826. Ovp_sw_sub:
  827. gosub Beep
  828. If ovp_sw = 0 Then
  829. Toggle ov
  830.      end if
  831.       If ov = 1 Then
  832.    Locate 4 , 1 : Lcd "OVP"
  833.    Else
  834.    If ov = 0 Then
  835.    Locate 4 , 1 : Lcd "   "
  836.   end if
  837.   end if
  838. Return
  839.  
  840. ' Obsługa przycisku OCP
  841. Ocp_sw_sub:
  842. gosub Beep
  843. If ocp_sw = 0 Then
  844. Toggle oc
  845.      end if
  846.       If oc = 1 Then
  847.    Locate 4 , 5 : Lcd "OCP"
  848.    Else
  849.    If oc = 0 Then
  850.    Locate 4 , 5 : Lcd "   "
  851.   end if
  852.   end if
  853. Return
  854.  
  855. ' ##########  Procedura ochrony OVP  ##########
  856. Overvoltage:
  857. relay = 0  'Wyłączenie przekaźnika
  858. output_led = 0
  859. ' Sygnalizacja dźwiękowa przeciążenia
  860. Pulses = 120   ' ustalenie długości tonu dźwiękowego
  861. Periods = 2200 ' ustawienie barwy tonu
  862. Sound buzzer , Pulses , Periods ' dźwięk ostrzegawczy
  863. Do
  864. relay = 0
  865. output_led = 0
  866. ov = 0
  867. Locate 1 , 1 : Lcd Frame_long
  868. Locate 2 , 1 : Lcd "-  OVP   Out: Off  -"
  869. Locate 3 , 1 : Lcd Frame_long
  870. Locate 4 , 1 : Lcd Info
  871. If output_sw = 0 Then
  872. cls
  873. waitms 20
  874. If output_sw = 0 Then
  875. relay = 0 : Mig = 0 : Mig1 = 0
  876. Call Show_voltage
  877. Call Show_current
  878. return
  879. end if : end if
  880. Loop
  881.  
  882. ' ##########  Procedura ochrony OCP  ##########
  883. Overcurrent:
  884. relay = 0  'Wyłączenie przekaźnika
  885. output_led = 0
  886. ' Sygnalizacja dźwiękowa przeciążenia
  887. Pulses = 120   ' ustalenie długości tonu dźwiękowego
  888. Periods = 2200 ' ustawienie barwy tonu
  889. Sound buzzer , Pulses , Periods ' dźwięk ostrzegawczy
  890. Do
  891. relay = 0
  892. output_led = 0
  893. oc = 0
  894. Locate 1 , 1 : Lcd Frame_long
  895. Locate 2 , 1 : Lcd "-  OCP   Out: Off  -"
  896. Locate 3 , 1 : Lcd Frame_long
  897. Locate 4 , 1 : Lcd Info
  898. If output_sw = 0 Then
  899. cls
  900. waitms 20
  901. If output_sw = 0 Then
  902. relay = 0 : Mig = 0 : Mig1 = 0
  903. Call Show_voltage
  904. Call Show_current
  905. return
  906. end if : end if
  907. Loop
  908.  
  909. ' ##########  Procedura ochrony OTP  ##########
  910. Overtemperature:
  911. relay = 0  'Wyłączenie przekaźnika
  912. output_led = 0
  913. ' Sygnalizacja dźwiękowa przeciążenia
  914. Pulses = 120   ' ustalenie długości tonu dźwiękowego
  915. Periods = 2200 ' ustawienie barwy tonu
  916. Sound buzzer , Pulses , Periods ' dźwięk ostrzegawczy
  917. Do
  918. relay = 0
  919. output_led = 0
  920. ot = 0
  921. Locate 1 , 1 : Lcd Frame_long
  922. Locate 2 , 1 : Lcd "-  OTP   Out: Off  -"
  923. Locate 3 , 1 : Lcd Frame_long
  924. Locate 4 , 1 : Lcd Info
  925. If output_sw = 0 Then
  926. cls
  927. waitms 20
  928. If output_sw = 0 Then
  929. relay = 0 : Mig = 0 : Mig1 = 0
  930. Call Show_voltage
  931. Call Show_current
  932. return
  933. end if : end if
  934. Loop
A tutaj dla atmega644p:
  1. ' ##############################
  2. ' ####   DC POWER SUPPLY    ####
  3. ' ####       M644P          ####
  4. ' ##############################
  5.  
  6. $regfile = "m644pdef.dat"
  7. $crystal = 11059200
  8.  
  9. $hwstack = 64
  10. $swstack = 64
  11. $framesize = 64
  12.  
  13. Const Timeout_time = 8 'x500ms
  14. Config Submode = New
  15.  
  16. ' config LCD 2X16
  17. Config Lcdpin = Pin , Rs = Porta.0 , E = Porta.1 , Db4 = Porta.2 , Db5 = Porta.3 , Db6 = Porta.4 , Db7 = Porta.5
  18. Config Lcd = 20x4
  19. Cursor Off
  20. Cls
  21.  
  22. Const Error = " ERROR"
  23. Const Info = "Press  switch On/Off"
  24. Const Frame_long = "--------------------"
  25.  
  26. 'Konfiguracja 1-WIRE dla DS18B20
  27. Config 1wire = Portc.6
  28.  
  29. ' Zmienne pomiar temperatury
  30. Dim Ds1(8) As Byte
  31. Dim Temperatura As Byte
  32. Dim Temperatura_str As String * 5
  33. Dim Ts As Integer
  34. Dim Wew(9) As Byte
  35. Dim T_heatsink As Integer
  36.  
  37.  ' ID Ds1 (HEX) 28E731CB010000FD czujnik temperatury głównego radiatora
  38. Ds1(1) = &H28
  39. Ds1(2) = &HE7
  40. Ds1(3) = &H31
  41. Ds1(4) = &HCB
  42. Ds1(5) = &H01
  43. Ds1(6) = &H00
  44. Ds1(7) = &H00
  45. Ds1(8) = &HFD
  46.  
  47. Declare Sub Temperature()
  48. Declare Sub Show_temperature()
  49.  
  50. ' Konfiguracja i/o
  51. Config POrTC.3 = Input : PORTC.3 = 1 : output_sw Alias PINC.3 ' switch OUTPUT ON/OFF
  52. Config Portc.5 = Output : Portc.5 = 0 : relay Alias Portc.5 ' Przekaźnik OUTPUT ON/OFF
  53. Config PortC.4 = Output : PortC.4 = 0 : output_led Alias PortC.4 'Led OUTPUT ON/0FF
  54. Config PortD.4 = Output : PortD.4 = 0 : buzzer Alias PortD.4 'Buzzer
  55. Config POrTA.7 = Input : PORTA.7 = 1 : cv Alias PINA.7 ' constant voltage
  56. Config POrTC.7 = Input : PORTC.7 = 1 : cc Alias PINC.7 ' constant current
  57. Config POrTB.0 = Input : PORTB.0 = 1 : ovp_sw Alias PINB.0 ' switch OVP
  58. Config POrTB.1 = Input : PORTB.1 = 1 : ocp_sw Alias PINB.1 ' switch OCP
  59. Config POrTB.3 = Input : PORTB.3 = 1 : sw1 Alias PINB.3 ' switch 1
  60. Config POrTB.2 = Input : PORTB.2 = 1 : sw2 Alias PINB.2 ' switch 2
  61. Config POrTB.4 = Input : PORTB.4 = 1 : sw3 Alias PINB.4 ' switch 3
  62.  
  63. Dim ovp As Single
  64. Dim ocp As Single
  65. Dim ov As Bit ' zmienna pomocnicza dla OVP
  66. Dim oc As Bit ' zmienna pomocnicza dla OCP
  67. Dim ot As Bit ' zmienna pomocnicza dla OTP
  68. Dim S As Bit
  69. ov = 0
  70. oc = 0
  71. ot = 0
  72. S = 0
  73.  
  74. Dim Pulses As Word  'Zmienna długości dźwięku
  75. Dim Periods As Word ' Zmienna barwy dźwięku
  76.  
  77. ' Symbole na LCD
  78. Deflcdchar 0,17,17,17,10,4,32,32,32' (volt)
  79. Deflcdchar 1,14,17,17,31,17,32,32,32' (amper)
  80. Deflcdchar 2,17,17,21,21,10,32,32,32' (wat)
  81. Deflcdchar 3,14,17,17,14,32,32,32,32' (stopień celcjusza)
  82.  
  83. ' Zmienne do zapisu danych w eeprom 24C02
  84. Dim N As Byte
  85. Dim Napiecie_ee As Single
  86. Dim Buf1(20) As Byte At Napiecie_ee Overlay
  87. Dim Pos_ee As Single
  88. Dim Buf2(20) As Byte At Pos_ee Overlay
  89. Dim Prad_ee As Single
  90. Dim Buf3(20) As Byte At Prad_ee Overlay
  91. Dim Pos2_ee As Single
  92. Dim Buf4(20) As Byte At Pos2_ee Overlay
  93.  
  94. ' Define the 24C02 EEPROM address
  95. Const Addressw_ee = 168
  96. Const Addressr_ee = 169
  97.  
  98. ' Konfiguracja I2C
  99. $lib "i2c_twi.lbx"
  100. Config Scl = Portc.0
  101. Config Sda = Portc.1
  102. I2cinit
  103. Config Twi = 100000
  104.  
  105. '#######################   Config for encoders  #########################################
  106.  
  107. ' ENCODER U_SET
  108. Config PortD.5 = Input : PortD.5 = 1 : Encoder1_a Alias PinD.5      'ENKODER1A
  109. Config Portd.3 = Input : Portd.3 = 1 : Encoder1_b Alias Pind.3      'ENKODER1B, INT1
  110. Config PortD.7 = Input : PortD.7 = 1 : Enc_sw1 Alias PinD.7         ' Przycisk Enkoder1
  111.  
  112. ' ENCODER I_SET
  113. Config PortD.6 = Input : PortD.6 = 1 : Encoder2_a Alias PinD.6      'ENKODER2A
  114. Config Portd.2 = Input : Portd.2 = 1 : Encoder2_b Alias Pind.2      'ENKODER2B, INT0
  115. Config PortC.2 = Input : PortC.2 = 1 : Enc_sw2 Alias PinC.2         ' Przycisk Enkoder2
  116.  
  117. Config Int1 = Rising 'przerwanie  generować będzie rosnące zbocze
  118. Enable Int1 : On Int1 Encoder1_isr Nosave
  119.  
  120. Config Int0 = Rising 'przerwanie  generować będzie rosnące zbocze
  121. Enable Int0 : On Int0 Encoder2_isr Nosave
  122.  
  123. Dim Encoder1_turn_left As Byte , Encoder1_turn_right As Byte
  124. Dim Encoder2_turn_left As Byte , Encoder2_turn_right As Byte
  125. '#######################################################################################
  126.  
  127.  'Config Timer2
  128. Config Timer2 = Timer , Prescale = 1024 , Clear_timer = 1
  129. Compare2a = 107 '10ms @11MHz/1024
  130.  
  131. ' Settings
  132. Dim 500ms As Byte , Mig As Byte , Timeout As Byte , Mig1 As Byte , Timeout1 As Byte
  133.  
  134. 'Zmienne dla encodera prądu
  135. Dim Prad As Single
  136. Dim Pos2 As Byte
  137. Dim Current_str As String * 10
  138. Dim Temp_str As String * 10
  139.  
  140. 'Zmienne dla encodera napięcia
  141. Dim Napiecie As Single
  142. Dim Pos As Byte
  143. Dim Volt_str As String * 10
  144. Dim Temp_str1 As String * 10
  145.  
  146. '================== Zmienne ADC ADS1110 ====================
  147.  
  148. ' Konfiguracj zmiennych ADS (158) - Pomiar prądu pobieranego I_OUT
  149. Dim Current As Single
  150. Dim Addressw As Byte
  151. Dim Addressr As Byte
  152. Dim Pomiarh As Byte
  153. Dim Pomiarl As Byte
  154. Dim Current_out As String * 10
  155. Dim ADC_current As Integer
  156. Dim I_str As String * 10
  157.  
  158. ' Konfiguracj zmiennych ADS1 (150) - Pomiar napięcia wyjściowego U_OUT
  159. Dim Voltage As Single
  160. Dim Addressw1 As Byte
  161. Dim Addressr1 As Byte
  162. Dim Pomiarh1 As Byte
  163. Dim Pomiarl1 As Byte
  164. Dim Voltage_out As String * 10
  165. Dim ADC_voltage As Integer
  166. Dim U_str As String * 10
  167.  
  168. Dim Moc AS Single
  169. Dim Moc_out As String * 10
  170. Dim Moc_str AS String * 10
  171.  
  172. 'Define the ADC address
  173. Addressw = &B10011110 '158; adres zapizu danych dla [ED7]
  174. Addressr = &B10011111 '159; adres odczytu danych dla [ED7]
  175.  
  176. Addressw1 = &B10010110 '150; adres zapizu danych dla [ED3]
  177. Addressr1 = &B10010111 '151; adres odczytu danych dla [ED3]
  178.  
  179. Declare Sub Measure()
  180. Declare Sub Show_measure()
  181. '============== Zmienne DAC AD5667 =======================
  182.  
  183. 'Implemet each I2c command
  184. Declare Sub Dac_reset()
  185. Declare Sub Dac_ref_on()
  186. Declare Sub Dac_ldac_async()
  187. Declare Sub Dac_power_on()
  188. Declare Sub Dac_set_a(value As Word)
  189. Declare Sub Dac_set_b(value As Word)
  190. Declare Sub Init_dac()
  191.  
  192. 'Define the DAC address
  193. Dim Dac_addr As Byte
  194. Dac_addr = &B00011110 ' shift left 1 for hardware i2c === ADRR podłączone do GND
  195.  
  196. 'zmienne dla przekształcenia prądu I_SET
  197. Dim Amp as Single
  198. Dim Ampi As Single
  199. Dim i_set As Single
  200. 'zmienna dla przekształcenia napięcia U_SET
  201. Dim Vol as Single
  202. Dim Voli As Single
  203. Dim u_set As Single
  204.  
  205. Dim Dachigh As Byte
  206. Dim Daclow As Byte
  207.  
  208. Dim Daccommand(3) As Byte
  209. Dim Length As Byte
  210.  
  211. Dim Ia As Word  'przyjmuje wartość 0 - 65535 wysłana do DAC (channel A)
  212. Dim Ib As Word  'przyjmuje wartość 0 - 65535 wysłana do DAC (channel B)
  213.  
  214. Enable Interrupts
  215.  
  216. Call Dac_reset()
  217. Call Dac_ref_on()
  218. Call Dac_ldac_async()
  219. Call Dac_power_on()
  220.  
  221. ' ======================= Koniec zmiennych DAC ===========================
  222.  
  223. output_led = 1
  224. Waitms 900
  225. output_led = 0
  226. Locate 1 , 1 : Lcd "  DC Power Supply   "   ' Headline
  227. Locate 2 , 1 : Lcd "   0 - 20V / 3A     "
  228. Locate 3 , 1 : Lcd "   ATmega 644PA     "
  229. Waitms 3000
  230. Buzzer = 1
  231. Waitms 50
  232. Buzzer = 0
  233. cls
  234.  
  235. ' Procedura wyświetlania napięcia U_SET
  236. Sub Show_voltage
  237.  
  238. Temp_str1 = Fusing(napiecie , "#.&&&")
  239. Volt_str = Format(temp_str1 , "      ") 'dwa znaki+kropka+trzy znaki
  240.  
  241. If Mig1 = 1 Then
  242. Select Case Pos
  243. Case 1
  244. Mid(volt_str , 1) = "  " 'wstaw spację w miejscu pos (migaj)
  245. Case 2
  246. Mid(volt_str , 4) = " "
  247. Case 3
  248. Mid(volt_str , 5) = " "
  249. Case 4
  250. Mid(volt_str , 6) = " "
  251. End Select
  252. End If
  253. Locate 1 , 1 : Lcd "SET " ; Volt_str ; Chr(0) ' Wyświetlenie na LCD napięcia ustawionego U_SET
  254. End Sub
  255.  
  256. ' Procedura wyświetlania prądu I_SET
  257. Sub Show_current
  258.  
  259. Temp_str = Fusing(prad , "#.&&&")
  260. Current_str = Format(temp_str , "      ") 'dwa znaki+kropka+trzy znaki
  261.  
  262. If Mig = 1 Then
  263. Select Case Pos2
  264. Case 1
  265. Mid(current_str , 1) = "  " 'wstaw spację w miejscu pos (migaj)
  266. Case 2
  267. Mid(current_str , 4) = " "
  268. Case 3
  269. Mid(current_str , 5) = " "
  270. Case 4
  271. Mid(current_str , 6) = " "
  272. End Select
  273. End If
  274. Locate 1 , 14 : Lcd Current_str ; Chr(1) ' Wyświetlenie na LCD ograniczenia prądowego I_SET
  275. End Sub
  276.  
  277. ' Przekształcenie zmiennych "prad" oraz "napiecie" wyświetlanych na lcd na kod 0 - 65536 i wysłanie do DAC
  278. Sub Set_dac
  279.  
  280. u_set = napiecie / 4
  281. Vol = u_set  'zmienna Vol to napięcie wyrażone w voltach podany z ENCODER1, przyjmuje wartość 0 - 5V
  282. Voli = Vol / 5
  283. Voli = Voli * 65535
  284. Ia = Voli
  285.  
  286. i_set = prad / 20
  287. Amp = i_set  'zmienna Amp to prąd wyrażony w amperach podany z ENCODER2, przyjmuje wartość 0 - 150mV
  288. Ampi = Amp / 5
  289. Ampi = Ampi * 65535
  290. Ib = Ampi
  291.  
  292. Call Dac_set_a(ia) 'U_SET
  293. Call Dac_set_b(ib) 'I_SET
  294. End Sub
  295.  
  296. 'sub zapisuje Eeprom wartością pod podanym adresem
  297. Sub Write_eeprom(byval Adres As Byte , Byval Value As Byte)
  298.     I2cstart
  299.     I2cwbyte Addressw_ee
  300.     I2cwbyte Adres
  301.     I2cwbyte Value
  302.     I2cstop
  303.     Waitms 5
  304. End Sub
  305.  
  306. 'funkcja zwraca wartosć bajtu pod podanym adresem w eepromie
  307. Function Read_eeprom(byval Adres As Byte )as Byte
  308.    I2cstart
  309.    I2cwbyte Addressw_ee
  310.    I2cwbyte Adres
  311.    I2cstart
  312.    I2cwbyte Addressr_ee
  313.    I2crbyte Read_eeprom , Nack
  314.    I2cstop
  315. End Function
  316.  
  317.  ' eeprom 24C02 reading U_SET
  318.         '------------------------------
  319. For N = 1 To 5
  320. Buf2(n) = Read_eeprom(n + 6)
  321. Next
  322. Pos = Pos_ee
  323. If Pos > 4 Then
  324. Pos = 4 : Pos_ee = Pos
  325. Napiecie_ee = 0
  326. end if
  327. ' ODCZYT WAROTOŚCI NAPIĘCIA Z 24C02
  328. For N = 1 To 5
  329. Buf1(n) = Read_eeprom(n + 1)
  330. Next
  331. Napiecie = Napiecie_ee
  332. Call Show_voltage()
  333. Call Set_dac()
  334.  
  335. ' eeprom 24C02 reading I_SET
  336.         '------------------------------
  337.         For N = 1 To 5
  338. Buf4(n) = Read_eeprom(n + 18)
  339. Next
  340. Pos2 = Pos2_ee
  341. If Pos2 > 4 Then
  342. Pos2 = 4 : Pos2_ee = Pos2
  343. Prad_ee = 0
  344. End If
  345. ' ODCZYT WAROTOŚCI PRĄDU Z 24C02
  346. For N = 1 To 5
  347. Buf3(n) = Read_eeprom(n + 12)
  348. Next
  349. Prad = Prad_ee
  350. Call Show_current()
  351. Call Set_dac()
  352.  
  353. relay = 0 ' Przekaźnik zawsze wyłączony po uruchomieniu zasilacza
  354. oc = 0
  355. ov = 0
  356. ' #######################################################################
  357. ' ########################## GŁÓWNA PĘTLA ###############################
  358. ' #######################################################################
  359.  
  360. Do
  361. ot = relay
  362. If relay = 0 Then
  363.    Locate 3 , 18 : Lcd "Off"
  364.                end if
  365. Debounce output_sw , 0 , Out_sw_sub , Sub 'switch output
  366. Debounce ovp_sw , 0 , Ovp_sw_sub , Sub 'switch ovp
  367. 'Obsługa funkcji OVP
  368. ovp = voltage
  369. If ov = 1 Then
  370. If ovp > napiecie Then gosub Overvoltage
  371. End if
  372.  
  373. Debounce ocp_sw , 0 , Ocp_sw_sub , Sub 'switch ocp
  374. 'Obsługa funkcji OCP
  375. ocp = current + 0.001
  376. If oc = 1 Then
  377. If ocp > prad Then gosub Overcurrent
  378. End if
  379.  
  380. '*************************** Obsługa encodera dla prądu
  381. Debounce Enc_sw2 , 0 , Enc_sw2_sub , Sub 'ENCODER I_SET
  382. '##### encoder turns left ######
  383. If 0 < Encoder2_turn_left Then
  384. Decr Encoder2_turn_left
  385.  
  386. If Timeout > 0 Then
  387. Select Case Pos2
  388. Case 1
  389. Prad = Prad - 1.0
  390. Case 2
  391. Prad = Prad - 0.1
  392. Case 3
  393. Prad = Prad - 0.01
  394. Case 4
  395. Prad = Prad - 0.001
  396. End Select
  397.  
  398. If Prad < 0 Then Prad = 0
  399. Mig = 0 : Call Show_current
  400. End If
  401.  
  402. Timeout = Timeout_time 'przedłuzaj/uruchamiaj timeout przy kazdym kliku
  403. Eifr.intf0 = 1
  404. Enable INT0
  405. End If
  406. ' #### encoder turns right ######
  407. If 0 < Encoder2_turn_right Then
  408. Decr Encoder2_turn_right
  409.  
  410. If Timeout > 0 Then
  411. Select Case Pos2
  412. Case 1
  413. Prad = Prad + 1
  414. Case 2
  415. Prad = Prad + 0.1
  416. Case 3
  417. Prad = Prad + 0.01
  418. Case 4
  419. Prad = Prad + 0.001
  420. End Select
  421.  
  422. If Prad > 3.0 Then Prad = 3.0
  423. Mig = 0 : Call Show_current
  424. End If
  425. Timeout = Timeout_time 'przedłuzaj/uruchamiaj timeout przy kazdym kliku
  426. Eifr.intf0 = 1
  427. Enable INT0
  428. End If
  429.  
  430. ' *********************** Obsługa encodera dla napięcia
  431. Debounce Enc_sw1 , 0 , Enc_sw1_sub , Sub 'ENCODER U_SET
  432. '##### encoder turns left ######
  433. If 0 < Encoder1_turn_left Then
  434. Decr Encoder1_turn_left
  435.  
  436. If Timeout1 > 0 Then
  437. Select Case Pos
  438. Case 1
  439. Napiecie = Napiecie - 1.0
  440. Case 2
  441. Napiecie = Napiecie - 0.1
  442. Case 3
  443. Napiecie = Napiecie - 0.01
  444. Case 4
  445. Napiecie = Napiecie - 0.001
  446. End Select
  447. If Napiecie < 0 Then Napiecie = 0
  448. Mig1 = 0 : Call Show_voltage
  449. End If
  450.  
  451. Timeout1 = Timeout_time 'przedłuzaj/uruchamiaj timeout przy kazdym kliku
  452. Eifr.intf1 = 1 'dla Mega8, M32 itp
  453. Enable Int1
  454. End If
  455.  
  456. ' #### encoder turns right ######
  457. If 0 < Encoder1_turn_right Then
  458. Decr Encoder1_turn_right
  459.  
  460. If Timeout1 > 0 Then
  461. Select Case Pos
  462. Case 1
  463. Napiecie = Napiecie + 1
  464. Case 2
  465. Napiecie = Napiecie + 0.1
  466. Case 3
  467. Napiecie = Napiecie + 0.01
  468. Case 4
  469. Napiecie = Napiecie + 0.001
  470. End Select
  471. If Napiecie > 20.0 Then Napiecie = 20.0
  472. Mig1 = 0 : Call Show_voltage
  473. End If
  474.  
  475. Timeout1 = Timeout_time 'przedłuzaj/uruchamiaj timeout przy kazdym kliku
  476. Eifr.intf1 = 1 'dla Mega8, M32 itp
  477. Enable Int1
  478. End If
  479.  
  480. If Tifr2.ocf2A = 1 Then '10ms
  481. Tifr2.ocf2A = 1
  482. If 500ms < 10 Then  ' 49 było
  483. Incr 500ms
  484. Else
  485. 500ms = 0
  486. If Mig = 0 Then Mig = 1 Else Mig = 0
  487.  
  488. If Timeout > 0 Then
  489. Decr Timeout
  490. If Timeout = 0 Then
  491. 'wyślij do DAC
  492. Mig = 0
  493.  
  494. ' Zapisz prąd i_set do eeprom dopiero po Timeout
  495. Prad_ee = Prad
  496. For N = 1 To 5
  497. Call Write_eeprom(n + 12 , Buf3(n))
  498. Next
  499.  
  500. Call Set_dac
  501. End If
  502.  
  503. Call Show_current()
  504. End If
  505.  
  506. If Mig1 = 0 Then Mig1 = 1 Else Mig1 = 0
  507.  
  508. If Timeout1 > 0 Then
  509. Decr Timeout1
  510. If Timeout1 = 0 Then
  511. 'wyślij do DAC
  512. Mig1 = 0
  513.  
  514. ' Zapisz napięcie u_set do eeprom dopiero po Timeout
  515. Napiecie_ee = Napiecie
  516. For N = 1 To 5
  517. Call Write_eeprom(n + 1 , Buf1(n))
  518. Next
  519.  
  520. Call Set_dac
  521. End If
  522. Call Show_voltage()
  523. End If
  524. End If
  525. End If
  526.  
  527. Call Measure           ' Pomiar napięcia i prądu na wujściu
  528. Call Show_measure      ' Wyświetlenie napięcia i prądu na wyjściu
  529.  
  530. Call Temperature       ' Pomiar temperatury
  531. Call Show_temperature  ' Wyświetlenie zmierzonej temperatury
  532.  
  533. Loop
  534. End
  535.  
  536. ' #################################### KONIEC GŁÓWNEJ PĘTLI ####################################
  537.  
  538. ' Obsługa przycisku Output on/off
  539. Out_sw_sub:
  540. gosub Beep
  541. If output_sw = 0 Then
  542. Toggle relay
  543.      end if
  544.       If relay = 1 Then
  545.    output_led = 1
  546.    Locate 3 , 18 : Lcd " On"
  547.    Else
  548.    If relay = 0 Then
  549.    Locate 3 , 18 : Lcd "Off"
  550.  output_led = 0
  551.   end if
  552.   end if
  553. Return
  554.  
  555. ' Obsługa przycisku Encoder1 U_SET
  556. Enc_sw1_sub:
  557. If Timeout1 > 0 Then
  558. Incr Pos : If Pos > 4 Then Pos = 1
  559.  
  560. Pos_ee = Pos 'Zapisz pozycję do eeprom
  561. For N = 1 To 5
  562. Call Write_eeprom(n + 6 , Buf2(n))
  563. Next
  564.  
  565. End If
  566. Timeout1 = Timeout_time 'przedłuzaj/uruchamiaj timeout przy kazdym kliku
  567. Return
  568.  
  569. ' Obsługa przycisku Encoder2 I_SET
  570. Enc_sw2_sub:
  571. If Timeout > 0 Then
  572. Incr Pos2 : If Pos2 > 4 Then Pos2 = 1
  573.  
  574. Pos2_ee = Pos2 ' Zapisz pozycję do eeprom
  575. For N = 1 To 5
  576. Call Write_eeprom(n + 18 , Buf4(n))
  577. Next
  578.  
  579. End If
  580. Timeout = Timeout_time 'przedłuzaj/uruchamiaj timeout przy kazdym kliku
  581. Return
  582.  
  583. 'obsługa przerwania zewnetrznego z encoder2
  584. Encoder2_isr:
  585.    $asm
  586.       PUSH R23
  587.       PUSH R24
  588.       PUSH R26
  589.       PUSH R27
  590.       !in R24, sreg
  591.       PUSH  R24
  592.    $end Asm
  593.  
  594.    Disable INT0
  595.  
  596.    If Encoder2_a = 1 Then
  597.       Incr Encoder2_turn_right
  598.    Else
  599.       Incr Encoder2_turn_left
  600.    End If
  601.  
  602. 'Tuned with NoSave Tool
  603.    $asm
  604.       POP  R24
  605.       !out sreg, r24
  606.       POP R27
  607.       POP R26
  608.       POP R24
  609.       POP R23
  610.    $end Asm
  611.  
  612. Return
  613.  
  614. 'obsługa przerwania zewnetrznego z encoder1
  615. Encoder1_isr:
  616.  
  617.    $asm
  618.       PUSH R23
  619.       PUSH R24
  620.       PUSH R26
  621.       PUSH R27
  622.       !in R24, sreg
  623.       PUSH  R24
  624.    $end Asm
  625.  
  626.    Disable Int1
  627.  
  628.    If Encoder1_a = 1 Then
  629.       Incr Encoder1_turn_right
  630.    Else
  631.       Incr Encoder1_turn_left
  632.    End If
  633.  
  634. 'Tuned with NoSave Tool
  635.  
  636.    $asm
  637.       POP  R24
  638.       !out sreg, r24
  639.       POP R27
  640.       POP R26
  641.       POP R24
  642.       POP R23
  643.    $end Asm
  644.  
  645. Return
  646.  
  647. ' ================== OBSŁUGA DAC =====================
  648.  
  649. 'Reset DAC
  650. Sub Dac_reset
  651. ' [ Slave Address ] [ Command Data Byte ] [ Most Significant Data Byte ] [ Least Significant Data Byte ]
  652. ' [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]
  653. ' [ 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
  654. Length = 3
  655. Daccommand(1) = &B00101000 ' Command Byte
  656. Daccommand(2) = &B00000000 ' MSB
  657. Daccommand(3) = &B00000000 ' LSB
  658. I2csend Dac_addr , Daccommand(1) , Length
  659. End Sub
  660.  
  661. 'Internal voltage reference off
  662. Sub Dac_ref_on()
  663. ' [ Slave Address ] [ Command Data Byte ] [ Most Significant Data Byte ] [ Least Significant Data Byte ]
  664. ' [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]
  665. ' [ 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
  666. Length = 3
  667. Daccommand(1) = &B00000000 ' Command Byte (00111000)internal ref off musi być
  668. Daccommand(2) = &B00000000 ' MSB
  669. Daccommand(3) = &B00000001 ' LSB
  670. I2csend Dac_addr , Daccommand(1) , Length
  671. End Sub
  672.  
  673. 'LDAC register set for asynchronous mode
  674. Sub Dac_ldac_async()
  675. ' [ Slave Address ] [ Command Data Byte ] [ Most Significant Data Byte ] [ Least Significant Data Byte ]
  676. ' [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]
  677. ' [ 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
  678. Length = 3
  679. Daccommand(1) = &B00110000 ' Command Byte
  680. Daccommand(2) = &B00000000 ' MSB
  681. Daccommand(3) = &B00000011 ' LSB
  682. I2csend Dac_addr , Daccommand(1) , Length
  683. End Sub
  684.  
  685. 'Power up both DAC channels
  686. Sub Dac_power_on()
  687. ' [ Slave Address ] [ Command Data Byte ] [ Most Significant Data Byte ] [ Least Significant Data Byte ]
  688. ' [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]
  689. ' [ 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
  690. Length = 3
  691. Daccommand(1) = &B00100000 ' Command Byte
  692. Daccommand(2) = &B00000000 ' MSB
  693. Daccommand(3) = &B00000011 ' LSB
  694. I2csend Dac_addr , Daccommand(1) , Length
  695. End Sub
  696.  
  697. 'Set DAC channel A
  698. Sub Dac_set_a(value As Word)
  699. ' [ Slave Address ] [ Command Data Byte ] [ Most Significant Data Byte ] [ Least Significant Data Byte ]
  700. ' [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]
  701. ' [ 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
  702. Length = 3
  703. Dachigh = High(value)
  704. Daclow = Low(value)
  705. Daccommand(1) = &B00011000 ' Command Byte
  706. Daccommand(2) = Dachigh ' MSB
  707. Daccommand(3) = Daclow ' LSB
  708. I2csend Dac_addr , Daccommand(1) , Length
  709. End Sub
  710.  
  711. 'Set DAC channel B
  712. Sub Dac_set_b(value As Word)
  713. ' [ Slave Address ] [ Command Data Byte ] [ Most Significant Data Byte ] [ Least Significant Data Byte ]
  714. ' [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]
  715. ' [ 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
  716. Length = 3
  717. Dachigh = High(value)
  718. Daclow = Low(value)
  719. Daccommand(1) = &B00011001 ' Command Byte
  720. Daccommand(2) = Dachigh ' MSB
  721. Daccommand(3) = Daclow ' LSB
  722. I2csend Dac_addr , Daccommand(1) , Length
  723. End Sub
  724.  
  725. ' ==================== KONIEC OBSŁUGI DAC ================================
  726.  
  727. ' ==================== OBSŁUGA ADC =======================================
  728. ' Pomiar U_OUT / I_OUT
  729. Sub Measure
  730.  
  731. ' I_OUT
  732. I2cstart
  733. I2cwbyte Addressr      'Adres Do Odczytu
  734. I2crbyte Pomiarh , Ack 'Odczyt Pomiaru
  735. I2crbyte Pomiarl , Nack
  736. I2cstop 'Bit Stopu
  737.  
  738. Const K = 2.048 / 32768
  739. ADC_current = Makeint(Pomiarl,Pomiarh)
  740. Current = ADC_current * K
  741. Current = Current + 0.001 ' Kalibracja
  742.  
  743. ' U_OUT
  744. I2cstart
  745. I2cwbyte Addressr1      'Adres Do Odczytu
  746. I2crbyte Pomiarh1 , Ack 'Odczyt Pomiaru
  747. I2crbyte Pomiarl1 , Nack
  748. I2cstop  'Bit Stopu
  749.  
  750. Const K = 2.048 / 32768
  751. ADC_voltage = Makeint(Pomiarl1,Pomiarh1)
  752. Voltage = ADC_voltage * K
  753. Voltage = Voltage * 10     ' Współczynnik K dla dzielnika rezystorowego
  754. Voltage = Voltage - 0.0250 ' Kalibracja
  755.  
  756. ' P_OUT
  757. Moc = voltage * current
  758.  
  759. End Sub
  760.  
  761. ' Wyświetlenie pomiarów U_OUT/I_OUT/P_OUT
  762. Sub Show_measure
  763.  
  764. Voltage_out = Fusing(voltage , "#.&&&")
  765. U_str = Format(voltage_out , "      ")
  766. Locate 2 , 1 : Lcd "OUT " ; U_str ; Chr(0)
  767.  
  768. Current_out = Fusing(current , "#.&&&")
  769. I_str = Format(current_out , "      ")
  770. Locate 2 , 14 : Lcd I_str ; Chr(1)
  771.  
  772. Moc_out = Fusing(moc , "#.&&&")
  773. Moc_str = Format(Moc_out , "      ")
  774. Locate 3 , 1 : Lcd Moc_str ; Chr(2)
  775.  
  776. If CC = 0 Then ' constant voltage
  777. Locate 3 , 10 : LCD "CC"
  778.   end if
  779. If CV = 0 Then ' constant current
  780. Locate 3 , 10 : LCD "CV"
  781. end if
  782.  
  783. End Sub
  784. ' ============================= KONIEC OBSŁUGI ADC ========================
  785.  
  786. ' Pomiar temperatury DS18B20
  787. Sub Temperature
  788. 1wreset
  789. 1wwrite &HCC
  790. 1wwrite &H44
  791. 1wverify Ds1(1)'1wreset i 1wwrite &H55 niepotrzebne bo 1wverify samo to przeprowadza
  792. 1wwrite &HBE
  793. Wew(1) = 1wread(9)
  794.  
  795. Ts = Makeint(wew(1) , Wew(2)) ' Obliczenie wartości teperatury
  796. Ts = Ts * 10
  797. Ts = Ts / 16
  798. T_heatsink = Ts / 10 ' obliczenie temperatury dla funkcji OTP (Over-temperature protection)
  799.  
  800. Temperatura_str = Str(ts)
  801. Temperatura_str = Format(temperatura_str , "0.0")
  802.  
  803. If T_heatsink > 30 Then ' Jeżeli temperatura głównego radiatora przekroczy 55 stC, to skok do procedury OTP
  804. If ot = 1 Then gosub Overtemperature
  805.         end if
  806. If ot = 1 Then
  807. If Err = 1 Then gosub Overtemperature ' Jeżeli błąd czujnika DS18B20 to skok do procedury OTP
  808. end if
  809. End Sub
  810.  
  811. ' Wyświetlenie temperatury DS18B20
  812. Sub Show_temperature
  813. If Err = 0 Then
  814. Locate 4 , 15 : Lcd Temperatura_str ; Chr(3) ; "C"
  815. else
  816. Locate 4 , 15 : Lcd Error
  817. End if
  818. End Sub
  819.  
  820. Beep:
  821. buzzer = 1
  822. waitms 50
  823. buzzer = 0
  824. Return
  825.  
  826. ' Obsługa przycisku OVP
  827. Ovp_sw_sub:
  828. gosub Beep
  829. If ovp_sw = 0 Then
  830. Toggle ov
  831.      end if
  832.       If ov = 1 Then
  833.    Locate 4 , 1 : Lcd "OVP"
  834.    Else
  835.    If ov = 0 Then
  836.    Locate 4 , 1 : Lcd "   "
  837.   end if
  838.   end if
  839. Return
  840.  
  841. ' Obsługa przycisku OCP
  842. Ocp_sw_sub:
  843. gosub Beep
  844. If ocp_sw = 0 Then
  845. Toggle oc
  846.      end if
  847.       If oc = 1 Then
  848.    Locate 4 , 5 : Lcd "OCP"
  849.    Else
  850.    If oc = 0 Then
  851.    Locate 4 , 5 : Lcd "   "
  852.   end if
  853.   end if
  854. Return
  855.  
  856. ' ##########  Procedura ochrony OVP  ##########
  857. Overvoltage:
  858. relay = 0  'Wyłączenie przekaźnika
  859. output_led = 0
  860. ' Sygnalizacja dźwiękowa przeciążenia
  861. Pulses = 120   ' ustalenie długości tonu dźwiękowego
  862. Periods = 2200 ' ustawienie barwy tonu
  863. Sound buzzer , Pulses , Periods ' dźwięk ostrzegawczy
  864. Do
  865. relay = 0
  866. output_led = 0
  867. ov = 0
  868. Locate 1 , 1 : Lcd Frame_long
  869. Locate 2 , 1 : Lcd "-  OVP   Out: Off  -"
  870. Locate 3 , 1 : Lcd Frame_long
  871. Locate 4 , 1 : Lcd Info
  872. If output_sw = 0 Then
  873. cls
  874. waitms 20
  875. If output_sw = 0 Then
  876. relay = 0 : Mig = 0 : Mig1 = 0
  877. Call Show_voltage
  878. Call Show_current
  879. return
  880. end if : end if
  881. Loop
  882.  
  883. ' ##########  Procedura ochrony OCP  ##########
  884. Overcurrent:
  885. relay = 0  'Wyłączenie przekaźnika
  886. output_led = 0
  887. ' Sygnalizacja dźwiękowa przeciążenia
  888. Pulses = 120   ' ustalenie długości tonu dźwiękowego
  889. Periods = 2200 ' ustawienie barwy tonu
  890. Sound buzzer , Pulses , Periods ' dźwięk ostrzegawczy
  891. Do
  892. relay = 0
  893. output_led = 0
  894. oc = 0
  895. Locate 1 , 1 : Lcd Frame_long
  896. Locate 2 , 1 : Lcd "-  OCP   Out: Off  -"
  897. Locate 3 , 1 : Lcd Frame_long
  898. Locate 4 , 1 : Lcd Info
  899. If output_sw = 0 Then
  900. cls
  901. waitms 20
  902. If output_sw = 0 Then
  903. relay = 0 : Mig = 0 : Mig1 = 0
  904. Call Show_voltage
  905. Call Show_current
  906. return
  907. end if : end if
  908. Loop
  909.  
  910. ' ##########  Procedura ochrony OTP  ##########
  911. Overtemperature:
  912. relay = 0  'Wyłączenie przekaźnika
  913. output_led = 0
  914. ' Sygnalizacja dźwiękowa przeciążenia
  915. Pulses = 120   ' ustalenie długości tonu dźwiękowego
  916. Periods = 2200 ' ustawienie barwy tonu
  917. Sound buzzer , Pulses , Periods ' dźwięk ostrzegawczy
  918. Do
  919. relay = 0
  920. output_led = 0
  921. ot = 0
  922. Locate 1 , 1 : Lcd Frame_long
  923. Locate 2 , 1 : Lcd "-  OTP   Out: Off  -"
  924. Locate 3 , 1 : Lcd Frame_long
  925. Locate 4 , 1 : Lcd Info
  926. If output_sw = 0 Then
  927. cls
  928. waitms 20
  929. If output_sw = 0 Then
  930. relay = 0 : Mig = 0 : Mig1 = 0
  931. Call Show_voltage
  932. Call Show_current
  933. return
  934. end if : end if
  935. Loop
Przypuszczam że problem jeszcze leży w tych wstawkach assamblera, ale tego zupełnie nie rozumiem.

Re: ATmega644A nie działa program napisanym pod ATmega32

: 04 lip 2021, 21:31
autor: Michał6201
Chciałem przeprosić za zamieszanie z tym nie działającym programem pod ATmega644 :D
Rejestry pozmieniałem i działa wszystko pięknie tak jak na ATmega32. Enkodery źle zliczały, bo pierwotnie miałem piny A i B podciągnięte do masy kondensatorkami 100nF i z tym ATmega32 działało poprawnie.
Natomiast z ATmega644 już zliczały impulsy z błędami. Zamieniłem te kondensatorki na 10nF i wszystko już pięknie działa :D

Jeszcze raz przepraszam za całe zamieszanie. Moja wina.