» »

PIC18F4550 in ds18s20

PIC18F4550 in ds18s20

korenje_ver2 ::

A kdo ve kako se tole pravilno usposobi na tem PICu?

Imam takole:

CLRF na vse porte, trise, late...

.TERMOPIN_HI MACRO
BSF TTERMO
ENDM

.TERMOPIN_LO MACRO
BCF LTERMO
BCF TTERMO
ENDM

_ibutton_INIT
.led1 .1
.TERMOPIN_HI
.TERMOPIN_LO
MOVLW .50
CALL _delay_ms, FAST ; 500 us
.TERMOPIN_HI
MOVLW .7 ; 70 us
CALL _delay_ms, FAST
_asd
BTFSC TERMO
goto _asd
.led1 .100
MOVLW .50
CALL _delay_ms, FAST ; 500 us
RETURN FAST


Ok dejstvo je, da bi moral program zaznati pulldown od senzorja, vendar ga ne, zato nastane tukaj neskončni loop.

Ko preverim z multimetrom, opazim, da pade voltaža na pinu na 0V parkrat... sumljivo, vendar je loop še vedno v neskončnost. Kaj sem naredil narobe?

(L pred TERMO je latch, T pa tris)

TESKAn ::

Pobriši še port od termo pina, torej BCF PORTX,y.
Uf! Uf! Je rekel Vinetou in se skril za skalo,
ki jo je prav v ta namen nosil s seboj.

Highlag ::

Pa imaš vhod nastavljen kot digitalnega? Da ni slučajno vklopljen A/D pretvornik ali kaj podobnega?

Poleg tega lahko pin nastaviš kot vhod ali izhod. Ko vlečeš pin na ničlo mora biti izhod, ko pa čakaš na podatke pa mora biti vhod. Drugače zadeva ne bo delovala.. Sploh pa ima sam Dallas kar en kos kode za Pice in DS1820 napisane na njihovih straneh malo pobrskaj.
Never trust a computer you can't throw out a window

korenje_ver2 ::

Takole mam...
#INCLUDE "macros.inc"

ORG H'0000'
GOTO MAIN0
ORG H'0008' ; 2 cycles = interrupt
INCF #timer0 ; 1 cycle = INCF
BCF INTCON, TMR0IF ; 1 cycle = BCF
BTFSS STATUS, OV
RETFIE FAST
INCF #timer1
BTFSC STATUS, OV
CALL _error_counteroverflow, FAST ; > 655 sec
RETFIE FAST


#INCLUDE "subs_timers.inc"
#INCLUDE "subs_time.inc"
#INCLUDE "subs_lcd.inc"
#INCLUDE "subs_menus.inc"
#INCLUDE "subs_termometer.inc"
#INCLUDE "subs_buttons.inc"

MAIN0:
CLRF PCLATU
CLRF TBLPTRU
; ***** USB
BCF UCON, USBEN ; on-chip usb disabled
BSF UCFG, UTRDIS ; on-chip transciver disabled
; ***** ALL PORTS TO DIGITAL
MOVLW H'000F'
MOVWF ADCON1
; ***** CONFIGURE PORTA
CLRF PORTA
CLRF LATA
CLRF TRISA
; ***** CONFIGURE PORTB
CLRF PORTB
CLRF LATB
CLRF TRISB
; ***** CONFIGURE PORTC
CLRF PORTC
CLRF LATC
CLRF TRISC
; ***** CONFIGURE PORTD
CLRF PORTD
CLRF LATD
CLRF TRISD
; ***** CONFIGURE PORTE
CLRF PORTE
CLRF LATE
CLRF TRISE
; ***** OSCCON
; BSF OSCCON, IRCF2
; BSF OSCCON, IRCF1
; BSF OSCCON, IRCF0
; BCF OSCCON, SCS1
; BSF OSCCON, SCS0
; ***** TIMER1
; MOVLW 80h ; intterupt at 1 second
; MOVWF TMR1H
; CLRF TMR1L
; BSF T1CON, TMR1ON ; enable timer1
; BSF PIE1, TMR1IE ; timer1 overflow interrupt
; ***** TIMER0
BSF INTCON, TMR0IE ; timer0 overflow interrupt
MOVLW B'10000000'
MOVWF T0CON
; ***** INITIALIZE stuff
CALL _init_timers, FAST
CALL _init_time, FAST
; CALL _init_lcd, FAST
; CALL _init_buttons, FAST
CALL _init_termometer, FAST
; CALL _menu_init, FAST
; ///////// Check for reset
BTFSC STKPTR, STKFUL ; stack overflow reset occured
CALL _#stkful
BTFSC STKPTR, STKUNF ; stack underflow reset occured
CALL _#stkunf
BTFSS RCON, TO ; watchdog time-out occured
CALL _#to
BTFSS RCON, RI ; reset occured
CALL _#ri
; ///////// check for reset
; ***** ENABLE INTERRUPTS
BSF INTCON, GIE
MAIN:
TSTFSZ #timer0 ; #timer0 set in interrupt
CALL _timer0, FAST
TSTFSZ #timer1
CALL _timer0, FAST
BTFSC BUP
BSF #checkups, 2h
BTFSC BDOWN
BSF #checkups, 3h
BTFSC BCENTER
BSF #checkups, 4h
GOTO MAIN


