Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
PIC16F1827 HPWM Push-pull
#21
Upravu si nisam rekao da sam pisao u PicBasic Pro i sve rutine su pisane u PicBasic.
Evo i kompletan Kod:

Code:
define OSC 4

OSCCON=%01101000
TRISB=%00000000   ' Port B je izlazni
ANSELB=%0000000   ' Port B je digitalni
ms var word
PortB.0=0
PortB.1=0  

    
    INTCON.5 = 0            'Onemoguci TMR0 prekide
    
    ms=0
    
   OPTION_REG = %1000010    '010 preskaler postavi u odnos    1:8
   TMR0=6               'Postavi vrednost TMR0
            
    INTCON.5=1        'Omoguci TMR0 prekide
    INTCON.7=1        'Omoguci sve prekide

   ON INTERRUPT goto Int_Sub
'------------Glavni program--------------------------
Pocetak:
     
   
   
   
    
    Goto Pocetak
    
'------Podprogram obrade prekida-----------------------
      disable
Int_Sub:

   INTCON.7=0
   
  if INTCON.2 AND INTCON.5 THEN
   INTCON.2=0
       ms = ms + 2
       ENDIF
   
     if ms = 6 then    
    PortB.0=0
    ENDIF
   
  if ms = 10 Then
    PortB.1=1
    endif
   
  IF MS = 16 THEN
    PortB.1=0
    endif
   
  if ms = 20 then
    PortB.0=1
    ms = 0
    endif
   
   
   INTCON.7=1  'Omoguci prekide
   INTCON.5=1  'Omoguci prekide

   resume         'Vrati se iz rutine prekida

    End
Reply
#22
Milane,

Ti si ceo tvoj program smestio u interaptu, umesto u glavnoj petlji.
Glavna petlja ti je potpuno prazna : Početak - goto Početak i TO NE VALJA !

U interaptu samo ono što mora iza čega nema vremena u glavnoj petlji !

Dalje, pošto si koristi samo jedan interapt (TMR) nema nikakve potrebe da kroz uslov :
if INTCON.2 AND INTCON.5 THEN
INTCON.2=0
gasiš zastavicu INTCON.2

( a i kad se koristi više interapta upotrebljava se da tako nazovem - interapt semafor gde ispituješ koja
je zastavica podignuta, ugasiš tu zastavicu i obradjuješ taj interapt pa sledeći ...)

Jednostavno ulaskom u interpat prvo kažeš : INTCON.2=0
i onda samo na brzinu promeniš stanje : ms = ms + 2
i to je sve za interapt.

( ili samo podigneš neki unapred definisani bit u interaptu, pa zatim stanje tog bita testiraš u glavnom programu
ako je podignut bilo je uvećanja stanja "ms" i onda prvo ugasiš taj bit i onda radiš sve dalje u potprogramu)

Potom u glavnom programu obradjuješ stanja izlaznih pinova.
Vremena mora biti dovoljno ako si sve uradio kako treba !

Dalje, obavezno uradi i definiciju svih ostalih portova sa TRIS (port) i ako ih ne koristiš.
Po pravilu se ništa ne ostavlja ne definisano.

------------

Ništa ti ne valja to programče, piši sve iz početka (nema puno) - !

Pozz
Reply
#23
Nije problem da uslove i kontrolu stanja pinova prebacim u neki drugi potprogram a da samo brojac uvecavam u interapt potprogramu. 
Kako da iz interapta odmah odem na taj potprogram da zamenim stanje na pinovima jer sa instrukcijom RESUME se izlazi iz interapt potprograma i vraca se u glavnu petlju a meni treba da ode na potprogram za kontrolu stanja pinova.

Glavnu petlju sam ostavio praznu iz razliga jer planiram kasnije da u toj petlji kontroler radi druge stvari poput A/D konverzije i ostalu matematiku.
Reply
#24
A mogao bi koristiti i :

select case ms

case 6
PortB.0=0

case 10
PortB.1=1

case 16
PortB.1=0

