Sida 1 av 3

Hjälp med kod 16F84 (nybörjare)

Postat: 13 april 2006, 10:06:39
av holta
Hej!
Har sedan ett par dagar sedan läst om och försökt programmera 16F84 utan några bra resultat. Vet inte riktigt var det blir fel, och känner nu att jag behöver lite mer hjälp från någon erfaren :)

Bifogar min kod först här nedan:

Kod: Markera allt

;==========================================================================
;        TEST.ASM
;
;       'LED-Display räknare'
;==========================================================================

LIST P=16F84
INCLUDE "p16f84.inc"
__CONFIG _PWRTE_ON & _XT_OSC & _WDT_OFF

;==========================================================================

TIMER1          EQU     H'0C'   ;Timer 1, Används för delay.
TIMER2          EQU     H'0D'   ;Timer 2, Används för delay.
TIMER3          EQU     H'0E'   ;Timer 3, Används för delay.

                ORG     0
                GOTO    RESET


DELAY1          MOVLW   D'7'
                MOVWF   TIMER1
                MOVLW   D'47'
                MOVWF   TIMER2
                MOVLW   D'3'
                MOVWF   TIMER3
DELAY_1         DECFSZ  TIMER1,F
                GOTO    $+2
                DECFSZ  TIMER2,F
                GOTO    $+2
                DECFSZ  TIMER3,F
                GOTO    DELAY_1
                RETURN


RESET           BCF     STATUS,RP0
                CLRF    PORTB
                BSF     STATUS,RP0
                MOVLW   B'00000000'
                MOVWF   TRISB
                BCF     STATUS,RP0
                GOTO    LOOP

L0              MOVLW   b'01110111'
                MOVWF   PORTB
                RETURN

L1              MOVLW   b'00010100'
                MOVWF   PORTB
                RETURN

L2              MOVLW   b'10110110'
                MOVWF   PORTB
                RETURN

L3              MOVLW   b'10110110'
                MOVWF   PORTB
                RETURN

L4              MOVLW   b'11010100'
                MOVWF   PORTB
                RETURN


LOOP            CALL L0
                CALL DELAY1
                CALL L1
                CALL DELAY1
                CALL L2
                CALL DELAY1
                CALL L3
                CALL DELAY1
                CALL L4
                CALL DELAY1
                GOTO    LOOP

                END
Det jag vill att programet ska göra är att på en LED-Display som är kopplad tilll PORTB på 16F84, är att den ska räkna från 0 upp till 9 för att sedan börja om från början, dock så är bara 0-4 programmerat nu. De olika LED-segmenten ligger anslutna till varsinn output, alltså RB0-RB7.

Men detta fungera alltså inte, kör kretsen i 4MHz. Jag har fått vissa färdiga program att fungera men inte detta som jag gjort själv. Skulle vara tacksam om någon kan kommentera vad som är fel, och eventuellt vad som kan göras bättre.

Postar även outputen när jag kompilerar programmet i linux.

Kod: Markera allt

gpasm -o test.hex test.asm  -a inhx8m -n
test.asm:9:Warning [205] Found directive in column 1.
test.asm:40:Message [302] Register in operand not in bank 0. Ensure bank bits are correct.
Edit: La till senaste koden och senaste kompileringsmeddelandena[/code]

Postat: 13 april 2006, 10:41:01
av Icecap
Då jag inte kör linux kan jag inte hjälpa med så mycket men jag ser direkt en intressant sak:
GOTO $+2
i dina delay's. Det ska väl ändå vara "GOTO $-2" eller hur?

Postat: 13 april 2006, 11:22:32
av holta
Som jag ser det så är det helt okej med GOTO $+2.
Men känner mig lite osäker på delays, så ja genererade koden med hjälp av: http://www.piclist.com/techref/piclist/ ... /delay.htm

Postat: 13 april 2006, 11:39:06
av holta
Felet uppenbarar sig i att jag inte verkar kunna styra vilka utgångar som ska vara höga eller låga, utan en del blir låga och en del höga, han verkar inte alls följa programmet utan hittar på eget. Som det är nu lyser alla LED-segment en sekund, sedan slocknar ett segment för att sedan efter en sekund börja om från början.

Hoppas att den här beskrivningen kan hjälpa något i sammanhanget.

Postat: 13 april 2006, 11:47:06
av Icecap
Så den gör delayen vid att hoppa _fram_ i koden om den ska upprepa????

Skulle inte tro det! Jag kanske var lite otydlig men det _ska_ vara $-2!

Vad är "MOVFW b'00010100'"???
Jag känner till "MOVLW b'00010100'" men det stavas ju inte lika, jag skulle rakt av tro att du har skrivit fel i dina L1, L2, L3 & L4.

Varför avsluter du DELAY1 med "RETLW 0"?
"RETURN" duger helt fint till sånt faktisk.

Postat: 13 april 2006, 11:49:50
av holta
Okej, jag gör en test, utvärdera det du säger helt enkelt och återkommer. Jag tackar så mycket för hjälpen så länge :)

