Witam, najpierw program:
Teraz opis:
Program steruje reglem moelarskim, który steruje silnikiem BLDC.
Dodatkowo wyświetla stan naładowania 2 akumulatorów Li-Poli zasilających regiel. Regiel dodatkowo jest wyłączany MOSFETem (oszczędzanie energii)
Całością steruje microswitch w sposób:
a) krótkie wciśniecie i puszczenie (do 250ms) to właczenie bądz wyłączenie urządzenia
b) dłuższe przetrzymanie przycisku powoduje zwiększenie wypełnienia skokowo, kolejne dłuższe przytrzymanie powoduje zmniejszenie wypełnienia (kazde wcisniecie powoduje zmianę kierunku zwiększenie-zmniejszenie)
Dodatkowo podczas włączania urządzenia stan naładowania aku jest podawany na diodzie LED poprzez jej odpowiednia ilość mrugnięć
Opis problemu:
Wygląda na to, że przepełnia mi się stos bo po jakiejś minucie od podłączenia zasilania i niekorzystania z przycisku nie można juz obudzić kontrolera.
Jeśli ktoś ma ochote to byłbym wdzięczny o pomoc w znalezieniu błędu
Dodam, że te same problemy miałem z ATiny26, więc to nie wina płytki ani kontrolera tylko moja
Pozdrawiam
Opis elementów:
TS1 to TS2951cs-5V (stabilizator low drop low power 5V/150mA)
IRF1 to IRF7455 (MOSFET)
W punkcie "sterowanie" podłączony jest przycisk podciągniety R12 = 1MOhm do plusa
W punkcie "pomiar temperatury" podłączam wyjście LM35
LED, PWM to wyjścia odpowiednio sterujące dioda i reglem. LED może będzie 2 katodowy, do tego przewidziałem kolejne wyjście tuz nad pierwszym)
Na dole tuż nad polami do programowania jest także indukcyjność oznaczona prostokątem i literką L leżącą na diolnych pinachm, więc niewiele jej widać.
R8 steruje GATE mosfetu a R13(nad nim) podciąga ją do masy
R9-R10 to dzielnik napięciowy do pomiaru napięcia ogniw, włączany tylko w czasie pracy poprzez zwarcie R10 do masy (wczesniej odpowiednie wyprowadzenia kontrolera maja wysoką impedancję - pracuja jako wejścia)
C2 to tantal 10uF filtrujący zasilanie
Dodatkowo jest mierzony prąd pobierany przez regiel poprzez pomiar spadku napięcia na ścierzce 1mm X 35mm biegnącej tuż pod plusem zasilania i rezystorami R12, R9. (1A=17mV=15kwantów)
Cytat:.include "m88def.inc"
; procek ustawiam na prace z wewnętrznego oscylatora 8MHz
; tryb sleep ustawiam jako POWER DOWN
; PD3 (INT1) jest przyciskiem (wejscie)
; PB1 (OC1A) to wyjscie sterujace reglem
; PB5 to wyjscie sterujące MOSFETami zalaczajacymi zasilanie regla
; PD5 (OC0B) to wyjscie sterujace LEDem
; ADC6 - pomiar pradu
; PC1, pomiar napiecia baterii (dziala gdy PC2,3,4 sa w stanie niskim)
; PC2, PC3, PC4 sa wejsciami, zmieniaja swoj stan tylko przy pomiarze napiecia (wyjscie, 0)
; PC5 (ADC5), pomiar temperatury
; BOD ustawiam na 101 (2,7V)
.org 0x0
rjmp Resetuj ; Reset handler
nop ;rjmp IRQ_INT0 ; IRQ0 Handler
rjmp IRQ_INT1 ; przerwanie od przycisku
nop ;rjmp PCINT0 ; PCINT0 Handler
nop ;rjmp PCINT1 ; PCINT1 Handler
nop ;rjmp PCINT2 ; PCINT2 Handler
nop ;rjmp WDT ; Watchdog Timer Handler
nop ;rjmp TIM2_COMPA ; Timer2 Compare A Handler
nop ;rjmp TIM2_COMPB ; Timer2 Compare B Handler
nop ;rjmp TIM2_OVF ; Timer2 Overflow Handler
nop ;rjmp TIM1_CAPT ; Timer1 Capture Handler
nop ;rjmp TIM1_COMPA ; Timer1 Compare A Handler
nop ;rjmp TIM1_COMPB ; Timer1 Compare B Handler
nop ;rjmp TIM1_OVF ; Timer1 Overflow Handler
nop ;rjmp TIM0_COMPA ; Timer0 Compare A Handler
nop ;rjmp TIM0_COMPB ; Timer0 Compare B Handler
nop ;rjmp TIM0_OVF ; Timer0 Overflow Handler
nop ;rjmp SPI_STC ; SPI Transfer Complete Handler
nop ;rjmp USART_RXC ; USART, RX Complete Handler
nop ;rjmp USART_UDRE ; USART, UDR Empty Handler
nop ;rjmp USART_TXC ; USART, TX Complete Handler
nop ;rjmp ADC ; ADC Conversion Complete Handler
nop ;rjmp EE_RDY ; EEPROM Ready Handler
nop ;rjmp ANA_COMP ; Analog Comparator Handler
nop ;rjmp TWI ; 2-wire Serial Interface Handler
nop ;rjmp SPM_RDY ; Store Program Memory Ready Handler
.org 0x1A
Resetuj: ; zainicjalizuj stos:
cli
ldi R16, low(RAMEND)
out SPL, R16
ldi R16, high(RAMEND)
out SPH, R16
ldi R16, 0
ldi R17, 0
ldi R18, 0
ldi R19, 0
ldi R20, 0
ldi R21, 0
ldi R22, 0
ldi R23, 0
ldi R24, 0
mov R15, R24
wdr
ldi R16, (1<<WDE)|(1<<WDCE)
sts 0x60, R16
ldi R16, (1<<WDP0)|(1<<WDP3)|(1<<WDCE)
sts 0x60, R16
rcall led_1
; ==================== ustawiam przerwanie od INT1 =========================
ldi R16, 0b00000000 ; ustawiam przerwanie przy niskim stanie INT1
sts EICRA, R16
ldi R16, 0b00000010
sts 0x3D, R16 ; odblokowuje przerwanie od INT1
; ==========================================================================
; ================== ustawiam tryb sleep jako POWER save ===================
ldi R16, 0b00000111 ; 101 -power down
sts SMCR, R16 ; ustawiam SMCR
rjmp spij
; ==========================================================================
IRQ_INT1:
cli ; blokujemy przerwania
ldi r16,0b00000000
out SMCR,r16 ;wylacz SE (zezwolenie na uspienie)
sbi EIFR, INTF1 ; kasujemy wywołanie
;cbi PORTB, 5 ; wylaczam urzadzenie <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; 1a) jesli jest to poczatek programu (R20=0) to wykonujemy procedure startu
; 1b) jesli program juz dziala (R20=1) to sprawdzamy czy ktos nie chce zmienic wypelnienia lub wylaczyc
; 2a) zmieniamy wypelnienie
; 2b) wylaczam (sleep)
; 1)
rcall Czekaj ; jesli w ciagu okreslonego czasu przycisk zostanie puszczony to wlaczamy
in R16, PIND
sbrs R16, 3 ; jesli nadal bedzie trzymany to zmieniamy wypelnienie
rjmp zmien_PWM
sbrc R20, 0
rjmp wylacz
ldi R20, 1 ; ustawiam znacznik pracy układu
; petla główna programu, ustawiamy generator (T1) na PWM (WGM10, WGM13)(COM1A0)(cs10, CS11) 50Hz OC1A i zmieniamy wypełnienie
; najpierw sprawdzamy temperature i na piecie
sbi DDRB, 1 ; ustawiam wyjscie B1
; jesli sa dobre to wlaczam generator PWM
sbi PORTB, 5
sbi DDRB, 5
ldi R16, 0b10000001 ; wgm 0b10000001 (61Hz) 0b10000010 (30,5Hz)
sts TCCR1A, R16
ldi R16, 0b1011 ; 0b1011
sts TCCR1B, R16 ; prescaler 64
ldi R16, 19 ; wypelnienie poczatkowe (19)
sts OCR1AL, R16
rcall napiecie
rcall temperatura
rcall Czekaj
rcall Czekaj
rcall Czekaj
;rcall Czekaj
;rcall Czekaj
lds R16, OCR1AL
inc R16
inc R16
sts OCR1AL, R16
nic:
wdr
sei
rcall czekaj
rcall czekaj
rcall czekaj
rcall czekaj
rcall prad
rjmp nic
zmien_PWM:
;sprawdzamy czy zalaczono uklad, jesli nie to wylaczamy
sbrs R20, 0
rjmp wylacz ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
rcall Czekaj ; jesli w ciagu okreslonego czasu przycisk zostanie puszczony to wylaczamy
zmieniam:
sbrs R20, 0
rjmp wylacz
; sprawdzam czy PWM jest podzielne przez 2 bez reszty, jesli tak to zwiekszam pwm, inaczej zmiejszam
mov R16, R21
lsr R16
in R16, SREG
sbrs R16, 0
rjmp PWM_PLUS
lds R16, OCR1AL
cpi R16, 23 ; nastawa minimum 22 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
brlo pozniej
dec R16
sts OCR1AL, R16
pozniej:
rcall Czekaj
; tu zmieniamy wypelnienie
; poniewaz zostało zmienione raz wypelnienie, oczekujemy na ponowna zmiana
in R16, PIND
sbrs R16, 3
rjmp zmien_PWM
; dodajemy obsługe zmiany wypelnienia w zaleznosci od R21 (+/-)
inc R21
rcall Czekaj
rcall Czekaj
rcall Czekaj
sei
rjmp nic
PWM_PLUS:
lds R16, OCR1AL
cpi R16, 25 ; nastawa maximum 25
brsh pozniej
inc R16
sts OCR1AL, R16
rjmp pozniej
temperatura:
ldi R16, 0b11000101 ; odpalam przetwornik ADC5 z Uref=1,1V i badam napiecie na czujniku temperatury
sts ADMUX, R16
ldi R16, 0b11000011
sts ADCSRA, R16
petla_temperatury: ; czekam na zakonczenie konwersji
lds R16, ADCSRA
sbrs R16, ADIF
rjmp petla_temperatury
lds R16, ADCL
lds R17, ADCH
ldi R22,0b00010000
sts ADCSRA, R22
rcall oblicz_temperature
ret
; ===================================== mierze napiecie ==========================================
napiecie:
; najpierw ustawiam stan niski na PC2, PC3, PC4
cbi PORTC,2
cbi PORTC,3
cbi PORTC,4
sbi DDRC,2
sbi DDRC,3
sbi DDRC,4
ldi R16, 0b11000001 ; odpalam przetwornik ADC1 z Uref=1,1V i badam napiecie na ADC1 poprzez rezystory R9, R10
sts ADMUX, R16
rcall czekaj ; czekamy na Uref
ldi R16, 0b11000011
sts ADCSRA, R16
petla_napiecia: ; czekam na zakonczenie konwersji
lds R16, ADCSRA
sbrs R16, ADIF
rjmp petla_napiecia
lds R16, ADCL
lds R17, ADCH
ldi R22,0b00010000 ; zeruje flage konca konwersju
sts ADCSRA, R22
; 790j-krytyczne(6,5V), 875j-1_d(7,2V), 899j-2_d(7,4V), 923j-3_d(7,6V), 947j-4_d(7,8V), 972j-5_d(8V)
ldi R18, 0x16 ; wpisuje 790
ldi R19, 0x03
cp R16, R18
cpc R17, R19
brsh napiecie_OK ; skocz jesli wieksze niz minimalne
rjmp wylacz
napiecie_OK: ; tutaj dodac kod wizualizujacy napiecie
ldi R18, 0xb3 ; wpisuje 947
ldi R19, 0x03
cp R16, R18
cpc R17, R19
brsh blysk_5 ; skocz jesli wieksze niz 8V
rjmp moze_4
blysk_5:
rcall LED_5
ret
; ==============================================================
moze_4:
ldi R18, 0x9b ; wpisuje 923
ldi R19, 0x03
cp R16, R18
cpc R17, R19
brsh blysk_4 ; skocz jesli wieksze niz 7,8V
rjmp moze_3
blysk_4:
rcall LED_4
ret
; ==============================================================
moze_3:
ldi R18, 0x83 ; wpisuje 899
ldi R19, 0x03
cp R16, R18
cpc R17, R19
brsh blysk_3 ; skocz jesli wieksze niz 7,6V
rjmp moze_2
blysk_3:
rcall LED_3
ret
; ==============================================================
moze_2:
ldi R18, 0x6b ; wpisuje 875
ldi R19, 0x03
cp R16, R18
cpc R17, R19
brsh blysk_2 ; skocz jesli wieksze niz 7,4V
rjmp moze_1
blysk_2:
rcall LED_2
ret
; ==============================================================
moze_1:
ldi R18, 0x52 ; wpisuje 850
ldi R19, 0x03
cp R16, R18
cpc R17, R19
brsh blysk_1 ; skocz jesli wieksze niz 7,2V
rjmp koniec_pomiaru
blysk_1:
rcall LED_1
ret
; ==============================================================
koniec_pomiaru:
lds R16, OCR1AL ; poniewaz mamy niskie napiecie, zwiekszamy PWM
inc R16
sts OCR1AL, R16
cbi DDRC,2 ; wyłączamy podciaganie do masy rezystora pomiarowego
cbi DDRC,3
cbi DDRC,4
ret
;
===========================================================================================
prad: ; sprawdzam czy prad jest jest odpowiedni (czy silnik pracuje) pomiar ADC6 (prog 17mV=15j)
ldi R16, 0b11000110 ; odpalam przetwornik ADC6 z Uref=1,1V i badam prad
sts ADMUX, R16
ldi R16, 0b11000011
sts ADCSRA, R16
ldi R16, 0
mov R15, R16
petla_pradu: ; czekam na zakonczenie konwersji
lds R16, ADCSRA
sbrs R16, ADIF
rjmp petla_pradu
lds R16, ADCL
lds R17, ADCH
add R15, R16
ldi R22,0b00010000
sts ADCSRA, R22
rcall czekaj
ldi R16, 0b11000011
sts ADCSRA, R16
petla_pradu1: ; czekam na zakonczenie konwersji
lds R16, ADCSRA
sbrs R16, ADIF
rjmp petla_pradu1
lds R16, ADCL
lds R17, ADCH
add R15, R16
ldi R22,0b00010000
sts ADCSRA, R22
rcall czekaj
ldi R16, 0b11000011
sts ADCSRA, R16
petla_pradu2: ; czekam na zakonczenie konwersji
lds R16, ADCSRA
sbrs R16, ADIF
rjmp petla_pradu2
lds R16, ADCL
lds R17, ADCH
add R15, R16
ldi R22,0b00010000
sts ADCSRA, R22
rcall czekaj
ldi R16, 0b11000011
sts ADCSRA, R16
petla_pradu3: ; czekam na zakonczenie konwersji
lds R16, ADCSRA
sbrs R16, ADIF
rjmp petla_pradu3
lds R16, ADCL
lds R17, ADCH
add R15, R16
ldi R22,0b00010000
sts ADCSRA, R22
mov R16, R15
cpi R16,10
brsh prad_OK ; skocz jesli wieksze niz minimalne
rjmp wylacz
prad_OK:
ret
; ===============================================================================================
Czekaj: ; ustawiam opoznienie 250ms CTC naT1 zliczam do 2000dec=07D0hex
; Timer1 ustawiam w trybie CTC(WGM01) z preskalerem 64(CS00, CS02) i zliczam do 2000 co daje nam 250ms
; OCIE01 ustawiam przerwanie
ldi R16, 0b10
out TCCR0A, R16
ldi R16, 0b101
out TCCR0B, R16 ; prescaler 1024
ldi R16, 255
out OCR0A, R16
nic1:
in R16, TIFR0
sbrc R16, OCF0A ; czekamy na ustawienie flagi
rjmp koniec ; jesli zostanie ustawiona to wychodzimy z petli nic1
nop
rjmp nic1
koniec:
ldi R16, 0
sts 0x44, R16
sts 0x45, R16
sts 0x47, R16
sbi TIFR0, OCF0A ; zerujemy flage
ret
; ====================================koniec petli opozniajacej===================================
oblicz_temperature: ; temperatura nie powinna przekraczac 65st.C czyli 0,65V (0,65*1024/1,1=605j)
ldi R18, 0x5d ; wpisuje 605
ldi R19, 0x02
cp R16, R18
cpc R17, R19
brsh wylacz ; skocz jesli wieksze niz wartosc maksymalna
ret
wylacz:
ldi R20, 0
ldi R21, 0
out PORTB, R20
out PORTC, R20
out PORTD, R20
out DDRB, R20
out DDRC, R20
out DDRD, R20
ldi R16, 0 ; wgm 0b10000001 (61Hz) 0b10000010 (30,5Hz)
sts TCCR1A, R16
ldi R16, 0 ; 0b1011
sts TCCR1B, R16 ; prescaler 64
spij:
rcall Czekaj
in R16, PIND ; czekam na puszczenie przycisku
sbrs R16, 3
rjmp spij
; ================== ustawiam tryb sleep jako POWER save ===================
ldi R16, 0b00000111 ; 101 -power down
sts SMCR, R16 ; ustawiam SMCR
; ==========================================================================
nop
sei
sleep
LED_1: ; program zapalajacy diode na jakis czas
; ================LED ON ====================
sbi DDRD, 5 ;
sbi PORTD, 5 ;
; ===========================================
rcall czekaj
; ================LED OFF ===================
cbi PORTD, 5
cbi DDRD, 5 ;
; ===========================================
ret
LED_2: ; program zapalajacy diode na jakis czas
; ================LED ON ====================
sbi DDRD, 5 ;
sbi PORTD, 5 ;
; ===========================================
rcall czekaj
; ================LED OFF ===================
cbi PORTD, 5 ;
; ===========================================
rcall czekaj
; ================LED ON ====================
sbi PORTD, 5 ;
; ===========================================
rcall czekaj
; ================LED OFF ===================
cbi DDRD, 5 ;
cbi PORTD, 5 ;
; ===========================================
ret
LED_3: ; program zapalajacy diode na jakis czas
; ================LED ON ====================
sbi DDRD, 5 ;
sbi PORTD, 5 ;
; ===========================================
rcall czekaj
; ================LED OFF ===================
cbi PORTD, 5 ;
; ===========================================
rcall czekaj
; ================LED ON ====================
sbi PORTD, 5 ;
; ===========================================
rcall czekaj
; ================LED OFF ===================
cbi PORTD, 5 ;
; ===========================================
; ===========================================
rcall czekaj
; ================LED ON ====================
sbi PORTD, 5 ;
; ===========================================
rcall czekaj
; ================LED OFF ===================
cbi DDRD, 5 ;
cbi PORTD, 5 ;
; ===========================================
ret
LED_4: ; program zapalajacy diode na jakis czas
; ================LED ON ====================
sbi DDRD, 5 ;
sbi PORTD, 5 ;
; ===========================================
rcall czekaj
; ================LED OFF ===================
cbi PORTD, 5 ;
; ===========================================
rcall czekaj
; ================LED ON ====================
sbi PORTD, 5 ;
; ===========================================
rcall czekaj
; ================LED OFF ===================
cbi PORTD, 5 ;
; ===========================================
; ===========================================
rcall czekaj
; ================LED ON ====================
sbi PORTD, 5 ;
; ===========================================
rcall czekaj
; ================LED OFF ===================
cbi PORTD, 5 ;
; ===========================================
; ===========================================
rcall czekaj
; ================LED ON ====================
sbi PORTD, 5 ;
; ===========================================
rcall czekaj
; ================LED OFF ===================
cbi DDRD, 5 ;
cbi PORTD, 5 ;
; ===========================================
ret
LED_5: ; program zapalajacy diode na jakis czas
; ================LED ON ====================
sbi DDRD, 5 ;
sbi PORTD, 5 ;
; ===========================================
rcall czekaj
; ================LED OFF ===================
cbi PORTD, 5 ;
; ===========================================
rcall czekaj
; ================LED ON ====================
sbi PORTD, 5 ;
; ===========================================
rcall czekaj
; ================LED OFF ===================
cbi PORTD, 5 ;
; ===========================================
; ===========================================
rcall czekaj
; ================LED ON ====================
sbi PORTD, 5 ;
; ===========================================
rcall czekaj
; ================LED OFF ===================
cbi PORTD, 5 ;
; ===========================================
; ===========================================
rcall czekaj
; ================LED ON ====================
sbi PORTD, 5 ;
; ===========================================
rcall czekaj
; ================LED OFF ===================
cbi PORTD, 5 ;
; ===========================================
; ===========================================
rcall czekaj
; ================LED ON ====================
sbi PORTD, 5 ;
; ===========================================
rcall czekaj
; ================LED OFF ===================
cbi DDRD, 5 ;
cbi PORTD, 5 ;
; ===========================================
ret
Teraz opis:
Program steruje reglem moelarskim, który steruje silnikiem BLDC.
Dodatkowo wyświetla stan naładowania 2 akumulatorów Li-Poli zasilających regiel. Regiel dodatkowo jest wyłączany MOSFETem (oszczędzanie energii)
Całością steruje microswitch w sposób:
a) krótkie wciśniecie i puszczenie (do 250ms) to właczenie bądz wyłączenie urządzenia
b) dłuższe przetrzymanie przycisku powoduje zwiększenie wypełnienia skokowo, kolejne dłuższe przytrzymanie powoduje zmniejszenie wypełnienia (kazde wcisniecie powoduje zmianę kierunku zwiększenie-zmniejszenie)
Dodatkowo podczas włączania urządzenia stan naładowania aku jest podawany na diodzie LED poprzez jej odpowiednia ilość mrugnięć
Opis problemu:
Wygląda na to, że przepełnia mi się stos bo po jakiejś minucie od podłączenia zasilania i niekorzystania z przycisku nie można juz obudzić kontrolera.
Jeśli ktoś ma ochote to byłbym wdzięczny o pomoc w znalezieniu błędu
Dodam, że te same problemy miałem z ATiny26, więc to nie wina płytki ani kontrolera tylko moja
Pozdrawiam
Opis elementów:
TS1 to TS2951cs-5V (stabilizator low drop low power 5V/150mA)
IRF1 to IRF7455 (MOSFET)
W punkcie "sterowanie" podłączony jest przycisk podciągniety R12 = 1MOhm do plusa
W punkcie "pomiar temperatury" podłączam wyjście LM35
LED, PWM to wyjścia odpowiednio sterujące dioda i reglem. LED może będzie 2 katodowy, do tego przewidziałem kolejne wyjście tuz nad pierwszym)
Na dole tuż nad polami do programowania jest także indukcyjność oznaczona prostokątem i literką L leżącą na diolnych pinachm, więc niewiele jej widać.
R8 steruje GATE mosfetu a R13(nad nim) podciąga ją do masy
R9-R10 to dzielnik napięciowy do pomiaru napięcia ogniw, włączany tylko w czasie pracy poprzez zwarcie R10 do masy (wczesniej odpowiednie wyprowadzenia kontrolera maja wysoką impedancję - pracuja jako wejścia)
C2 to tantal 10uF filtrujący zasilanie
Dodatkowo jest mierzony prąd pobierany przez regiel poprzez pomiar spadku napięcia na ścierzce 1mm X 35mm biegnącej tuż pod plusem zasilania i rezystorami R12, R9. (1A=17mV=15kwantów)