case 20
PortB.0=1
ms = 0

end select


umesto silnih IF - Endif
Reply
#25
I treba da se vrati u glavnu petlju pošto ti je prazna, odnosno da se vrati na mesto u bilo kom potprogramu gde je trenutno bio PC pre odlaska u interapt.

Već sam ti rekao, podigni neki tvoj definisan bit u interaptu i testiraj taj bit u glavnom delu programa.
Reply
#26
Nismo se razumeli kada kontrolu pinova prebacim u glavnoj petlji to radi ali onda nemogu nista drugo da odradim u toj petlji.
Zbog toga ja hocu da odma nakon izlaska iz interrupt potprograma odem na kontrolu stanja pinova i zamenim stanje i nakon toga da se vratim u glavnoj petlji ali kojom instrukcijom.
Reply
#27
Može Milane, može ...

Ti nikako da ukapiraš !

Evo ti primer koji sam na brzinu skuckao da biu video o čemu pričam.
Ne tvrdim da nema greške, ali čisto da vidiš pristup :

define OSC 4

OSCCON=%01101000
TRISB=%00000000 ' Port B je izlazni
ANSELB=%0000000 ' Port B je digitalni
ms var word
Timerbit var bit
PortB.0=0
PortB.1=0


INTCON.5 = 0 'Onemoguci TMR0 prekide

ms=0

OPTION_REG = %1000010 '010 preskaler postavi u odnos 1:8
TMR0=6 'Postavi vrednost TMR0

INTCON.5=1 'Omoguci TMR0 prekide
INTCON.7=1 'Omoguci sve prekide

ON INTERRUPT goto Int_Sub
'------------Glavni program--------------------------
Pocetak:

gosub Izlazi
'--------- odavde pozovi AD konverziju itd ...
'-------------
Goto Pocetak

'------Podprogram obrade prekida-----------------------
disable
Int_Sub:
' Ovde samo podigni bit i beži napolje !!!
INTCON.2=0
Timerbit = 1
resume 'Vrati se iz rutine prekida
'-------------------------------------------------------
Izlazi:
if Timerbit = 0 then return ' Odmah napusti ako nije bilo TMR interapta
Timerbit = 0

select case ms

case 6
PortB.0=0

case 10
PortB.1=1

case 16
PortB.1=0

case 20
PortB.0=1
ms = 0

end select

endif
return
'---------------------------------------------------------
End

=============================================
Pozz
Reply
#28
Ups,

Evo sada vidim da nisam nigde uvećao vrednost "ms".
Trebalo je odmah iza : Timerbit = 0

Čak si mogao i ovako :

If ms < 20 then
ms = ms + 2
else
ms = 0
endif

i onda ne treba u case 20 da resetuješ vrednost "ms"

Zato ti i kažem : ne mogu ja ovako napamet pisati a nemati na čemu da izvršim program ...
Reply
#29
Evo napisao sam kako si zamislio:

 define OSC 4
 
OSCCON=%01101000
TRISB=%00000000   ' Port B je izlazni
ANSELB=%0000000   ' Port B je digitalni
ms var word
Timerbit var bit
PortB.0=0
PortB.1=0   


INTCON.5 = 0   'Onemoguci TMR0 prekide

ms=0

    OPTION_REG = %1000010    '010 preskaler postavi u odnos 1:8
    TMR0=6   'Postavi vrednost TMR0

INTCON.5=1 'Omoguci TMR0 prekide
INTCON.7=1 'Omoguci sve prekide

    ON INTERRUPT goto Int_Sub
'------------Glavni program--------------------------
Pocetak:

   Gosub Izlazi
      
   PortB.3=1
   pause 1000
   PortB.3=0
   pause 1000 


Goto Pocetak
 
'------Podprogram obrade prekida-----------------------
       disable
Int_Sub:

    
    INTCON.2=0
      Timerbit=1  
        ms = ms + 2 
     
    INTCON.7=1  'Omoguci prekide
    INTCON.5=1  'Omoguci prekide

    resume         'Vrati se iz rutine prekida
    
 '----------Podprogram za kontrolu I/O pinova----------------   
