Problem med data tables (PIC16f877a)

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Spket
Inlägg: 81
Blev medlem: 22 mars 2009, 02:19:50

Problem med data tables (PIC16f877a)

Inlägg av Spket »

Hej!
Jag har byggt ett litet prov projekt i syftet att lära mig. Projektet är uppbyggt av en PIC16f877a, några lysdioder och en 3-siffrig 7-segments LED display (gemensam cathode). Jag har fått den att vissa fasta siffror dvs t.ex. 001, men vill nu kunna räkna upp. För tillfället använder jag bara en siffra av de tre multiplexade displayerna, det finns inte heller någon kod till de andra lysdioderna här.

Kod: Markera allt

	list		p=16f877A	; list directive to define processor
	#include	<p16f877A.inc>	; processor specific variable definitions
	
	__CONFIG _XT_OSC & _WDT_OFF & _LVP_OFF & _PWRTE_ON

; '__CONFIG' directive is used to embed configuration data within .asm file.
; The lables following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.
cblock		h'20'
	d1
	d2
	d3
	d4
	unit

endc
org 0

Start:
 	clrf	PORTA			; Make all ports output
	clrf	PORTB
	bsf		STATUS,RP0		; Go to bank 1		
	clrf	TRISA
	clrf	TRISB
	bcf		STATUS,RP0		; Back to bank 0
	movlw	0x08
	movwf	d2
	movlw	0x2F
	movwf	d3
	movlw	0x03
	movwf	d4
	movlw	0x04
	movwf	PORTA	; Endast sista siffran ska lysa!


Main
	call	Table
	movwf	PORTB
	call	Delay2
	
	goto	Main
	

Table
	addwf	PCL
	retlw	0x3f	;0
	retlw	0x06	;1
	retlw	0x5B	;2
	retlw	0x4F	;3
	retlw	0x66	;4
	retlw	0x6D	;5
	retlw	0x7C	;6
	retlw	0x07	;7
	retlw	0x7F	;8
	retlw	0x67	;9



Delay2
	decfsz	d2, f
	goto	$+2
	decfsz	d3, f
	goto	$+2
	decfsz	d4, f
	goto	Delay2

			;3 cycles
	goto	$+1
	nop

	return




	END                       ; directive 'end of program'
Det jag får fram är "0". Sen händer inget mer. Kär jag coden i MPLAB SIM så för jag "CORE-W0014: Halted due to PC incrementing over the Maximum PC address and wrapping back to Zero"
Jag är nybörjare inom programering av uC och detta är första gången jag håller på med data tables.
Min hjälp hittilst har varit:
http://www.picaxeforum.co.uk/archive/in ... -2317.html
http://www.mstracey.btinternet.co.uk/pi ... gtut10.htm
Användarvisningsbild
Icecap
Inlägg: 26651
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Problem med data tables (PIC16f877a)

Inlägg av Icecap »

Omedelbart tycker jag att det är konstigt att du kallar din indextabell utan att ställa värdet i W först! Du har ju inget koll på vad den kommer med.
Spket
Inlägg: 81
Blev medlem: 22 mars 2009, 02:19:50

Re: Problem med data tables (PIC16f877a)

Inlägg av Spket »

Det är så att jag har provat mig fram, tagit bort och skrivit ny kod hela tiden. Jag har provat att ställa värdet i W till t.ex. 0 eller 1 först men det blir ingen skillnad
Spket
Inlägg: 81
Blev medlem: 22 mars 2009, 02:19:50

Re: Problem med data tables (PIC16f877a)

Inlägg av Spket »

Jag har uppdaterat koden lite, vet inte om jag ska uppdatera mitt första inlägg eller lägga en ny post så jag lägger en ny. Det funkar fortfarande lika dåligt

Kod: Markera allt

;**********************************************************************
;   This file is a basic code template for assembly code generation   *
;   on the PIC16F877A. This file contains the basic code              *
;   building blocks to build upon.                                    *  
;                                                                     *
;   Refer to the MPASM User's Guide for additional information on     *
;   features of the assembler (Document DS33014).                     *
;                                                                     *
;   Refer to the respective PIC data sheet for additional             *
;   information on the instruction set.                               *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Filename:	    xxx.asm                                           *
;    Date:                                                            *
;    File Version:                                                    *
;                                                                     *
;    Author:                                                          *
;    Company:                                                         *
;                                                                     * 
;                                                                     *
;**********************************************************************
;                                                                     *
;    Files Required: P16F877A.INC                                     *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Notes:                                                           *
;                                                                     *
;**********************************************************************


	list		p=16f877A	; list directive to define processor
	#include	<p16f877A.inc>	; processor specific variable definitions
	
	__CONFIG _XT_OSC & _WDT_OFF & _LVP_OFF & _PWRTE_ON

