PIC 16F887 en MikroBasic

Arco

Special Member

De file heet ook geen pic16f1827.inc... ;)
De porta equate moet weg, want die bestaat al. (haakje achter END ook)
Gaat hier zonder problemen door de assembler heen...

pic asm code:


;**********************************************************************
                #include <p16f1827.inc>     ;processor specific variable definitions
   				__CONFIG _CONFIG1, _FOSC_HS & _WDTE_OFF & _BOREN_ON & _PWRTE_ON & _CP_OFF & _CPD_OFF & _MCLRE_OFF & _IESO_ON
				__CONFIG _CONFIG2, _LVP_OFF & _PLLEN_OFF & _BORV_19
;**********************************************************************
teller		EQU	40h
teller2	        EQU	41h

                ORG	00h     	;beginadres kiezen

		BSF 	03,5		;kies bank 1
		CLRF	trisa	        ;alles pinnen poort A uitgang maken
	    	BCF 	03,5		;kies bank 0

knipper	        MOVLW	01h		;laad 01h in W
		MOVWF	porta		;zet de waarde van W
				        ;in porta, oftewel zet de led aan

                MOVLW	0FFh		;laad 0FFh in W
		MOVWF	teller2
verder          MOVLW	0FFh
		MOVWF	teller
opnieuw         DECFSZ	teller, 1
		GOTO	opnieuw
		DECFSZ	teller2, 1
		GOTO	verder

		MOVLW	00h		;laad 00h in W
		MOVWF	porta		;zet de waarde van W
					;in porta, oftwel doe de led uit

                MOVLW	0FFh		;1 cycle
		MOVWF	teller2		;1 cycle
again		MOVLW	0FFh		;1 cycle
		MOVWF	teller		;1 cycle
again2	        DECFSZ	teller, 1       ;1 cycle
		GOTO	again2		;2 cycles
	        DECFSZ	teller2, 1
		GOTO	again

		GOTO	knipper	
		END
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Arco

Special Member

Het geknoei met bits om een bank te kiezen is een hele slechte gewoonte, beter banksel gebruiken:

pic asm code:


;**********************************************************************
                #include <p16f1827.inc>     ;processor specific variable definitions
   				__CONFIG _CONFIG1, _FOSC_HS & _WDTE_OFF & _BOREN_ON & _PWRTE_ON & _CP_OFF & _CPD_OFF & _MCLRE_OFF & _IESO_ON
				__CONFIG _CONFIG2, _LVP_OFF & _PLLEN_OFF & _BORV_19
;**********************************************************************
teller		EQU	40h
teller2	        EQU	41h

                ORG	00h     	;beginadres kiezen

		BANKSEL TRISA		;kies bank 1
		CLRF	TRISA	        ;alles pinnen poort A uitgang maken

	    	BANKSEL LATA		;kies bank 0
knipper	        MOVLW	01h		;laad 01h in W
		MOVWF	LATA		;zet de waarde van W
				        ;in porta, oftewel zet de led aan

                MOVLW	0FFh		;laad 0FFh in W
		MOVWF	teller2
verder          MOVLW	0FFh
		MOVWF	teller
opnieuw         DECFSZ	teller, 1
		GOTO	opnieuw
		DECFSZ	teller2, 1
		GOTO	verder

		MOVLW	00h		;laad 00h in W
		MOVWF	LATA		;zet de waarde van W
					;in porta, oftwel doe de led uit

                MOVLW	0FFh		;1 cycle
		MOVWF	teller2		;1 cycle
again		MOVLW	0FFh		;1 cycle
		MOVWF	teller		;1 cycle
again2	        DECFSZ	teller, 1       ;1 cycle
		GOTO	again2		;2 cycles
	        DECFSZ	teller2, 1
		GOTO	again

		GOTO	knipper	
		END
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Gaat hier zonder problemen door de assembler heen...

Hier niet echt..