Izlazi: 
 If Timerbit=0 then return
     Timerbit=0


     select case ms

case 6
PortB.0=0

case 10
PortB.1=1

case 16
PortB.1=0

case 20
PortB.0=1
ms = 0

end select 


Return  

     End 


Ali ovako nece da radi a namerno sam u glavnom programu stavio da kontroler nesto drugo radi.
Tek kad ostavim slobodnu glavnu petlju tada radi uredno oscilovanje.
Razlog zbog kog nece ovo ovako da radi je sto se iz interapt potprograma skace direktno u glavnu petlju a trebalo bi odmah na potprogram IZLAZI.
Reply
#30
Ako ti vreme TMR od 2ms odgovara jo za nešto u programu, možeš upotrebiti još proizvoljan broj nekih brojača koji se mogu većavati ili smanjivati posle testiranja bita "Timerbit".

Mogu mikrokontroleri mnogoi toga obraditi istovremeno ( uslovno rečeno) - samo moraš imati pravilnu strukturu programa.

Pozz
Reply
#31
(11-28-2015, 10:49 PM)Milan94 Wrote: Razlog zbog kog nece ovo ovako da radi je sto se iz interapt potprograma skace direktno u glavnu petlju a trebalo bi odmah na potprogram IZLAZI.

Nisi pročitao da sam u medjuvremenu primetio grešku sa uvećanjem ms, što sam i napisao.

NE MOŽEŠ TI da odrediš gde će PC nastaviti posle izlaska iz interapta.
PC nastavlja isključivo sa adrese koju je odložio u STACK pre ulaska u interapt !


Dalje, ako tebi PC posle interapta dodje u na glavnu petlju, potprogram "izlazi" će se automatski izvršiti ako su za to stečeni uslovi ( a to su : bio je TMR interapt odnosno podignut je Timerbit ).
Jer , za sve vreme dok NISI u interaptu glavni program NON STOP poziva komandom GOSUB potprogram Izlazi i proverava da li je bilo TMR interapta putem stanja bita "Timerbit"
Reply
#32
Primetio sam taj propust sa uvecanje MS i odmah sam stavio ali to ovako nece da radi jer evo upravo sam to i testirao na hardveru i sve dosad sto je pisano to je i testirano.

Ovde je potrebno da se odmah nakon uvecanja ms skoci na labelu IZLAZI i nakon toga da se vratimo u glavni program.
Reply
#33
Sasvim sam ti dovoljno objasnio gde grešiš,
Zagrej malo stolicu, pažljivo sve ponovo napiši kako sam ti objasnio
(ne koristi Copy /Paste stari program koji si ti napisao a ja samo doradio) - već sve iz početka !
Mora da radi

Toliko oid mene
Pozz
Reply
#34
Kako uklonio kada u postu29 stoji odma ispod labele POCETAK gosub Izlazi naredba.

gosub naredba se izvrsava kada se dodje do nje u programu i ne poziva se NON STOP u tom programu koliko sam ja mogao da se informisem.
Reply
#35
Još jednom ti ponavljam ne možeš ti birati gde ćeš ići nakon izlaska iz interapta, to je već odredjeno stanjem na steku.
A ako ti je baš neophodno da što brže izvršiš promenu stanja bitova zavisno od stanja MS onda to možeš i da uradiš dok si još u interaptu.
Sa select case će ići brže neg sa mnoštvom if-then komandi, mada nije praksa da se dugo boravi u interaptu.
Treće ti nema !

(možda ima kod drugih jačih i moćnijih PIC-ova , nisam radio sa njima pa ne tvrdim)
Reply
#36
(11-28-2015, 11:15 PM)Milan94 Wrote: Kako uklonio kada u postu29 stoji odma ispod labele POCETAK gosub Izlazi naredba.

gosub naredba se izvrsava kada se dodje do nje u programu i ne poziva se NON STOP u tom programu koliko sam ja mogao da se informisem.

