Powerdown mode w ATmega32A chyba źle robię

Pytania, kody i porady dotyczące nie tylko Bascom.
Awatar użytkownika
Michał6201
Posty: 165
Rejestracja: 03 paź 2015, 20:07

Powerdown mode w ATmega32A chyba źle robię

Post autor: Michał6201 » 09 maja 2026, 14:40

Cześć

Chciałem sobie wytestować usypianie atmegi32a za pomocą przerwania INT0
Niby program działa poprawnie, ale co któreś wyzwolenie stanem niskim nie powoduje przejścia do głównej pętli, tak jakby się zawieszał program.
Co może być tego przyczyną?

Uśpienie działa bezbłędnie, ale po wybudzeniu nic się nie da robić oprócz kręcenia się w kółko w głównej pętli.
Próba przejścia do jakiejkolwiek procedury z głównej pętli jest niemożliwe bo cały czas INT0 tak jakby przeszkadzał.
To wygląda na to że to całe POWER MODE do niczego nie jest potrzebne, bo bezużyteczne.
W trakcie normalnej pracy chcę, aby INT0 było cały czas podłączone do GND. A to chyba wyklucza usypiania?


  1. $regfile = "m32adef.dat"
  2.     $crystal = 11059200 '11,0592MHz
  3.     $hwstack = 64
  4.     $swstack = 32
  5.     $framesize = 64
  6.  
  7.  Config Int0 = Low Level
  8.   Enable Interrupts
  9.   On Int0 Int0_isr
  10.  
  11.  
  12. Config PortB.0 = Input : PortB.0 = 1 : INT_PCF Alias PinB.0 ' WEJŚCIE SYGNAŁU INT 1Hz
  13. Config PortB.3 = Output : PortB.3 = 1 : LED Alias PortB.3
  14. Config POrTD.2 = Input : PORTD.2 = 1 : SWITCH Alias PIND.2
  15. Dim Mig As Bit
  16. Dim Flaga As Bit
  17. Flaga = 0
  18.  
  19.  
  20. Do
  21.  
  22. 'Mig = INT_PCF
  23. 'If Mig = 0 Then LED = 0 Else LED = 1
  24.  
  25.  
  26.  
  27.    ' Wprowadzenie w tryb Power Down
  28.         If SWITCH = 1 Then Flaga = 1
  29.         If Flaga = 1 Then
  30.         'LED = 1
  31.              Enable Int0
  32.                Config Powermode = Powerdown
  33.               end if
  34.  
  35. Loop
  36. END
  37.  
  38. Int0_isr:
  39.  Enable INT0
  40. SWITCH = 0
  41. Flaga = 0
  42.  
  43. Return
Przy zasilaniu mikrokontrolera napięciem +5V i taktowaniu zewnętrznym kwarcem 11.0592MHz, po wejściu mikrokontrolera w POWERDOWN MODE pobór prądu spada o 10mA.
Oczywiście miganie ledem wyciąłem, tak jak w załączonym kodzie, aby nic nie przekłamywało pomiaru prądu.
Awatar użytkownika
niveasoft
Posty: 1313
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Powerdown mode w ATmega32A chyba źle robię

Post autor: niveasoft » 10 maja 2026, 2:09

Taka klasyka gatunku :D Dziwne że jeszcze po latach tego nie wiesz, ale napiszę.
Jak stoi w nocie aplikacyjnej stan przerwania LOW LEVEL trwa tak długo jak jest włączone i jak długo utrzymuje sie stan niski na pinie INT jesli ktoś włączyył LOW LEVEl INTERRUPT.
Nie wyjdzie z przerwania dopóki trwa stan niski na pinie, ale to jedyny sposób by wybudzić z POWERDOWN :D (może jeszcze asynchroniczny zegar potrafi - nie pamiętam)
Tak więc sekwencja powinna być przynajmniej taka, że po wejściu w przerwanie wyłaczasz je, czekasz na ustabilizowanie stanu pinu/wyłacznika/stycznika i dopiero kasujesz flagi kolejnego przerwania (bo drgania na pewno wymusiły następne) i wychodzisz z przerwania. Najkrótszym kodem przerwania powiino być to:
  1. INT0_isr:
  2. Disable INT0
  3. Bitwait SWITCH , 1 ' poczekaj aż wejście otrzyma stan wysoki
  4. Do
  5. Waitms 10
  6. If SWITCH = 1 Then Exit Do
  7. Loop
  8. GIFR = 255 ' General Interrupt Flag Register - kasujemy flagi INTF1, INTF0, i INTF2 - przez 255 jest szybciej
  9. Return