; '__CONFIG' directive is used to embed configuration data within .asm file.
; The lables following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.
cblock		h'20'
	d1
	d2
	d3
	d4
	unit

endc
org 0

Start:
 	clrf	PORTA			; Make all ports output
	clrf	PORTB
	clrf	PORTC
	clrf	PORTD
	clrf	PORTE
	bsf		STATUS,RP0		; Go to bank 1		
	clrf	TRISD			; Make all ports "low"
	clrf	TRISA
	clrf	TRISB
	clrf	TRISC
	clrf	TRISE
	bcf		STATUS,RP0		; Back to bank 0
	movlw	0x08
	movwf	d2
	movlw	0x2F
	movwf	d3
	movlw	0x03
	movwf	d4
	movlw	0xA6
	movwf	d1
	movlw	0x04
	movwf	PORTA
	movlw	0x00
	movwf	unit	
	movlw	0x00
	

Main
	call	Table
	movwf	PORTB
;	call	Delay2
	movlw	unit
	incf	unit,f
	goto	Main
	goto	Start
	

Table
	addwf	PCL,f
	retlw	0x3f	;0
	retlw	0x06	;1
	retlw	0x5B	;2
	retlw	0x4F	;3
	retlw	0x66	;4
	retlw	0x6D	;5
	retlw	0x7C	;6
	retlw	0x07	;7
;	retlw	0x7F	;8
;	retlw	0x67	;9

;Delay
;	decfsz	d1, f
;	goto	Delay

			;1 cycle
;	nop



					
;	return

Delay2
	decfsz	d2, f
	goto	$+2
	decfsz	d3, f
	goto	$+2
	decfsz	d4, f
	goto	Delay2

			;3 cycles
	goto	$+1
	nop

	return




	END                       ; directive 'end of program'

Jag har gjort en kommentar av call delay2 p.g.a jag kör coden i simulatorn
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Problem med data tables (PIC16f877a)

Inlägg av sodjan »

> Kär jag coden i MPLAB SIM så för jag "CORE-W0014: Halted due to PC incrementing over the
> Maximum PC address and wrapping back to Zero"

Ja men då så. Fixa det. Det är ju bara att stega igenom och se var PC'n "skenar"...
bos
Inlägg: 2311
Blev medlem: 24 februari 2007, 23:29:15
Kontakt:

Re: Problem med data tables (PIC16f877a)

Inlägg av bos »

Spket skrev:

Kod: Markera allt

	movlw	unit
	incf	unit,f
Jag vet inte riktigt vad du förväntar dig att ovanstående ska göra, men det ser väldigt fel ut. Första raden, "move literal to w", tar det numeriska värdet för unit (0x25 enligt din CBLOCK) och lägger i W. Andra raden ökar registret på adress 0x25 med 1. Om det är så att du vill läsa in variabeln units värde till W ska du byta den första operanden till movfw istället för movlw.

Fast det enklaste är kanske att du förklarar hur du tänker vad det är du vill åstadkomma. Jag gissar att det finns ganska många fel.
Spket
Inlägg: 81
Blev medlem: 22 mars 2009, 02:19:50

Re: Problem med data tables (PIC16f877a)

Inlägg av Spket »

Tack bos för ditt svar.. Jo jag har själv grublat över hur jag har tänkt. Problemet är nog att jag har försökt lite för snabbt och inte riktigt uppfattat vad allt gör än så länge. Jag började så smått med uC i April och provade mig fram t.o.m Juni, sen har jag tagit en paus från det hela så även sånt jag lärt mig innan kan nog behöva en uppdatering.

Meningen är att jag ska på en 7-segment display ska räkna från 0-9 å sen ev. loopa det eller gå vidare med något annat. Jag ska sätta mig ner och göra en ny kod och försöka läsa lite mera, när jag postade koden igår var jag lite frustrerad över att jag ej fick igång det innan det var sängdags.
Spket
Inlägg: 81
Blev medlem: 22 mars 2009, 02:19:50

Re: Problem med data tables (PIC16f877a)

Inlägg av Spket »

Tydligen så hade jag på något sätt lyckats igår (kanske inte med koden som jag postat ovan), den räknade från 0 till 1 och stog sedan still. Problemet var att jag definerade variablerna d1, d2, d3 i början av programmet. Sedan när delay loopen kördes så ändrades ju dessa till 0.. så nästa loop vart väldigt lång!

