Räkna ner i (Mikro)Basic ?

Elektronik- och mekanikrelaterad mjukvara/litteratur. (T.ex schema-CAD, simulering, böcker, manualer mm. OS-problem hör inte hit!)
Användarvisningsbild
JimmyAndersson
Inlägg: 26308
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Räkna ner i (Mikro)Basic ?

Inlägg av JimmyAndersson »

Har stött på ytterligere ett problemi MikroBasic.
Jag vill göra en nedräkning från 3 till 0 med en FOR-loop, men när jag kör koden i PIC18LF1320 så hoppar den över nedräkningsloopen. (Se kommentarerna i koden.)
Koden nedan är lite modifierad med några "blinka fyra/två LED" för att se när nedräkningen kommer.

Här är koden. Något omständig men, som sagt det är bara för test:

Kod: Markera allt

program PimEget

dim vilkena as byte
dim vilkenb as byte

TRISB = 0 ' Utgångar på B
PORTB = 0 ' Stäng av alla

do
  for vilkena = 0 to 3
      SetBit (PORTB,vilkena)
      delay_ms(200)
      ClearBit (PORTB,vilkena)
      delay_ms(5)
  next vilkena

  PORTB = $0F            <----BLINKAR FYRA LED BARA FÖR ATT SE
  delay_ms(50)
  PORTB = $00
  delay_ms(50)
  PORTB = $0F
  delay_ms(50)
  PORTB = $00
  delay_ms(200)


  for vilkenb = 3 to 0 step -1  <-----HÄR ÄR PROBLEMET. DEN HOPPAR ÖVER HÄRIFRÅN
      SetBit (PORTB,vilkenb)
      delay_ms(200)
      ClearBit (PORTB,vilkenb)
      delay_ms(5)
  next vilkenb                 <------OCH HIT.

  PORTB = $06               <-----BLINKAR LED 2 OCH 3.
  delay_ms(200)
  PORTB = $00
  delay_ms(200)



loop until 0 = 1
end.


Det går ju att lösa genom att räkna uppåt och minska med tre. Ungefär såhär: (Ingen korrekt PIC-kod, bara exempel)

For tal = 0 to 3
ner = 3 - tal
print ner
next tal

Det skulle ju ge utskriften:
3
2
1
0
...men nog borde man kunna göra en FOR-loop som går neråt? Det går ju i "vanliga" Basic...
Användarvisningsbild
Icecap
Inlägg: 26147
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Inlägg av Icecap »

Nu är BASIC ju ett hat-ämne för mig men varför inte räkna 0 -> 3 och indexera med (3 - vilkenb)?
Senast redigerad av Icecap 21 september 2005, 17:08:36, redigerad totalt 1 gång.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Inlägg av sodjan »

> "...men nog borde man kunna göra en FOR-loop som går neråt? Det går ju i "vanliga" Basic..."

Och vad säger TFM om det ???
Användarvisningsbild
JimmyAndersson
Inlägg: 26308
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Inlägg av JimmyAndersson »

Sodjan: :) Både TFM och Google säger att koden stämmer, dvs att det är samma syntax för FOR i MikroBasic som i 19385st andra Basic-former. Men i debuggern ser man att den inte räknar ner den FOR-loopen. 'vilkenb' sätts bara till 3 och sedan hoppar den ner till raden under "next vilkenb".

Icecap: Jo det får nog bli så. Det blir ju lite extra kod, men det fungerar iallfall.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Inlägg av sodjan »

Kolla hur asm koden ser ut för en FOR loop med negativ "step".
Det kanske ger någon ledtråd kring vad som händer...
Användarvisningsbild
JimmyAndersson
Inlägg: 26308
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Inlägg av JimmyAndersson »

Har jämfört looparna i asm-koden. Tyvärr har jag inte hittat någon lösning, men det ser nästan ut som om den missar att den ska "minska med ett".
Så FOR-loopen avslutas eftersom 'vilkenb' är större än slut-talet (dvs noll).
(Om allt varit som det skulle, så hade loopen avslutats om 'vilkenb' varit mindre än slut-talet.)



Nåväl, det får bli en positiv FOR-loop som minskas med 3. Åtminstone tills det löser sig.
Användarvisningsbild
speakman
Inlägg: 4838
Blev medlem: 18 augusti 2004, 23:03:32
Ort: Ånge

Inlägg av speakman »