Pobriši še port od termo pina, torej BCF PORTX,y.


kje točno?

ko dam pin na low, al na high (pull-up)?

Zgodovina sprememb…

TESKAn ::

Interrupt rutino imaš narobe napisano - moraš shranit status in W register ter ju ob koncu obnovit. Nadalnje ti imaš vse IO porte kot izhode? Bolje, da jih daš kot vhode in imaš izhode samo na pinih, kjer to potrebuješ. Če ti kaj pomaga, je tu moja koda za onewire v assemblerju - narejena sicer za PICa 16f876, ma princip je enak.

kje točno?

ko dam pin na low, al na high (pull-up)?


Ko daš pin na low.
Uf! Uf! Je rekel Vinetou in se skril za skalo,
ki jo je prav v ta namen nosil s seboj.

Zgodovina sprememb…

  • spremenil: TESKAn ()

korenje_ver2 ::

Interrupt rutino imaš narobe napisano - moraš shranit status in W register ter ju ob koncu obnovit. Nadalnje ti imaš vse IO porte kot izhode? Bolje, da jih daš kot vhode in imaš izhode samo na pinih, kjer to potrebuješ. Če ti kaj pomaga, je tu moja koda za onewire v assemblerju - narejena sicer za PICa 16f876, ma princip je enak.

kje točno?

ko dam pin na low, al na high (pull-up)?


Ko daš pin na low.


Ni potrebno shraniti W registra. Interrupt naj bi v 18F2550 in 4550 to napravil sam. Sem pa videl errato, da pri nekaterih tipih to ne naredi...

btw, teska, tudi z bcf ne dela...

Pa je normalno, da če naredim kratek stik med 0V in 1wire busom, da mi dejansko ves tok požre, in resetira PIC?
vprašanje če nism gnd in vdd narobe obrno. ker američani imajo glih obratno projekcijo :S
bom zdej probu obratno pospajkat ^^

edit: k zdej sm obrnu in če dam stik z 0V, gre ven iz loopa. termometer sam pa noče it :S
je možno da sem skuril termometer ali kaj podobnega, ko sem obrnil pola? (1amp) mam drgač.

delaaa...
^^
sem moral dodati še nekaj časa po datapin high... ker je bil pin vedno low, pa sem ga dal na hi samo za par nanosekund. tko da.

Zgodovina sprememb…

TESKAn ::


delaaa...

Me veseli :).
Uf! Uf! Je rekel Vinetou in se skril za skalo,
ki jo je prav v ta namen nosil s seboj.

korenje_ver2 ::

ok ne dela. ^^

init pulz dobim nazaj.... pol ko je treba pa podatke poslat, pa ne dela. :S

korenje_ver2 ::

Teska, mogoče veš zakva ne dela tole?

Vedno mi prikaže FFFFFF na lcdju. (če naredim stik z 0V in 1wire busom, potem prikaže 000000 na lcdju...

Kako lahko stestiram, če mi komunikacija dela? read rom?

Prilagam datoteko...

Zgodovina sprememb…

TESKAn ::

Hm, kjer nastavljaš pin na LOW, pobriši po spremembi porta na input še data register za tisti pin, da bo vsakič zagotovo dalo na nič.

Kot drugo, ko bereš vrednost, namesto da brišeš vsak bit posebej, pobriši celo spremenljivko na začetku - manj dela :).
Transmitt rutina ti pa ne bo delovala - ti pošiljaš podatek, ki ga imaš shranjenega v WREG registru, ampak vsakič, ko pokličeš rutino za pošiljanje, imaš v njej ukaz MOVLW - ta ti pa da nek drug podatek. Z drugimi besedami - podatek, ki ga ti pošiljaš, spreminjaš med pošiljanjem. Ustvari si novo spremenljivko in takoj, ko prideš v rutino za pošiljanje, spravi noter vsebino W registra in nato beri iz nje podatke za pošiljanje. Torej kot je trenutno narejeno, ti pošiljaš kdovekaj.