Wpisywanie do przerwania czegoś takiego jak SWITCH=0 jest metodą życzeniową i na pewno nieskuteczną. To tak jakbyś wyszedł na dwór, spojrzał że pada deszcz i powiedział, nie pada :D
Jeśli przycisk ma zwarty pin do masy to procesor nic z tym zrobić nie może. Po prostu jest zwarty do masy. Może to tylko odczytywać.
Awatar użytkownika
Michał6201
Posty: 165
Rejestracja: 03 paź 2015, 20:07

Re: Powerdown mode w ATmega32A chyba źle robię

Post autor: Michał6201 » 10 maja 2026, 10:45

Dziękuję Ci za podpowiedź.
Przy tym zapisie pokazuje się błąd i nie pozwala skompilować.
  1. Bitwait SWITCH , set 1 ' poczekaj aż wejście otrzyma stan wysoki  
Ale i tak raczej w takiej sytuacji nic z tego usypiania nie będzie, bo płytkę mam już od dawna zrobioną, pin INT (PD2) w czasie działania programu jest zwarty na stałe do GND, a tylko podczas braku aktywności jest podciągnięty do VCC. Więc zwarcie INT do GND na stałe musiałoby aż do odwołania wybudzić jednorazowo mikrokontroler z powerdown, aby mógł program normalnie wykonywać się.
W ogóle nie przewidywałem używania przerwań. Teraz wpadłem na taki pomysł chcąc obniżyć pobór prądu w czasie bezczynności. Ale jak widać nie da się.

To kompiluje się, ale nie działa. Tzn program wykonuje się w głównej pętli dopóki INT0 nie zostanie podciągnięty do VCC. I na tym kończy się działanie programu. Pomaga tylko reset.
Zmieniłem też zapis po Bitwait na RESET zamiast SET, bo PD2 ma być w czasie działania układu cały czas podciągnięty do GND, ale też zawiesza się procek. GIFR = 255 też zawiesza procka.
  1.     $regfile = "m32adef.dat"
  2.     $crystal = 11059200 '11,0592MHz
  3.     $hwstack = 64
  4.     $swstack = 32
  5.     $framesize = 64
  6.  
  7.  
  8. Config Int0 = Low Level
  9. Enable Interrupts
  10. On Int0 Int0_isr
  11.  
  12. Config PortB.0 = Input : PortB.0 = 1 : INT_PCF Alias PinB.0 ' WEJŚCIE SYGNAŁU INT 1Hz
  13. Config PortB.3 = Output : PortB.3 = 1 : LED Alias PortB.3
  14. Config PortC.7 = Output : PortC.7 = 0 : BUZ Alias PortC.7
  15. Config POrTD.2 = Input : PORTD.2 = 1 : SWITCH Alias PIND.2
  16.  Config POrTC.6 = Input : PORTC.6 = 1 : SW Alias PINC.6
  17. Dim Mig As Bit
  18. Dim Flaga As Bit
  19. Flaga = 0
  20. Dim Bip As Bit
  21. Bip = 0
  22.  
  23. Do
  24. Flaga = 0
  25. Mig = INT_PCF
  26. If Mig = 0 Then LED = 0 Else LED = 1
  27.  
  28.  
  29.    ' Wprowadzenie w tryb Power Down
  30.         If SWITCH = 1 Then Flaga = 1
  31.        If Flaga = 1 Then
  32.         Led = 1
  33.         Enable INT0
  34.  
  35.        Config Powermode = Powerdown
  36.                      end if
  37.  
  38. Loop
  39. END
  40.  
  41.  
  42.   INT0_isr:
  43. Disable INT0
  44. 'SWITCH = 1
  45. Bitwait SWITCH , Set ' poczekaj aż wejście otrzyma stan wysoki
  46. Do
  47. Waitms 10
  48. If SWITCH = 1 Then Exit Do
  49. Loop
  50. GIFR = 255 ' General Interrupt Flag Register - kasujemy flagi INTF1, INTF0, i INTF2 - przez 255 jest szybciej
  51. Return