MikroBasic kanske inte stöder STEP alls? Har du testat med en positiv räkning med STEP 2 t.ex.? Eller ta bort STEP helt från den negativa?
Mvh
speakman
Användarvisningsbild
JimmyAndersson
Inlägg: 26308
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Inlägg av JimmyAndersson »

Jodå, i 'manualen' står STEP med. Det står även att den ska klara negativa tal: "Note that parameter step_value may be negative, allowing you to create a countdown". FOR-loopar ser förresten ut såhär i MikroBasic-hjälpen:

for counter = initial_value to final_value [step step_value]
statements
next counter

Det som står inom [ och ] betyder att det är "valfritt"...

I alla exempel-koder jag kollat så stämmer det med det jag skrivit.

Om jag kör: for talet = 1 to 10 step 2
så stegar den: 1, 3, 5 osv..
Om jag kör: for talet = 10 to 1
UTAN step alltså, så går den bara förbi loopen.
Om jag kör: for talet = 10 to 1 step -2
så går den också förbi loopen.
Användarvisningsbild
speakman
Inlägg: 4838
Blev medlem: 18 augusti 2004, 23:03:32
Ort: Ånge

Inlägg av speakman »

Tragisk BASIC-tolk.. :D
Maila å påpeka!

Mvh
speakman
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Inlägg av sodjan »

En sak...

Loop räknaren "vilkenb" är definierad som "byte".
"step" är alltså -1.

I manualen står det : "The initial_valueand final_valueshould be expressions compatible with the counter;"

Det kanske gäller "step" också, och i så fall undrar jag om "-1" är kompatiblent med "byte". Du kanske skulle prova att ändra "byte" (0...255) till "short" (-128...127) för att eventuellt göra loopvariablen kompatibel med step värdet.


speakman skrev : Tragisk BASIC-tolk..

"Basic-tolk" ?? :-)
Användarvisningsbild
JimmyAndersson
Inlägg: 26308
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Inlägg av JimmyAndersson »

Precis, jag funderade också på det. Tyvärr hjälpte det inte att ändra "vilkenb" till 'short'.

Det verkar nästan som om STEP inte klarar att hantera negativa tal. Det kanske är en bugg..? :lol:
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Inlägg av sodjan »

Mycket möjligt, opch det skulla vara rellativt enkelt att kolla om man hade asm koden från ett litet exempel...
Användarvisningsbild
JimmyAndersson
Inlägg: 26308
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Inlägg av JimmyAndersson »

Det går att ordna. :)


Först MikroBasic-koden för ett exempel:

Kod: Markera allt

program PimTest

dim vilkenb as short

TRISB = 0 ' Utgångar på B
PORTB = 0 ' Stäng av alla

do
  for vilkenb = 3 to 0 step -1
      SetBit (PORTB,vilkenb)
      delay_ms(40)
      ClearBit (PORTB,vilkenb)
      delay_ms(1)
  next vilkenb


loop until 0 = 1
end.


Sedan asm-varianten: (Har tyvärr inte fixa till den. Gjorde precis test-koden ovan. Hoppas det går att läsa asm-koden ändå..)

Kod: Markera allt

;//  ASM code generated by mikroVirtualMachine for PIC - V. 3.0.0.0
;  Date/Time: 2005-09-22 00:30:03
;  Info: http://www.mikroelektronika.co.yu


