citac s PIC + vystup 8 bitu pro DS2408 - Problem

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

Ten výsledek by byl nepřesný. Násobit bys musel číslem 256.
Na program snad mrkne někdo jiný.

jj asi mas pravdu mi uz dneska z toho vseho parkuje mozek :slight_smile: sem to bral ze to bude oddychovy program a takhle me to vypeklo :slight_smile:

Tak uz pravdepodobne vim :slight_smile: 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.

Takze snad definitivni verze:

INCLUDE<P16F627A.INC>
	__CONFIG _PWRTE_ON & _WDT_OFF & _MCLRE_ON & _BODEN_OFF & _LVP_OFF & _INTRC_OSC_NOCLKOUT

PRETECENI		equ			0x20	; Odkladaci registr pro preteceni 

	org		00h
	goto	INIT

	org	04h
	goto PRERUS 




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	

START:
	
		movf		TMR0,W			; presun dat z TIMER0
		movwf		PORTB			; na port B
		goto		START


PRERUS:
	incf		PRETECENI,f			; po preteceni bufferu zvedne hodnotu registru PRETECENI +1
	movf		PRETECENI,W			; presun dat z registru W
	movwf		PORTA				; na port A
	bsf			STATUS,RP0
	movlw		b'10100000'			; Povoleni preruseni od TMR0
	movwf		INTCON				; v registru INTCON
	bcf			STATUS,RP0
;	movlw		d'250'	;	test
;	movwf		TMR0	;	test
	goto START


end

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.

kolko ze to je urovnovy zasobnik 8 :smiley: spust simulaciiu a uvidis co to spravy.

Inak na strankach dovedy…su pekene ukazky ako by mohol vyzerat asm.
doveda.byl.cz/programy/pic_set.zip

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…

:arrow_right: 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 :slight_smile:
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 :slight_smile:
Snad to bude uz lepsi :slight_smile:
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 :slight_smile:


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

Nenašel jsem tam zásadní problém. Vypadá to dobře. Ať se ti daří při vývoji!

nebolo by lepsie implementovat 1wire zbrnicu priamo do procesora…

Diky moc za kontrolu - sem rad , ze sem to nakonec nejak zmastil :slight_smile: 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).