Dobry den,
Zacinam s programovanim PIC a ted resim problem s jednim projektem. Delam si doma takovou malou automatizaci a vyuzivam pro komunikaci PC s cidly a spinaci 1 wire sbernici. Spousta veci mi jiz uspokojive bezi a ted resim jeden maly problem s citacem. Chci pocitat pulzy (spotrebovana energie,prutok,vody atd.) a jednou za minutu precist stav pocitadla ridicim pocitacem.
Klasicky counter funguje dobre, to neni problem. Nicmene jeste sem chtel rozsirit moznosti citace a pocitat vice pulzu nez 255 za minutu. A tak jsem uvazoval, ze bych pocital kolikrat casovac pretekl a vysledek poslal jako 4 bitove cislo na portA. Na PC bych vynasobil 4 bitove cislo z portu A *255 a 8 bitove cislo zbytku z portu B k tomu secetl a tim bych ml presny vysledek poctu pulzu za jednu minutu. Po precteni by se PIC vyresetoval (MCLR) a tim by se program opakoval. Vse mi funguje ± uspokojive az na posledni krok a tim je zapis vysledneho poctu preteceni na portA.
Zkousel jsem i zapisovat vysledek do registru PORTA po bitech (prvni ctyri bity-myslel jsem ze muze byt problem v nakonfigurovani RA4 jako vstup counteru) a stejne to neslo
Muzete mi prosim poradit kde delam chybu . Predem diky marek
INCLUDE<P16F627A.INC>
__CONFIG _PWRTE_ON & _WDT_OFF & _MCLRE_OFF & _BODEN_OFF & _LVP_OFF & _INTRC_OSC_NOCLKOUT
PRETECENI equ 0x20 ; Odkladaci registr pro preteceni
org 00h
goto INIT
org 04h
goto PRERUS
PRERUS:
incf PRETECENI,f ; po preteceni bufferu zvedne hodotu registru PRETECENI +1
movf PRETECENI,W ; presun dat z registru W
movwf PORTA ; na port A
goto START
INIT:
bsf STATUS,RP0 ;inicializace uP
movlw b'00000000'
movwf TRISB
movlw b'00010000' ; RA0 az RA3 vystup RA4 -timer vstup
movwf TRISA
movlw b'10101000' ; nastavení citace a odpojeni pullup od portu B
movwf OPTION_REG ; s delickou 1:1 (delicka pripojena na WDT)
movlw b'10100000' ; Povoleni preruseni od TMR0
movwf INTCON
bcf STATUS,RP0
clrf PORTA
clrf PORTB
clrf PRETECENI
clrf TMR0
movlw d'250' ; test
movwf TMR0 ; test
START:
movf TMR0,W ; presun dat z TIMER0
movwf PORTB ; na port B
goto START
end
Tak uz pravdepodobne vim Problem bude asi v nastaveni komparatoru na PORTU A. Ted to vypada dle simu snad ze to funguje. Jeste sem upravil v programu par drobnosti a pak ho tu cely hodim. Snad bude mit nejaky zkusenejsi uzivatel fora cas a zkoukne mi na to.
No jestli je to definitivní verze nevím. Jedno je jisté, problémy teprve přijdou.
Přečti si prosím něco o přerušení, o nezbytném uložení registrů, příznacích přerušení a o návratu z přerušení. To co jsi napsal, považuji za naprosto dokonalou cestu do pekel.
pekne jednotne, vsetko na svojom mieste. Skus si niektory stiahnut otvorit upravit na tvoj procesor (628 je dost podobna ak sa nemylim hi hi hi) zaroven tam mas osetrene veci okolo prerusenia a podobne…
administrator: přiloženy externí soubory pic_set.zip (11.9 KB)
OK kazdopadne diky za konstruktivni kritiku. O tom preruseni jsem uz cosi cetl. Myslel jsem ze nebude treba okladat vsecky registry, ale asi jsem myslel spatne
Rozhodne prostuduju a zkusim se z toho poucit. Abych to shrnul mam spatne napsanou tu proceduru okolo preruseni ze ?
EDIT:
Jinac v simulatoru mi to chodi tak jak jsem planoval. A proto jsem si myslel ze by to i takhle mohlo ±fungovat
EDIT2:
Task jsem trochu postudoval - snad sem pochopil jak teda priste na to preruseni
Snad to bude uz lepsi
Pokud tam mam jeste nejakou dalsi botu tak budu rad za kazde dalsi nakopnuti. Jak jsem psal s PICama teprve zacinam (venuju se tomu poradne treti den) a uz mi neni 20 a tak mi to trochu hur leze do palice
INCLUDE<P16F627A.INC>
__CONFIG _PWRTE_ON & _WDT_OFF & _MCLRE_ON & _BODEN_OFF & _LVP_OFF & _INTRC_OSC_NOCLKOUT
PRETECENI equ 0x20 ; Odkladaci registr pro preteceni
TMP_W equ PRETECENI+1 ; temp preruseni
TMP_S equ PRETECENI+2 ; temp preruseni
TMP_PCL equ PRETECENI+3
org 00h
goto INIT
org 04h
goto PRERUS
PRERUS:
movwf TMP_W ; ulozeni hodnot registru W do TMP_W
movf STATUS,W ; ulozeni registru STATUS do W
clrf STATUS ; nastaveni banky 0
movwf TMP_S ; ulozit STATUS do TMP_S
movf PCLATH,W ; Totez pro PCLATH
movwf TMP_PCL
clrf PCLATH ; nastaveni banky 0
;------------------------
bcf INTCON,T0IF ; vynulovat priznak preruseni (pretekl casovac TMR0)
;------------------------------- procedury preruseni
incf PRETECENI,f ; po preteceni bufferu zvedne hodnotu registru PRETECENI +1
movf PRETECENI,W ; presun dat do registru W
movwf PORTA ; a nasledne z registru W na port A
movlw d'250' ; test
movwf TMR0 ; test
;------------------------------- (obnovení hodnot registru W a STATUS)
INT_END:
movf TMP_PCL,W
movwf PCLATH ; obnova PCLATH
movf TMP_S,W ; nacte TMP_S a ulozi do W
movwf STATUS ; obnova STATUS
swapf TMP_W,F ; prohodi nibble TMP_W a ulozi do W
swapf TMP_W,W ; obnova W
retfie
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
INIT:
movlw B'00000111' ; typ komparatoru (off)
movwf CMCON
bsf STATUS,RP0 ;inicializace uP
movlw b'00000000'
movwf TRISB
movlw b'00010000' ; RA0 az RA3 vystup RA4 -timer vstup
movwf TRISA
movlw b'10101000' ; nastavení citace a odpojeni pullup od portu B
movwf OPTION_REG ; s delickou 1:1 (delicka pripojena na WDT)
movlw b'10100000' ; Povoleni preruseni od TMR0
movwf INTCON ; v registru INTCON
bcf STATUS,RP0
clrf PORTA
clrf PORTB
clrf PRETECENI
clrf TMR0
movlw d'250' ; test
movwf TMR0 ; test
goto START
START:
movf TMR0,W ; presun dat z TIMER0
movwf PORTB ; na port B
goto START
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
Asm u piců nemá instrukce push a pop (ukládání na zásobník a vyzvedávání)? Ikdyž někdo tu psal o omezenym počtu úrovní (nevim jesli je jen pro adresy a pro data třeba není jinej v ram). Asi jsem zhejčkanej ze všech ostatních mcu. Ty ho totiž mají v ram a je tak velkej, jak je velká volná paměť. Pak se používá i pro zálohy registrů.
Asi nějak nechápu, co to vlastně má dělat. Psal jsi něco o 1w sběrnici a komunikaci s PC. Proč vypisuješ hodnoty paralelně na porty? Že v programu není komunikace po 1-wire chápu, kdo by to tu taky zkoumal. Ty výpisy mi ovšem jasný nejsou. Přeci si ty data můžeš nechat v ram a v simulátoru to snad bude vidět.
Ahoj je to jednoduche.
Na komunikaci PICu s ridicim pocitacem automatizace pouzivam jak uz jsem psal 1 wire sbernici. Konkretne na tuto aplikaci s obvody DS2408 (8 bitovy “spinac” dokaze spinat 8 kanalu a nebo precist jejich log.hodnotu po 1 wire+po vycteni dat dokaze generovat reset napr. pro ten pic) a 2x DS2413 (totez ale ve 2 bitech). No a takhle celkem jednoduse prectu po 1 wire v Linuxboxu pocty impulzu za 1 minutu nasnimane counterem s PICem ktere dale budu zpracovavat.
Jinak v simulatoru ten program facha presne dle zadani a tak doufam, ze to bude ok.
Tak jsem este trosku postudoval datasheet a tim padem jsem prepsal celou rutinu preruseni dle datasheetu (pochopil jsem ze je zadouci zalohovat registry pomoci swapf atd.) jeste jsem do programu doplnil volitelne prirazeni predelicky 2:1 ke counteru (jumper) a tim padem je rozsah rozsireny bez zmeny programu az na 8192 pulzu a to je pro mou potrebu pravdepodobne vice nez dostatecne. Rad bych poprosil o mistni odborniky o letmou kontrolu programu zda jsem zas neco neprehlidnul. O vikendu bych rad zmastil tistak a cely counter vyzkousel. Jen avizuji ze dle simulatoru to snad vse vypada OK. Predem diky
Marek
INCLUDE<P16F627A.INC>
__CONFIG _PWRTE_ON & _WDT_OFF & _MCLRE_ON & _BODEN_OFF & _LVP_OFF & _INTRC_OSC_NOCLKOUT
PRETECENI equ 0x20 ; Odkladaci registr pro preteceni
TMP equ 0x70 ; temp
TMP_W equ TMP+1 ; temp preruseni
TMP_S equ TMP+2 ; temp preruseni
org 00h
goto INIT
org 04h
goto PRERUS
PRERUS:
movwf TMP_W ; ulozeni hodnot registru W do TMP_W
swapf STATUS,W ; ulozeni registru STATUS s prehozenym nibble do W
bcf STATUS,RP0 ; Přepne vždy do BANKY 0
movwf TMP_S ; ulozit STATUS do TMP_S
;------------------------
bcf INTCON,T0IF ; vynulovat priznak preruseni (pretekl casovac TMR0)
;------------------------------- procedury preruseni
incf PRETECENI,f ; po preteceni bufferu zvedne hodnotu registru PRETECENI +1
movf PRETECENI,W ; presun dat do registru W
movwf PORTA ; a nasledne na port A
;movlw d'250' ; test
;movwf TMR0 ; test
;------------------------------- (obnovení hodnot registru W a STATUS)
INT_END:
swapf TMP_S,W ; nacte TMP_S a ulozi do W
movwf STATUS ; obnova STATUS
swapf TMP_W,F ; ulozi TMP_W do TMP_W s prehozenym nibble
swapf TMP_W,W ; ulozi TMP_W do W v puvodnim stavu pred prerusenim
retfie
; ****************************************************************************
; ************************** Inicializace uP ********************************
; ****************************************************************************
INIT:
; Komparator
banksel CMCON
movlw B'00000111' ; typ komparatoru (off)
movwf CMCON
; PORTA
banksel TRISA ; Vyber banky s registrem TRISA
movlw b'00010100' ; RA2 Jumper vstup,RA4 -timer vstup, ostatni vystup
movwf TRISA
; PORTB
banksel TRISB ; Vyber banky s registrem TRISB
movlw b'00000000' ; Cely PORTB vystupni
movwf TRISB
; Nastaveni preddelicky citace jumperem pri inicializaci obvodu log1= delicka 2:1
banksel PORTA ; Vyber banky s registrem PORTA
btfsc PORTA,2 ; Testuje hodnotu RA2 - jeli port v log.0 preskoci nasledujici instrukci
goto citac2
; Citac
banksel OPTION_REG ; Vyber banky s registrem OPTION_REG
movlw b'10101000' ; nastavení citace a odpojeni pullup od portu B
movwf OPTION_REG ; s delickou 1:1 (delicka pripojena na WDT)
goto INIT_CONT ; pokracuje v inicializaci
; Citac2
citac2
banksel OPTION_REG ; Vyber banky s registrem OPTION_REG
movlw b'10100000' ; nastavení citace a odpojeni pullup od portu B
movwf OPTION_REG ; s delickou 2:1 (delicka pripojena na TMR0)
INIT_CONT:
; Nastaveni preruseni
banksel INTCON ; Vyber banky s registrem INTCON
movlw b'10100000' ; Povoleni preruseni od TMR0
movwf INTCON ; v registru INTCON
;************ Zpet do banky 0***************
banksel PORTA
clrf PORTA
clrf PORTB
clrf PRETECENI
clrf TMR0
;movlw d'250' ; test
;movwf TMR0 ; test
goto START
; ****************************************************************************
; **************************** Hlavni smycka *********************************
; ****************************************************************************
START:
movf TMR0,W ; presun dat z TIMER0
movwf PORTB ; na port B
goto START
; ****************************************************************************
; ******************************** KONEC *************************************
; ****************************************************************************
end
Diky moc za kontrolu - sem rad , ze sem to nakonec nejak zmastil Jinak s tou implementaci 1 wire by to bylo asi fakt lepsi , ale zatim sem si na to netroufal. Cosi sem hledal na netu, ale nenasel sem nic co by se mi asi mohlo na mou aplikaci hodit - potrebuju at lze data precist na linuxu pomoci projektu OFWS a nevim jestli by to bylo s PICem mozne. Pokud ano byl bych moc rad za nakopnuti spravnym smerem (sehnat DS2408 neni zrovna jednoduche).