Release build of project `C:\Pic\Ledje\Ledje.disposable_mcp' started.
Language tool versions: MPASMWIN.exe v5.51, mplink.exe v4.49, mplib.exe v4.49
Fri Nov 08 19:21:32 2019
----------------------------------------------------------------------
Clean: Deleting intermediary and output files.
Clean: Done.
Executing: "C:\Program Files (x86)\Microchip\MPASM Suite\MPASMWIN.exe" /q /p16F1827 "Ledje.asm" /l"Ledje.lst" /e"Ledje.err"
Message[303] C:\PIC\LEDJE\LEDJE.ASM 3 : Program word too large. Truncated to core size. (FF82)
Message[303] C:\PIC\LEDJE\LEDJE.ASM 4 : Program word too large. Truncated to core size. (DEFF)
Warning[232] C:\PIC\LEDJE\LEDJE.ASM 11 : STATUS register has no IRP or RP1 or RP0 bits
Error[113] C:\PIC\LEDJE\LEDJE.ASM 12 : Symbol not previously defined (trisa)
Warning[232] C:\PIC\LEDJE\LEDJE.ASM 13 : STATUS register has no IRP or RP1 or RP0 bits
Error[113] C:\PIC\LEDJE\LEDJE.ASM 16 : Symbol not previously defined (porta)
Error[113] C:\PIC\LEDJE\LEDJE.ASM 29 : Symbol not previously defined (porta)
Message[303] C:\PIC\LEDJE\LEDJE.ASM 42 : Program word too large. Truncated to core size. (FF82)
Message[303] C:\PIC\LEDJE\LEDJE.ASM 42 : Program word too large. Truncated to core size. (DEFF)
Halting build on first failure as requested.
----------------------------------------------------------------------
Release build of project `C:\Pic\Ledje\Ledje.disposable_mcp' failed.
Language tool versions: MPASMWIN.exe v5.51, mplink.exe v4.49, mplib.exe v4.49
Fri Nov 08 19:21:33 2019
----------------------------------------------------------------------
BUILD FAILED

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

De porta equate moet weg, want die bestaat al.

Maar waar staat deze dan?

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

De laatste versie vertaalt wel, maar met wat messages:

pic asm code:

Clean: Deleting intermediary and output files.
Clean: Done.
Executing: "C:\Program Files (x86)\Microchip\MPASM Suite\MPASMWIN.exe" /q /p16F1827 "Ledje.asm" /l"Ledje.lst" /e"Ledje.err"
Message[303] C:\PIC\LEDJE\LEDJE.ASM 3 : Program word too large.  Truncated to core size. (FF82)
Message[303] C:\PIC\LEDJE\LEDJE.ASM 4 : Program word too large.  Truncated to core size. (DEFF)
Message[302] C:\PIC\LEDJE\LEDJE.ASM 12 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\PIC\LEDJE\LEDJE.ASM 16 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\PIC\LEDJE\LEDJE.ASM 29 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[303] C:\PIC\LEDJE\LEDJE.ASM 42 : Program word too large.  Truncated to core size. (FF82)
Message[303] C:\PIC\LEDJE\LEDJE.ASM 42 : Program word too large.  Truncated to core size. (DEFF)
Executing: "C:\Program Files (x86)\Microchip\MPASM Suite\mplink.exe" /p16F1827 "Ledje.o" /z__MPLAB_BUILD=1 /o"Ledje.cof" /M"Ledje.map" /W /x
MPLINK 4.49, Linker
Device Database Version 1.14
Copyright (c) 1998-2011 Microchip Technology Inc.
Errors    : 0