Postat: 13 april 2006, 12:14:22
av holta
Nu har jag gjort lite test av det hela.
Det du säger om MOVLW verkar ju stämma, har ändrat till det. Men jag får fortfarande ej det resultat jag önskar, verkar vara mer fel.

Sen testa jag även delayen att ändra till $-2, men detta fungerar inte alls.

Postat: 13 april 2006, 12:15:24
av exile
Nu är jag ingen expert på PIC men jag får till det ska vara GOTO $+2

Om jag över sätter i C kanse det är lättare att se

Kod: Markera allt

delay1 = 12;
delay2 = 10;

while(1){
	delay1--;
	if (delay1 == 0){
		delay2--;
		if (delay2 == 0){
			breake;
		}
	}
}
Sedan brukar man använda return som Icecap sa...

Postat: 13 april 2006, 13:03:00
av Icecap
Nämen... *suck*

OK, vi tar det tydligt och lugnt: (utklipp med pseudoadressor)

Kod: Markera allt

Delay_1
0000     DECFSZ  TIMER1,F ; Denna ska upprepas<TIMER1> gg, om den blir noll utförs nästa kommando inte
0001     GOTO    $+2         ; Hopp till 0004 då PC redan är inkremented
0002     DECFSZ  TIMER2,F
0003     GOTO    $+2         ; Hopp till 0006
Ser ni felet?

Det ÄR $-2 som gäller!!!

Exile: din kod representerar INTE korrekt holta's. Hans kod är:

Kod: Markera allt

delay1 = 12;
delay2 = 10;
while(1)
  {
  delay1--;
  if(delay1 > 0)
    {
    delay2--;
    if(delay2 > 0) break;
    }
  }

Postat: 13 april 2006, 13:15:21
av holta
Jag uppdaterade precis den första posten med den kod och den output jag får från kompileringen.
Får det fortfarande inte att fungera som det ska.

Och sen när jag ändrar delay rutinen till GOTO $-2 så får jag ingen form av delay överhuvudtaget. När jag kör GOTO $+2 så får jag delay mellan varje händelse på 1 sekund, vilket är vad jag önskar. Men jag ska kolla på delay functionen igen för att se om det verkligen är något fel där.

Men sen förstår jag inte heller varför min LED-Display bara visar skräp, jag är hyffsat säker på att jag kopplat rätt. Antingen är kretsen knäpp eller så är jag knäpp, eller möjligtvis en kompination av båda :wink:

Men jag testar vidare, och jag är tacksam för alla kommentar jag får. Underlättar en del.

Postat: 13 april 2006, 13:32:42
av Icecap
Först en lite enklare kodbit:

ShowDigit
movf Index,W ; Index = räknaren (0-9)
call ReplyIndex ; Svarar med talets mönster
movwf PORTA ; som slängs ut på porten
return ; hejdå
ReplyDigit
andlw h'0F' ; Stoppa "skogsturar"
addwf PCL,F ; Hopp indexerat
retlw b'01110111' ; '0'
retlw b'00010100' ; '1'
retlw b'10110110' ; '2'
retlw b'10110110' ; '3'
retlw b'11010100' ; '4'
osv upp till och med 15! (kan ju vara 0-9, A, b, C, d, E, F om du vill)

Detta gör att du laddar W med talet du vill visa (0-9) och CALL'ar ShowDigit kommer talet up på PORTA, enkelt och smärtfritt.

Postat: 13 april 2006, 13:34:56
av sodjan
Kör koden genom MPASM och återkom.

Fungerar det i MPSIM ?

Håller med Icecap ang MOVFW, ser ut som en bug. Är deet rättat ?

Använd labels istället för "$" så blir det inga otydlighter.
Det finns i princip aldrig någon anledning att använda "$" i programhopp,
däremot kan det vara motiverat i "PAGESEL $" t.ex, men det är en annan historia...

> test.asm:57:Warning [219] Invalid RAM location specified.

Jaha !? Och vad har du gjort åt det ? Är det något problem ?

För delayer längre än upp till ca 100 us, använd timers.
DELAY rutinen fungerar (ger 1 sek i MPSIM) men är lite "udda" skrivet,
och som sagt, timers är snyggare...

DELAY1 och DELAY_1 är synnerligen olämpligt valda namn !

Är det verkligen en F84 ? Inte en F84A ? Hur som helst, byt till något modernare, t.ex F628A

Postat: 13 april 2006, 13:42:09
av holta
Hej!
Har nu fått allt att fungera som det ska, till att börja med hade jag missuppfattat vilket som var hög och låg av bitvärdena på PORTB :roll:

Och som sagt delay rutinen fungerar som den ska den ger en sekund.
Väldigt tacksam för programförslaget från dig Icecap :)
Timers är något som jag får börja titta på.

Känner att jag har väldigt mycket att lära inom det är med PIC, men väldigt roligt när man kommer igång med det hela :)

Tack alla

Postat: 13 april 2006, 13:49:07
av Icecap
Det blir ju en del roligare när man har fått de första LED'arna att blinka. Kör hårt.

Postat: 13 april 2006, 13:55:02
av sodjan
Och det är mycket roligare på en processor som inte är så
begränsad som F84... :-)