;// ADDRESS	OPCODE	ASM
; ----------------------------------------------
$0000	$EF04	F000	GOTO	PimTest_main
$0008	$	PimTest_main:
$0008	$	PimTest_main_main:
$0008	$6A93	CLRF	TRISB, 0
$000A	$6A81	CLRF	PORTB, 0
$000C	$	PimTest_L_1:
$000C	$0E03	MOVLW	3
$000E	$6E15	MOVWF	main_global_vilkenb, 0
$0010	$	PimTest_L_2:
$0010	$6A01	CLRF	STACK_1, 0
$0012	$80D8	BSF	STATUS, C, 0
$0014	$BE15	BTFSC	main_global_vilkenb, 7, 0
$0016	$D002	BRA	PimTest_L_5
$0018	$5015	MOVF	main_global_vilkenb, W, 0
$001A	$5C01	SUBWF	STACK_1, W, 0
$001C	$	PimTest_L_5:
$001C	$E33D	BNC	PimTest_L_4
$001E	$	PimTest_L_3:
$001E	$0E01	MOVLW	1
$0020	$1281	IORWF	PORTB, F, 0
$0022	$0E03	MOVLW	3
$0024	$6E01	MOVWF	STACK_1, 0
$0026	$0EFF	MOVLW	255
$0028	$6E02	MOVWF	STACK_2, 0
$002A	$0EFF	MOVLW	255
$002C	$6E03	MOVWF	STACK_3, 0
$002E	$2E01	DECFSZ	STACK_1, F, 0
$0030	$D001	BRA	$+2
$0032	$D007	BRA	$+8
$0034	$2E02	DECFSZ	STACK_2, F, 0
$0036	$D001	BRA	$+2
$0038	$D003	BRA	$+4
$003A	$2E03	DECFSZ	STACK_3, F, 0
$003C	$D7FE	BRA	$-1
$003E	$D7FA	BRA	$-5
$0040	$D7F6	BRA	$-9
$0042	$0E0B	MOVLW	11
$0044	$6E01	MOVWF	STACK_1, 0
$0046	$0EFF	MOVLW	255
$0048	$6E02	MOVWF	STACK_2, 0
$004A	$2E01	DECFSZ	STACK_1, F, 0
$004C	$D001	BRA	$+2
$004E	$D003	BRA	$+4
$0050	$2E02	DECFSZ	STACK_2, F, 0
$0052	$D7FE	BRA	$-1
$0054	$D7FA	BRA	$-5
$0056	$0E1A	MOVLW	26
$0058	$6E01	MOVWF	STACK_1, 0
$005A	$2E01	DECFSZ	STACK_1, F, 0
$005C	$D7FE	BRA	$-1
$005E	$0000	nop
$0060	$0E01	MOVLW	1
$0062	$6E02	MOVWF	STACK_2, 0
$0064	$1E02	COMF	STACK_2, F, 0
$0066	$5002	MOVF	STACK_2, W, 0
$0068	$1681	ANDWF	PORTB, F, 0
$006A	$0E0D	MOVLW	13
$006C	$6E01	MOVWF	STACK_1, 0
$006E	$0EFF	MOVLW	255
$0070	$6E02	MOVWF	STACK_2, 0
$0072	$2E01	DECFSZ	STACK_1, F, 0
$0074	$D001	BRA	$+2
$0076	$D003	BRA	$+4
$0078	$2E02	DECFSZ	STACK_2, F, 0
$007A	$D7FE	BRA	$-1
$007C	$D7FA	BRA	$-5
$007E	$0EF3	MOVLW	243
$0080	$6E01	MOVWF	STACK_1, 0
$0082	$2E01	DECFSZ	STACK_1, F, 0
$0084	$D7FE	BRA	$-1
$0086	$0EFF	MOVLW	255
$0088	$2615	ADDWF	main_global_vilkenb, F, 0
$008A	$0EFF	MOVLW	255
$008C	$6E15	MOVWF	main_global_vilkenb, 0
$008E	$0EFF	MOVLW	255
$0090	$B0D8	BTFSC	STATUS, C, 0
$0092	$0F01	ADDLW	1
$0094	$2615	ADDWF	main_global_vilkenb, F, 0
$0096	$D7BC	BRA	PimTest_L_2
$0098	$	PimTest_L_4:
$0098	$D7B9	BRA	PimTest_L_1
$009A	$D7B8	BRA	PimTest_L_1
$009C	$	PimTest_L_6:
$009C	$	PimTest_L_7:
$009C	$D7FF	BRA	PimTest_L_7
Användarvisningsbild
speakman
Inlägg: 4838
Blev medlem: 18 augusti 2004, 23:03:32
Ort: Ånge

Inlägg av speakman »

sodjan: kompilator då... men bara för den här gången! :twisted:

Mvh
speakman
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Inlägg av sodjan »

Alltså, tanken var att ha en *ENKEL* loop utan en massa onödigt som inte har med "FOR...STEP" att göra. Plocka bort allt utom något enkelt som går lätt att identifiera i asm koden, t.ex "PORTB = 0" eller liknande.

Måste man ha med do...until ?

Något i stil med :

Kod: Markera allt

program PimTest

dim vilkenb as short

for vilkenb = 3 to 0 step -1
    PORTB = 0
next vilkenb

end.
Jag misstänker att SetBit och ClearBit skapar en hel del kod (som är ointressant i detta fall), eftersom det inte finns någon direkt motsvarighet i assembler till det...
Skriv svar