Ten kod działa, ale co jakiś czas zawiesza się program, więc wygląda na to, że te przerwania i usypiania to nic pewnego. Nie powinien wieszać się program przy próbie wybudzenia.
  1.     $regfile = "m32adef.dat"
  2.     $crystal = 11059200 '11,0592MHz
  3.     $hwstack = 64
  4.     $swstack = 32
  5.     $framesize = 64
  6.  
  7.  
  8. Config Int0 = Low Level
  9. Enable Interrupts
  10. On Int0 Int0_isr
  11.  
  12. Config PortB.0 = Input : PortB.0 = 1 : INT_PCF Alias PinB.0 ' WEJŚCIE SYGNAŁU INT 1Hz
  13. Config PortB.3 = Output : PortB.3 = 1 : LED Alias PortB.3
  14. Config PortC.7 = Output : PortC.7 = 0 : BUZ Alias PortC.7
  15. Config POrTD.2 = Input : PORTD.2 = 1 : SWITCH Alias PIND.2
  16.  Config POrTC.6 = Input : PORTC.6 = 1 : A Alias PINC.6
  17. Dim Mig As Bit
  18. Dim Flaga As Bit
  19. Flaga = 0
  20. Dim Bip As Bit
  21. Bip = 0
  22.  
  23. Do
  24. Flaga = 0
  25. Mig = INT_PCF
  26. If Mig = 0 Then LED = 0 Else LED = 1
  27. If A = 0 then gosub Beep
  28.  
  29.    ' Wprowadzenie w tryb Power Down
  30.         If SWITCH = 1 Then Flaga = 1
  31.        If Flaga = 1 Then
  32.         Led = 1
  33.         Enable INT0
  34.  
  35.        Config Powermode = Powerdown
  36.                      end if
  37.  
  38. Loop
  39. END
  40.  
  41.  
  42. INT0_isr:
  43. Disable INT0
  44. SWITCH = 0
  45. 'Bitwait SWITCH , RESET ' poczekaj aż wejście otrzyma stan wysoki
  46. Do
  47. SWITCH = 0
  48. Waitms 500
  49. If SWITCH = 0 Then Exit Do
  50. Loop
  51. GIFR = 255 ' General Interrupt Flag Register - kasujemy flagi INTF1, INTF0, i INTF2 - przez 255 jest szybciej
  52. Return
Awatar użytkownika
niveasoft
Posty: 1313
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Powerdown mode w ATmega32A chyba źle robię

Post autor: niveasoft » 11 maja 2026, 12:01

Proponuję nie kopać się z koniem i wymienić procesor na nowszy.
Na przykład jeśli masz to nawet w obudowie DIL64 to możesz sobie tam wsadzić Mega324P, Mega644P, Mega1284P.
Program ktory już masz będzie pasował jeden do jednego a będziesz mógł wybudzić procesor przerwaniem PCINT.
Awatar użytkownika
Michał6201
Posty: 165
Rejestracja: 03 paź 2015, 20:07

Re: Powerdown mode w ATmega32A chyba źle robię

Post autor: Michał6201 » 11 maja 2026, 20:02

ATMEGA324P odpada, bo inaczej ma piny zasilania wyprowadzone, a tak jak już pisałem płytka jest złożona.
Natomiast pasować będzie ATMEGA644P, ATMEGA324A z tych mniejszych. Konicznie obudowa TQFP44.
Zaraz wytestuję na mojej płytce testowej program na ATMEGA644, bo mam taką w obudowie DIL.

Czy w ATMEGA644P dla pinu PCINT26/INT0 (PD2) zmienić musi się kod służący do uśpienia i wybudzenia?
Ostatnio zmieniony 11 maja 2026, 20:27 przez Michał6201, łącznie zmieniany 1 raz.
Awatar użytkownika
niveasoft
Posty: 1313
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Powerdown mode w ATmega32A chyba źle robię

Post autor: niveasoft » 11 maja 2026, 20:27

Oczywiscie z iloscią tych pinów się machnąłem bo pisałem "z głowy. DIP ma 40 pinów a TQFP 44.
Jednak co do tych 324P że nie pasują to bym jeszcze sprawdził. U mnie one mają jedną wspólna notę katalogową (164/324/644) a literki na końcu to były dla minimalnych napięc przy jakich pracują stabilnie. V działa z najniższymi napięciami. P z trochę wyższymi. Kiedyś chyba gdzieś dawno słyszałem żę P to "Pico Power". Te A były najstarsze chyba.

W programie może być tylko delikatna różnica w Timerach bo stare mają czasem tylko "Compare" a nowsze moga mieć "Compare_a", "Compare_b" itd...