Jag hittade också denna sida som hjälpte mig otroligt mycket http://www.gooligum.com.au/tut_baseline.html

Här är i alla fall min kod för att få en 7-segment display att räkna från 0-9 och sedan börja om.
Synpunkter på koden och kommentarer tas gärna emot (har jag tänkt rätt så som jag beskriver koden i mina kommentarer?)

Kod: Markera allt

	list		p=16f877A	; list directive to define processor
	#include	<p16f877A.inc>	; processor specific variable definitions
	
	__CONFIG _XT_OSC & _WDT_OFF & _LVP_OFF & _PWRTE_ON

; '__CONFIG' directive is used to embed configuration data within .asm file.
; The lables following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.
cblock		h'20'
	d1
	d2
	d3
	d4
	digit

endc
org 0

Start:
 	clrf	PORTA			; Make all ports output
	clrf	PORTB
	clrf	PORTC
	clrf	PORTD
	clrf	PORTE
	bsf		STATUS,RP0		; Go to bank 1		
	clrf	TRISD			; Make all ports "low"
	clrf	TRISA
	clrf	TRISB
	clrf	TRISC
	clrf	TRISE
	bcf		STATUS,RP0		; Back to bank 0
	movlw	0x04			; 00000100
	movwf	PORTA			; Gör RA2 aktiv
	clrf	digit			; Rensar digit
	goto	Main			; Gå till main

Main
	movf	digit,w			; Kopiera värdet i digit till w
	call	Table			; Kolla vilken siffra som ska visa
	movwf	PORTB			; Och visa den
	call	Delay
	incf	digit,f			; Öka digit med 1
	movlw	.10				; w = 10
	xorwf	digit,w			; om digit = 10
	btfsc	STATUS,Z
	clrf	digit			; så resettar vi den till 0
	goto	Main			; Loopa!
	
Table
	addwf	PCL,f 
	retlw	0x3f	;0
	retlw	0x06	;1
	retlw	0x5B	;2
	retlw	0x4F	;3
	retlw	0x66	;4
	retlw	0x6D	;5
	retlw	0x7C	;6
	retlw	0x07	;7
	retlw	0x7F	;8
	retlw	0x67	;9

Delay
	movlw	0x08			; Laddar delay loopen
	movwf	d1
	movlw	0x2F
	movwf	d2
	movlw	0x03
	movwf	d3
	goto	Delay2

Delay2						; Här är loopen
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	$+2
	decfsz	d3, f
	goto	Delay2

	goto	$+1
	nop

	return

END                       ; directive 'end of program'
Användarvisningsbild
Swech
EF Sponsor
Inlägg: 4750
Blev medlem: 6 november 2006, 21:43:35
Ort: Munkedal, Sverige (Sweden)
Kontakt:

Re: Problem med data tables (PIC16f877a)

Inlägg av Swech »

Lite tips bara..
Anta alltid att allt kan gå åt h..vete, celler kan ha konstiga värden.
Varje subrutin som man anropar skall vara så stabil som det bara går.
Subrutiner skall alltså även kunna ta hand om felaktiga data utan att spåra ur fullständigt.

Nu antar din retlw tabell att w bara kan ha värden mellan 0 och 9.. övriga värden 10-255 får
subrutinen att spåra ur okontrollerat.

På ett annat ställe där du kollar om värdet är 10 så kollar du om det är exakt 10..
0-9 är godkänt.. men även 11-255 är det....

Det funkar som du har gjort.. men nästa vecka då du ändrar något så kan det sluta att funka med
riktigt elaka buggar som följd.