Loaded C:\Pic\Ledje\Ledje.cof.
----------------------------------------------------------------------
Release build of project `C:\Pic\Ledje\Ledje.disposable_mcp' succeeded.
Language tool versions: MPASMWIN.exe v5.51, mplink.exe v4.49, mplib.exe v4.49
Fri Nov 08 19:34:36 2019
----------------------------------------------------------------------
BUILD SUCCEEDED
  
Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

PORTA is een standaard PIC register, die bestaan allemaal al (staan ook in de p16f1827.inc)
Er staat toch 'build succeeded'???
(die warnings stellen vaak niet veel voor. de bank warnings kun je onderdrukken met ERRORLEVEL - 302)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Hij heeft inderdaad 'gebuild'. Ik focuste me op de messages, maar die zijn niet zo erg begrijp ik.

De schakeling werkt, de led knippert, zij het dat het niet met het oog zichtbaar is.
Ik heb de scoop er even bij gepakt en de knipperfrequentie is ca 4 Mhz.

Ik zie in de settings ook niet de kloksnelheid staan (zoals Xtal = 4 in Basic).
Daar zal nog wel wat mis gaan.

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Dat kan niet. Met een 4MHz kristal is het technisch onmogelijk om op 4MHz te knipperen. (daar hoef je niet eens voor naar de code te kijken)
Op 4MHz clock is de aan/uit tijd ongeveer 12/12mS (kun je in MPSim zien)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Klopt. Ik mat op de verkeerde pin (waar het kristal aan zat, dan kan die 4Mhz wel kloppen...)

Ok, maar het werkt nu; de led knippert vrolijk. En ik heb een werkende assembler-omgeving.

Wederom bedankt, Arco!

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Hier heb je er een met delay loops (die moet je zelf maken in assembly... ;) )
Sysclock moet je op de juiste frequentie zetten...

pic asm code:


;**********************************************************************
                #include <p16f1827.inc>     ;processor specific variable definitions
   				__CONFIG _CONFIG1, _FOSC_ECH & _WDTE_OFF & _BOREN_OFF & _PWRTE_ON & _CP_OFF & _CPD_OFF & _MCLRE_OFF & _IESO_ON
				__CONFIG _CONFIG2, _LVP_OFF & _PLLEN_OFF & _BORV_19
                ErrorLevel - 302
;**********************************************************************
sysclock        equ	d'10000000'	;Crystal frequency 10MHz
fclock		set	sysclock >> 2	;Internal cycle clock
delay1ms_value	set	fclock / d'54000' + fclock / d'500000'    	;Delayloop value 1 ms

mscount		equ     20h
lp_delay	equ     21h
scount		equ     22h
lpcount         equ     23h
teller		equ	24h
teller2	        equ	25h

                org	00h                 ;beginadres kiezen

		banksel TRISA               ;kies bank 1
		clrf	TRISA               ;alles pinnen poort A uitgang maken

                banksel ANSELA          
                clrf    ANSELA
                clrf    ANSELB

                
knipper	        
		banksel LATA
		movf	LATA,w		    ;laad 01h in W
		xorlw   1
		movwf	LATA		    ;zet de waarde van W
                call    delay_500ms
		goto	knipper	

delay_500ms     call    delay_250mS
delay_250ms	movlw	d'250'              ;Wait loops
		goto    delay_ms
delay_100ms	movlw	d'100'					
		goto	delay_ms
delay_50ms	movlw	d'50'
		goto	delay_ms
delay_20ms	movlw	d'20'
		goto	delay_ms				
delay_10ms	movlw	d'10'
		goto	delay_ms				
delay_1ms	movlw	d'1'

delay_ms        
		banksel	mscount			
		movwf   mscount         
delay_ms_lp1    movlw   delay1ms_value  
                movwf   lp_delay               
		
delay_ms_lp2	movlw	d'15'
		movwf	lpcount
delay_ms_lp	decfsz	lpcount,f
		goto	delay_ms_lp		

		decfsz  lp_delay,f             		
                goto    delay_ms_lp2           		
                decfsz  mscount,f              		
                goto    delay_ms_lp1           		
                retlw   0                      		

delay_1min	movlw	d'60'
		goto	delay_s	
delay_5s        movlw   d'5'
		goto	delay_s
delay_1s        movlw   d'1'
delay_s         
		banksel scount
		movwf   scount
delay_s_lp      movlw   d'250'
                call    delay_ms
                movlw   d'250'
                call    delay_ms
                movlw   d'250'
                call    delay_ms
                movlw   d'250'
                call    delay_ms
                decfsz  scount,f
                goto    delay_s_lp
                retlw   0

		END
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Het is mij nog niet duidelijk waarom dit Banksel nodig is

pic asm code:

banksel TRISA               ;kies bank 1
		clrf	TRISA               ;alles pinnen poort A uitgang maken

                banksel ANSELA           

Waarom van bank switchen?

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Het geheugen van basic en midrange pics is onderverdeeld in banks. De 16F1827 heeft er 32.

Je moet alvorens een register aan te spreken wel de bank kiezen waar die in zit.
(hoeft niet altijd; je kunt ook indirecte addressering gebruiken maar dat is weer een ander hoofdstuk... ;) )

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

In de Tutorial wordt een opsomming gemaakt van alle instructies die er zijn.

Daar staat de BANKSEL en SET niet bij.
Er zijn er dus meer begrijp ik.

Moet ik het zo lezen dat bij BANKSEL ANSELA je adres 18D (Bank 3) selecteert?

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

BANKSEL en SET zijn geen instructies, maar assembler directives. (zie de MPasm helpfile)
BANKSEL ANSELA selecteert bank 3: 0x180 tot 0x1FF

Er is trouwens een uitzondering: de locaties 0x70 tot 0x7F in bank 0 zijn gekopieerd in alle banken.
Dus ongeacht in welke bank je zit zijn die altijd bereikbaar.

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Ik zit net te grasduinen in de datasheet van de 1827. En zojuist ook de bijbehorende .inc bekeken.
Ik begin het toch wel leuk te vinden moet ik zeggen.

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Er zat nog een klein foutje in het programma: ;)

pic asm code:

 
call    delay_250mS
delay_250ms	movlw	d'250' 

De S van delay_250mS staat als hoofdletter.
Blijkbaar is alles case-sensitive (of je moet dat uit kunnen schakelen).

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Case sensitivity altijd uitzetten:
Project -> Build Options -> Project -> MPAsm assembler -> Disable case sensitivity...

SET en EQU zijn om constantes een naampje te geven. Zijn beiden hetzelfde met 1 verschil:
EQU is eenmalig (kan niet gewijzigd worden), terwijl SET wel gewijzigd kan worden.

[Bericht gewijzigd door Arco op zaterdag 9 november 2019 01:59:27 (42%)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

pic asm code:

 sysclock        equ	d'10000000'	;Crystal frequency 10MHz
fclock		set	sysclock >> 2	;Internal cycle clock
delay1ms_value	set	fclock / d'54000' + fclock / d'500000'    	;Delayloop value 1 ms
 

Dit ontgaat me even, wat er hier nu precies gebeurt.
sysclock, fclock, delay1ms_value zijn allemaal naampjes voor constanten en geen instructies voor zover ik het begrijp.

Maar wie zet nu de frequentie goed? Welke instructie doet dat dan?
en vanwaar het delen door 54000 en 500000?

Ik heb een fysiek kristal van 4 Mhz aangesloten en de waarde van d'10000000 veranderd in d'4000000.
De Led knippert nu met een interval van 40 seconden.

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

De deling is nodig, om (ongeveer) de juiste delays te krijgen.
(hangt van de routines af. Als je andere routine maakt zul je die deling weer moeten tweaken om de juiste waarde te krijgen...)
Sysclock is de oscillatorfrequentie, fclock de instructieclock en delay1ms de waarde voor de delayroutines. Zijn allemaal constantes.

Het programma zou 500mS aan/uit moeten knipperen. 40sec kan niet, is veel te veel.
Ik zie wel dat ik de config op externe oscillator had laten staan. Voor een kristal moet je die veranderen.

- _FOSC_LP voor een 32kHz kristal
- _FOSC_XT voor 4MHz en lager
- _FOSC_HS voor hoger als 4MHz

Er valt in frequentie niks 'goed te zetten'. De delayloops is zuiver een kwestie van instructiecycles tellen...
(op 4MHz een kwestie van tot 1.000.000 tellen voor 1sec... ;) )

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Het aanbrengen van _FOSC_XT bracht de LED inderdaad naar een beduidend lagere knipperfrequentie terug.

Dat doe hij nu ca 0,5 sec.

De waardes van delay_250ms t/m delay_1ms hebben vrijwel geen invloed op de knipperfrequentie. Ik heb wat waarden geprobeerd tussen d'0 en d'250 maar dat geeft geen (zichtbaar) effect.

Verder valt me op dat er geen RETURN instructie is na de call delay_250 ms
Dat hoeft niet?

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Welke delay je kiest heeft wel degelijk invloed op de knipperfrequentie.
Bij delay_500mS moet de 250mS loop twee maal worden doorlopen, daarom geen return achter de eerste keer...

pic asm code:


delay_500ms     call    delay_250mS    ;Eerste 250mS loop
delay_250ms	movlw	d'250'         ;Tweede 250mS loop   
		goto    delay_ms
                ...
                ...
                ...
                decfsz  mscount,f              		
                goto    delay_ms_lp1           		
                retlw   0

Dit had ook gekund (maar kost meer code en levert niks extra's op):

pic asm code:


delay_500ms     call    delay_250mS    ;Eerste 250mS loop
                call    delay_250mS    ;Tweede 250mS loop   
                return

delay_250ms	movlw	d'250'         
		goto    delay_ms
                ...
                ...
                ...
                decfsz  mscount,f              		
                goto    delay_ms_lp1           		
                retlw   0

[Bericht gewijzigd door Arco op zondag 10 november 2019 12:34:48 (32%)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Maar wanneer (bij welk statement) eindigt dan een call zonder return?

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Beide hebben een return: de retlw aan het eind van de routine. Let op dat alleen de eerste een call is, de tweede niet.

pic asm code:


delay_500ms     call    delay_250mS    ;Eerste 250mS loop
delay_250ms	movlw	d'250'         ;Tweede 250mS loop   
		goto    delay_ms
                ...
                ...
                ...
                decfsz  mscount,f              		
                goto    delay_ms_lp1           		
                retlw   0  <<<<<<<<----
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Het kosttte wat moeite om alles te doorgronden, maar ik ben nu een heel eind.

De vele goto's maken een programma wat lastig om te doorgronden. Maar daar kom je niet onderuit denk ik.

In een ander artikel las ik dat de instructietijd = 4 / oscillatorfrequentie.

Maar waar dient dit statement

pic asm code:

 fclock		set	sysclock >> 2	;Internal cycle clock

dan voor?

Fouten zijn het bewijs dat je het probeert..