Nato lahko postaviš celo rutino za pisanje v eno zanko - greš skozi zanko 8 - krat, vsakič preveriš bit0 za pošiljanje, na koncu rutine pa shiftaš podatek v desno (RRCF ukaz).
Uf! Uf! Je rekel Vinetou in se skril za skalo,
ki jo je prav v ta namen nosil s seboj.

korenje_ver2 ::

evo zrihtu sm ^^

Sam mi je vseeno sumljivo, da moja zadevščina ni delovala...
v glavnem zdej mi prikaže prve 3 bajte v hex. bom probal še za read uporabit ta rrcf, da ne bo koda tako velika ^^


_ibutton_send_byte
MOVWF #buffer+0
MOVLW .8
MOVWF #buffer+1
__ibutton_send_byte
RRCF #buffer+0, F
BTFSS STATUS, C
CALL _ibutton_write_0, FAST
BTFSC STATUS, C
CALL _ibutton_write_1, FAST
DECFSZ #buffer+1
GOTO __ibutton_send_byte
RETURN FAST


sam ni mi jasno, zakaj moram dati 8 v #buffer+1. Če uporabim WREG, mi ne dela :S
Ni mi jasno, kaj bi lahko tukaj spremenilo wreg.

Zgodovina sprememb…

TESKAn ::

wreg je delovni register in je samo eden. Ti si najprej spravil v wreg podatek, ki si ga hotel poslat in poklical rutino za pošiljanje. Nato si iz te rutine klical podrutino za pošiljanje enega bita, v kateri si v taisti wreg naložil zakasnitev za delay funkcijo. Ko se vrneš iz te podrutine za pošiljanje bita, se ti wreg nikjer ne obnovi. To, da kličeš podrutine z FAST parametrom ti nič ne pomaga, ker uporabljaš interrupte in se FAST stack porabi zanje in ga ne moreš uporabit za klice svojih rutin.
Uf! Uf! Je rekel Vinetou in se skril za skalo,
ki jo je prav v ta namen nosil s seboj.

korenje_ver2 ::

čudn mi je to. RETFIE FAST naj bi obnovil wreg in ostalo, podobno kot return fast.

:S

datasheet pravi:

5.1.3 FAST REGISTER STACK
A Fast Register Stack is provided for the STATUS,
WREG and BSR registers to provide a “fast return”
option for interrupts. Each stack is only one level deep
and is neither readable nor writable. It is loaded with the
current value of the corresponding register when the
processor vectors for an interrupt. All interrupt sources
will push values into the stack registers. The values in
the registers are then loaded back into their associated
registers if the RETFIE, FAST instruction is used to
return from the interrupt.
If both low and high priority


Na pamet mi pride samo to, da sem nekje pozabil uporabit RETURN FAST, in mi dejansko skoči en level nižje po stacku, kjer ne bi smelo.

Zgodovina sprememb…

TESKAn ::

Beri še naprej. Najprej:
If both low and high priority interrupts are enabled, the
stack registers cannot be used reliably to return from
low priority interrupts. If a high priority interrupt occurs
while servicing a low priority interrupt, the stack register
values stored by the low priority interrupt will be
overwritten. In these cases, users must save the key
registers in software during a low priority interrupt.

in nato še:
If interrupt priority is not used, all interrupts may use the
Fast Register Stack for returns from interrupt. If no
interrupts are used, the Fast Register Stack can be
used to restore the STATUS, WREG and BSR registers
at the end of a subroutine call. To use the Fast Register
Stack for a subroutine call, a CALL label, FAST
instruction must be executed to save the STATUS,
WREG and BSR registers to the Fast Register Stack. A
RETURN, FAST instruction is then executed to restore
these registers from the Fast Register Stack.

Predvsem tale del:
If no
interrupts are used, the Fast Register Stack can be
used to restore the STATUS, WREG and BSR registers
at the end of a subroutine call.


Torej če uporabljaš interrupte, ne moreš porabit FAST stacka za rutine, ker imaš samo enega in ta je namenjen interruptom. Ta ti pa lahko prileti kjerkoli, tudi, ko ti ravno kličeš eno subrutino z FAST parametrom in ti shrani noter svojo verzijo registrov. In če se ne motim, imaš timer interrupt za zakasnitev, torej se ti sproži interrupt vsaj enkrat med tem čakanjem, kar pomeni povožen w register - seveda, če ti compiler sploh upošteva FAST v kodi.
Uf! Uf! Je rekel Vinetou in se skril za skalo,
ki jo je prav v ta namen nosil s seboj.