Nie będę drążył tematu tych 324A/P/V bo ta Atmega644P jest popularna i najtańsza chyba.
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
Awatar użytkownika
Michał6201
Posty: 165
Rejestracja: 03 paź 2015, 20:07

Re: Powerdown mode w ATmega32A chyba źle robię

Post autor: Michał6201 » 11 maja 2026, 20:32

A czy kod odpowiedzialny za usypianie i wybudzanie zmienia się jakoś przy ATMEGA644p?
Chodzi o pin PCINT26/INT0 (PD2) bo to na nim mam usypianie/wybudzanie
Awatar użytkownika
niveasoft
Posty: 1313
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Powerdown mode w ATmega32A chyba źle robię

Post autor: niveasoft » 11 maja 2026, 20:56

Raczej tak. Spróbuj tego. Pisałem tak na szybciora z głowy, ale to ma pokazać koncept.
W PCINT on reaguje na zmiany na pinie wiec przerwanie masz i jak dostanie stan wysoki i jak zmieni na niski. Jeden trzeba wtedy przy usypianiu zignorować.
Pewnie tu dużo mozna dopieścić.
Teraz powinno migać LED`em jak na PD2 jest masa a jak nie to LED powinien zgasnąć
  1. $regfile = "m644pdef.dat"
  2.  $crystal = 11059200                                        '11,0592MHz
  3.  $hwstack = 64
  4.  $swstack = 32
  5.  $framesize = 64
  6.  
  7.  
  8.  PCMSK3 = &B0000_0100  'aktywny tylko PD2
  9.  Enable PCINT3 : On PCINT3 Pcint3_isr
  10.  
  11.  Int_pin alias pind.2 : set portd.2
  12.  
  13.  Config PortB.3 = Output : PortB.3 = 1 : LED Alias PortB.3
  14.  
  15.  Dim sleep_request as byte
  16.  
  17.  Enable interrupts
  18.  
  19.  do
  20.  
  21.   Waitms 500 : toggle LED
  22.  
  23.   if sleep_request = 1 then  'jesli nie bylo masy i ustawiono flage
  24.    sleep_request = 0          'kasuj i idz spac
  25.   Set LED 'nie zapomnij zgasic LED`a
  26.    Config powermode = powerdown
  27.   end if
  28.  
  29.   'tu program bedzie jak sie obudzi
  30.   'zatoczy kolo i bedzie normalnie migac LED`em
  31.  loop
  32.  end
  33.  
  34.  Pcint3_isr:   'zmiana stanu na pinie
  35.    If int_pin = 0 then   'jesli pokazała się masa to nic nie rob
  36.     return
  37.    else
  38.     sleep_request = 1      'jesli masa zanikla to ustaw flage i wracaj
  39.    end if
  40.  Return
Awatar użytkownika
Michał6201
Posty: 165
Rejestracja: 03 paź 2015, 20:07

Re: Powerdown mode w ATmega32A chyba źle robię

Post autor: Michał6201 » 11 maja 2026, 21:24

Jeśli INT0 jest podciągnięty do VCC i na chwilę zniknie zasilanie mikrokontrolera, to program startuje, tak jakby INT0 było ściągnięte do GND.
Czyli chwilowy zanik napięcia spowoduje włączenie układu i wykonywanie programu w głównej pętli.
Awatar użytkownika
niveasoft
Posty: 1313
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Powerdown mode w ATmega32A chyba źle robię

Post autor: niveasoft » 11 maja 2026, 21:33

Na próbę dodaj sobie jakieś opóźnienie przed włączeniem przerwań. Na przykład przed Enable Interrupts:
  1. Dim sleep_request as byte
  2.  
  3. Waitms 500
  4. 'kasowanie wywolania przerwania jesli juz jakies procesor zauwazyl
  5. PCIFR = PCIFR 'jesli gdzies jest flaga 1 to ja tam wpisze przez co ją skasuje
  6. sleep_request = 1 'jesli ma spac z zalozenia
  7. Enable Interrupts
Możesz też na bezczelnego w pętli dać warunek że jak stan wysoki to ma iśc spać bo Tobie potrzebny jest tylko stan niski do wybudzenia:
  1. sleep_request = Int_pin 'jesli stan wysoki w petli to idz spac
  2. If sleep_request = 1 Then ' ..... itd...
ODPOWIEDZ