Učinilo mi se da si uklonio.

Kada imaš :

Main :

gosub Izlazi
goto main

Program STALNO poziva Izlazi i ako nije podignut Timerbit odmah se vraća (GOSUB-RETURN) i tako u krug !

Probaj odmah na početku Izlazi, a pre testiranja Timerbit-a upaliti i ugasiti LED pa ćeš se uveriti !
Reply
#37
Jasno je meni da ako uvek program nailazi na GOSUB instrukciju ona ce i biti izvrsena ali posto meni treba odmah nakon uvecanja promenljive da se odradi kontrola I/O pinova ja sam to stavio u potprogram za obradu interrupta.
Kada je glavni program prazan ili nema pauze u njemu onda interrupt lepo radi.

Evo iznova sam napisao cod i neradi jer imam u glavnom programu pauze.

Code:
define OSC 4

OSCCON=%01101000  ' Interni oscilator 4MHz
TRISA=%00000000   ' port A je izlazni
TRISB=%00000000   ' Port B je izlazni
ANSELB=%0000000   ' Port B je digitalni
ms var word       ' Promenljiva za milisekunde
PortB.0=0
PortB.1=0  

    
    INTCON.5 = 0            'Onemoguci TMR0 prekide
    
    ms=0
    
   OPTION_REG = %1000010    '010 preskaler postavi u odnos    1:8
       TMR0=6                    'Postavi vrednost TMR0
            
    INTCON.5=1        'Omoguci TMR0 prekide
    INTCON.7=1        'Omoguci sve prekide

   ON INTERRUPT goto Int_Sub
'------------Glavni program--------------------------
Pocetak:
     
  PortB.3=1
  pause 1000
  PortB.3=0
  pause 1000


    Goto Pocetak
    
'------Podprogram obrade prekida-----------------------
      disable
Int_Sub:

    ms = ms + 2   ' Uvecava se promenljiva
   INTCON.2=0     ' Gasi zastavicu
 
 
 select case ms

case 6
PortB.0=0

case 10
PortB.1=1

case 16
PortB.1=0

case 20
PortB.0=1
ms = 0

end select
   
   INTCON.7=1  'Omoguci prekide
   INTCON.5=1  'Omoguci prekide

   resume         'Vrati se iz rutine prekida
   
    End
Reply
#38
1. Već sam ti rekao da sam i ja imao problema sa upotrebom ON INTERRUPT i iz tog razloga sam i prešao na ASM interapte u PBP
2. Odma iza Int_Sub: treba prvo ugasiti zastavicu - pa onda sve ostalo
3. Komanda RESUME sama odradjuje sve što treba nakon napuštanja interapta - tako da je nepotrebno :
INTCON.7=1 'Omoguci prekide
INTCON.5=1 'Omoguci prekide

4. Na kraju krajeva, napiši interapte u ASM (nije teško - imaš primer u linku koji sam postavio) pa ćeš videti gde je probleem.
Može lako biti da se sudaraju PAUSE pbp kod i ON INTERRUPT.
Ako ovo nije tačno, u svakom slučaju DOBRO ĆE TI doći kasnije, interapt u ASM za bilo koji iole ozbiljniji softver.!

Pozz
Reply
#39
Kada se obraćaš direktno pinu koristi LOW ili HIGH taj pin,
A kada se obraćaš odredjenom bitu u okviru neke promenljive koristi 0 ili 1 za stanje tog bita.

I koristi SYMBOL da "krstiš taj pin"
recimo:

Symbol Relej = PORTD.4

posle kažeš samo :

Low Relej ili High Relej
Reply
#40
Posto sam port B postavio u digitalnom modu zato sam pisao nule i jedinice za njihova stanja.

Sto se tice Asemblera nisam nikada nista pisao u njemu na sta si konkretno mislio  da li samo ulaz u interrupt ili potprogram koji obradjuje interrupt rutinu da se napise u Asembleru.
Reply


Forum Jump:


Users browsing this thread: 10 Guest(s)