snow ::

Kaj če bi lepo 1-wire rutino na strani od maxima vzel?
Random mutation plus nonrandom cumulative natural selection - Richard Dawkins

korenje_ver2 ::

teska, je pa tut res, da ne uporabljam wreg-a v interruptu...

ORG H'0008'
INCF #timer0
BCF INTCON, TMR0IF
BTFSS STATUS, OV
RETFIE FAST
INCF #timer1
BTFSC STATUS, OV
CALL _error_counteroverflow, FAST ; > 655 sec
RETFIE FAST

Uporabljam tudi samo en interrupt in ne uporabljam interrupt prioritet.

snow, 1wire komunikacijo sem že zrihtal ^^

hm. odčitava mi stalno 168.0°C...

pošljem 44h, potem BEh... čudno.

če se da komu pogledat kaj je narobe, bi bilo lepo ^^

http://the-nox.com/ibm60gb/subs_termome...

oz. FF07.

za 2. bajt vem da mora biti FF ali 00.
tako da je pri meni malo čudno... FF pomeni 255°C...

Zgodovina sprememb…

TESKAn ::

teska, je pa tut res, da ne uporabljam wreg-a v interruptu...

Mikrokontroler ob vsakem interruptu shrani w register v fast stack, ne glede na to, ali ti potem uporabljaš w register ali ne in ne glede na to, ali imaš prioriteto ali ne. Če uporabljaš prioriteto je še malo bolj zanimivo, ker moraš v interruptih z niko prioriteto sam shranjevat te registre, saj ti jih lahko interrupt z visoko prioriteto povozi.

Kar se temperature tiče, ne moreš merit temperatur, višjih od 125°C. In če pogledaš v datasheet, vidiš, da je zgornjih 7 bitov v spodnjem bajtu tvoja temperatura v °C, najnižji bit pa pomeni 0,5°C. Torej za izračun temperature imaš zgornji bajt za predznak, spodnji bajt pa shiftaš desno za eno mesto, počistiš bit7 in to je tvoja temperatura v °C. čisto spodnji bit pa ti da še +(-)0,5°C, pač glede na predznak. FF07 tako pomeni -3,5°C.
Uf! Uf! Je rekel Vinetou in se skril za skalo,
ki jo je prav v ta namen nosil s seboj.

korenje_ver2 ::

fora je v tem, da se mi temperatura nč ne spreminja.... dejansko dobim vedno iste bajte vn.

in prvi bajt naj bi bil temperatura, drugi pa FF ali 00. no pri meni je drugi bajt 07 prvi pa FF.

:S

edit:
ok sem sprobal z drugim termometrom, pa dela...
očitno sem prvega skuril ali kaj podobnega... sam mi je čudno, ker normalno prikaže id senzorja.

hm MSB dobim 1, LSB pa 9E.

torej 019E.

Kera temperatura naj bi to bila...

torej 019h = pred decimalko, 0xE pa za decimalko?
to se mi zdi še najbolj logično...

ok še en senzor sm uniču izgleda...

namesto LSB in HSB mi pošilja 05 50. Začelo se je kar od enkrat...

teska mogoče veš kaj o tem?

Zgodovina sprememb…

korenje_ver2 ::

v glavnem vse sem že skoraj zrihtal... samo še nastavljivost preklapljanja relejev, pa analogni termometer, pa koračni motor...

drgač pa link do videota

Pa če ima kdo kodo za analogni pt100 ali pt1000 temperaturni senzor, bi je bil zelo vesel ^^
pa vezje me tudi zanima.

snow ::

Random mutation plus nonrandom cumulative natural selection - Richard Dawkins


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

esembler-hitro

Oddelek: Programiranje
111463 (1151) aaaaa93
»

programiranje procesorja (strani: 1 2 3 48 9 10 11 )

Oddelek: Elektrotehnika in elektronika
50536613 (26014) icek
»

PIC 16f84A - utripanje

Oddelek: Elektrotehnika in elektronika
222210 (2010) ql000
»

ideja: koda za razne mikrokontrolerje na enem mestu

Oddelek: Elektrotehnika in elektronika
73693 (3170) neoto
»

mikrokontrolerji, programatorji, c/asm ?

Oddelek: Elektrotehnika in elektronika
292986 (2605) snow

Več podobnih tem