------------
Jag brukar göra retlw tabeller jämnt delbara med 2,4,8,16,32.... (oanvända hopp , i ditt fall nr 10,11...15,
sätter man till t.ex retlw 0

isåfall kan man göra en andlw med 1,3,7,15,31... och förhindra att man indexerar utanför tabellen.

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

Läsbarhet....
Program är kul att skriva men ett elände att underhålla, Ju mer man döljer i koden destå värre blir det.
Kod som förutsätter hårdvara på ett visst sätt är oerhört tråkig att fixa till...
Säg nu att du kopplar om din display. Du bytar plats på några segment.
Men du har hårdkodat vart de skall vara i ditt program

Kod: Markera allt

   retlw   0x3f   ;0
   retlw   0x06   ;1
.
.
0x06 -> bit 1 och bit 2 skall vara tända och ger en 1a....

Definiera istället 7 konstanter som du kallar LED_A,LED_B,LED_C..... LED_G

(vet att det finns ett korrekt a-g layout för 7 seg)
Då definierar du istället retlw LED_C+LED_D så får du din 1a....
ändrar du layouten ändrar du bara vad LED_A.. LED_G har för bitnummer...

Exakt hur du skriver lämnar jag över till PIC specialisterna... Hade det varit AVR så..... :wink:


Swech
bos
Inlägg: 2311
Blev medlem: 24 februari 2007, 23:29:15
Kontakt:

Re: Problem med data tables (PIC16f877a)

Inlägg av bos »

Bra tips. Jag kan bidra med ett till när det gäller definitionen av LED-segmenten. Såhär gör jag:

Kod: Markera allt

display_table                                   ; converts the number to segment-format
        addwf   PCL, f
        ;           PORTB
        ;         76543210
        ;         -EDCBAGF
        retlw   b'10000010'                     ; 0
        retlw   b'10110111'                     ; 1
        retlw   b'11000001'                     ; 2
        retlw   b'10010001'                     ; 3
        retlw   b'10110100'                     ; 4
        retlw   b'10011000'                     ; 5
        retlw   b'10001000'                     ; 6
        retlw   b'10110011'                     ; 7
        retlw   b'10000000'                     ; 8
        retlw   b'10010000'                     ; 9
        retlw   b'11111111'                     ; blank
Ändrar man utgångarna så är det busenkelt att ändra i koden också.
Nerre
Inlägg: 27234
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Problem med data tables (PIC16f877a)

Inlägg av Nerre »

Swechs lösning var ju betydligt smartare. Säg att du för att få enklare kortlayout vill göra så att segment F ligger på pinne 6 och segment E på pinne 0, då måste du ändra på ALLA raderna.

Med Swechs lösning så blir det (med reservation för att jag inte kan syntaxen) nåt i stil med

Kod: Markera allt

;           PORTB
;        76543210
;        -EDCBAGF
LED_A  b'00000100'
LED_B  b'00001000'
LED_C  b'00010000'
LED_D  b'00100000'
LED_E  b'01000000'
LED_F  b'00000001'
och sen

Kod: Markera allt

        retlw   LED_B+LED_E                   ; 1
osv...
Och för att kasta om segment E och F ändrar man bara

Kod: Markera allt

LED_E  b'01000000'
LED_F  b'00000001'
till

Kod: Markera allt

LED_E  b'00000001'
LED_F  b'01000000'
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Problem med data tables (PIC16f877a)

Inlägg av sodjan »

Bättre än alla tidigare alternativ är att skippa bitarna helt i RETLW
instruktionerna (och symb + symb + symb köret). Skapa färdiga
symboler direkt i i början av koden så att du bara sedan kan ha :

Kod: Markera allt

; Först definition av mappning mellan I/O pinne och segment.
LED_A   EQU    b'00000001'
LED_B   EQU    b'00000010'
LED_C   EQU    b'00000100'
...
...
; Sedan definition av hur de olika symbolerna ska se ut.
7SEG_1  SET    LED_A | LED_B | LED_C
7SEG_2  SET    LED_A | LED_D | LED_E
...
...
Sedan i din lookuptable använder du :

Kod: Markera allt

        retlw   7SEG_1
        retlw   7SEG_2
...
...
Då slipper du även de där korkade kommenterarna till RETLW instruktionerna som bara säger ";1" o.s.v... :-)
bos
Inlägg: 2311
Blev medlem: 24 februari 2007, 23:29:15
Kontakt:

Re: Problem med data tables (PIC16f877a)

Inlägg av bos »

Bättre o bättre vet jag inte. Alla de föreslagna lösningarna gör *exakt* samma sak, dvs använder en LUT beståendes av retlw. Skillnaden i lösningarna är ju enbart kosmetiskt. sodjans lösning är förvisso den mest tilltalande, men jag själv skulle inte använda den.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Problem med data tables (PIC16f877a)

Inlägg av sodjan »

Visst, i dag skulle man sannolikt använda TBLRD istället vilket
ger en snyggare och renare kod utan PCLATH problem o.s.v.
Nerre
Inlägg: 27234
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Problem med data tables (PIC16f877a)

Inlägg av Nerre »

Den assemblerade koden blir likadan, men källkoden blir tydligare, enklare att felsöka och enklare att hantera. Och man överlåter de jobbiga grejerna åt assemblern.

Vill man få det ännu snyggare kan man göra ett makro så man enkelt kan välja om etta eller nolla skall vara tänt segment. Då kan man definiera med ettor (och använda or (|) eller + för att kombinera segment) även om det ska vara nollor för att tända.


Fast det kräver ju att man tänker lite innan man börjar koda:-)
Skriv svar