microbasic: variabel i delay_us(), hur gör jag?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
oJsan
EF Sponsor
Inlägg: 1541
Blev medlem: 11 november 2005, 21:36:51
Ort: Umeå
Kontakt:

Inlägg av oJsan »

En kort fråga bara... det var länge sedan jag använde basic, men är det verkligen samma operator för att jämföra som för att tilldela?
Ska man inte använda operatorn IS, eller är det bara i Visual Basic?...igorera mig om jag helt är ute och cyklar :lol:
Användarvisningsbild
Icecap
Inlägg: 26685
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

OK, vi ignorerar all vi orkar ;-)
Användarvisningsbild
Kalf
Inlägg: 249
Blev medlem: 5 november 2005, 09:59:45

Inlägg av Kalf »

Okay, nu har jag gjort några ändringar. Jag har lagt till if satsen i interupten istället, men jag lyckas inte ändra så jag får en kort och en lång signal. Det jag testat är att ändra värde på TMR0 = 96.

Här är koden:

Kod: Markera allt

program Tmr0

dim cnt as byte

sub procedure interrupt
   cnt = cnt + 1         
   if portb = $ff then
   TMR0   = 96
   INTCON = $20
   else
   TMR0 = 96
   INTCON = $20
   end if          

end sub

main:

  OPTION_REG = $84       
  trisb  =   0           
  portb  = $FF             
  TMR0   =  96
  INTCON = $A0           

  do
       if cnt = 200 then 
           portb  = not(portb)
           cnt = 0
       end if
  loop until 0 = 1
end.
Sedan skulle jag gärna vilja kunna ändra prescalern med en variabel också. Men man skulle inte sätta ifstasen i main, går det då att flytta option_reg till interupten?
Användarvisningsbild
Icecap
Inlägg: 26685
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Hur förväntar du att PORTB blir 0xFF?

Kod: Markera allt

sub procedure interrupt
   TMR0   = 96 ' Ska göras snabbt som ögat!
   INTCON = $20 ' Nolla interruptflaggan
   cnt = cnt - 1 'ä Räkna ner countern
  if cnt = 0 then ' om pulsens bredd är klar
    if (portb and $40) > 0 then ' eller vilken pinne den nu sitter på
      cnt = Pulsbredd1
      portb = portb and $BF ' Nollar pinnen
    else
      cnt = Pulsbredd2
      portb = portb or $40 ' Settar pinnen
    end if         
  endif
end sub
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Bearing:
> Om det skulle vara en ersättare för delay_ms är det [d.v.s FOR-loopar]
> väl en ekvivalent lösning men med variabel längd?

Japp, och precis lika sopiga lösningar. På den punkter är de "ekvivalenta"...

> Nåväl, du verkar känna till mer om Kalf:s application än jag.

Tror jag inte, men det förändrar i princip ingenting.
Det aktuella problemet löses bäst med timers.
Användarvisningsbild
Kalf
Inlägg: 249
Blev medlem: 5 november 2005, 09:59:45

Inlägg av Kalf »

Jag gjorde som jag tror icecap menar:

Men det fungerar inte, som jag sagt tidigare så har jag en led inkopplad till picen och nu lyser den bara.(Jag testade med en summer också
, för att se till att det inte kom så korta signaler så ögat inte hinner uppfatta dem.)

Kod: Markera allt

program Tmr0

dim cnt as byte

sub procedure interrupt
	
	TMR0 = 96
	INTCON = $20
	cnt = cnt - 1
		if cnt = 0 then
			if portb.0 > 0 then
				cnt = 200
				portb.0 = 0
			else
				cnt = 200
				portb.0 = 1
			end if
		endif
end sub

main:

  OPTION_REG = $84       
  trisb  =   0           
  portb  = $FF
  INTCON = $A0           

end.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> INTCON = $20 ' Nolla interruptflaggan

Nja, jo det gör den kanske, men den "nollar" samtidigt
6 andra bitar i INTCON, det ser lite okontrollerat ut.

Bättre med "INTCON.T0IF = 0".

Sen några andra saker som gör det hela mer lättläst...

> OPTION_REG = $84

1. Använd *binärt* format när du sätter FSR's där bitarna kan ha helt
olika funktion och inte utgär ett "värde". Alltså :
"OPTION_REG = %10000100" i detta fall.

2. Skriv även dit som kommentar i koden vad det är du *tror* att kommandot
gör så att det går att verifiera att du både *tänker* och *skriver* rätt (eller fel).

> main:
>
> OPTION_REG = $84
> trisb = 0
> portb = $FF
> INTCON = $A0
>
> end.

Ett program får **ALDRIG** komma till "end." !!!!
Vart tog din "do...loop" vägen ?? Utan den startar programmet
om från början hela tiden...

> går det då att flytta option_reg till interupten?

Du kan manipulera OPTION_REG var du vill i koden.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Ett litet tillägg...

Jag såg just detta i MB manualen :
In mikroBasic, the end. statement ... acts as an endless loop.
OK, så då ska det fungera utan do...loop, fine.

Men, personligen skulle jag ändå se till att programmet inte kommer till "end."...
Användarvisningsbild
Kalf
Inlägg: 249
Blev medlem: 5 november 2005, 09:59:45

Inlägg av Kalf »

>Vart tog din "do...loop" vägen ??

Jag gjorde som icecap sa och definerade portb.0 och satte värde på cnt i interupt prceduren. Så eftersom det var det den do...loopen gjorde så tog jag bort den ifån main. Men Hur skall jag göra där i main då, jag måste tydligen ha en loop eller goto eller liknande. Som det är nu så kommer den väll aldrig till interupten eller? Eller vart "hoppar" den dit? Måste man loopa den istället/också?


>Bättre med "INTCON.T0IF = 0".

Jag fattar inte riktigt detta med T0IF och T0IE
bearing
Inlägg: 11678
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Inlägg av bearing »

IE = Interrupt Enable
IF = Interrupt Flag

Sodjan:
Det gick inte att undvika att ta din kritik mot for-loop personligt. Därav min fortsatta argumentation för loopen som delay.
Självklart är en delayloop oftast kass. Det förstår nog de flesta enkelt.
I alla lägen är dock inte timers tillgängliga för delayer. Trådstartaren ville ha en variabel ersättare för delay_us, som är en delayloop. Alltså kunde man dra slutsatsen ett det gick med en loop. Föreslog därför detta.

Vår diskutionen känns dock helt onödig.
Användarvisningsbild
Kalf
Inlägg: 249
Blev medlem: 5 november 2005, 09:59:45

Inlägg av Kalf »

Nu är vi ganska helt off topic, men men. Bearing: Jag vill altså styra ett servo och eftersom sodjan vet det och både jag och han är överäns om att det är bäst att sköta detta med en timer, igentligen borde mina senaste inlägg ligga i en tidigar tråd som jag skapat. Bara för din information.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Jag fattar inte riktigt detta med T0IF och T0IE

OK, då är det dags att stänga av datorn, plocka fram databladet och läsa
kapitlet om interrupt. Det finns absolut ingen genväg till det... :-)
Det är lite onödigt att gå in på detaljer här, innan vi vet mer exakt vad
som är oklart.

> jag måste tydligen ha en loop eller goto eller liknande.

Se min rättelse. Tydligen inte i mikroBasic, men personligen tycker jag att
det är god programmeringssed att inte låta koden löpa fritt på slutet.

> Som det är nu så kommer den väll aldrig till interupten eller?

Som det ser ut så *borde* den göra det. Men det är jätte enkelt att kolla,
sätt dit en extra LED, tänd den på ett lämpligt ställe (t.ex i början på ISR'en)
så vet du säkert. Sedan kan du flytta runt "tändningen" för att debugga...

Bearing, helt rätt. Vi har naturligtsvis rätt båda två. Du svarade exakt på frågan,
jag ville styra mot en bättre lösning. Men båda har rätt på sitt sätt... :-)

Slutligen, var det verkligen bara vad IE resp IF är *förkortningar* för,
som var problemet ?

Nä, i morgon sparkar jag igång mikroBasic, kopplar upp en 16F62x och
testar lite. Jag kanske även har något 25 år gammalt Graupner servo
liggandes... :-)

Såg just en annan liten detalj...

> if portb.0 > 0 then

Notera att PORTB.0 *bara* kan vara "0" eller "1", alltså är det tydligare
att skriva "if portb.0 = 1" istället. Jag vet inte hur "smart" mikroBasic är,
men det kan bli effektivare kod på det sättet. Det blir i alla fall betydligt
tydligare Basic kod ! :-)
Användarvisningsbild
Kalf
Inlägg: 249
Blev medlem: 5 november 2005, 09:59:45

Inlägg av Kalf »

Nu får jag väll förklara(försvara eller vad du nu vill kalla det. :-P)

>var det verkligen bara vad IE resp IF är *förkortningar* för,
som var problemet ?

Ja, nu fattade jag det när jag såg den förklaringen.

>> jag måste tydligen ha en loop eller goto eller liknande.
>
>Se min rättelse. Tydligen inte i mikroBasic, men personligen tycker jag att
>det är god programmeringssed att inte låta koden löpa fritt på slutet.

Exakt vad är det man loopar då man bara låter det finnas en end.? Är det hela koden då eller?

>Notera att PORTB.0 *bara* kan vara "0" eller "1", alltså är det tydligare
att skriva "if portb.0 = 1" istället.

Detta gjorde jag för jag följde bara icecapskod vilken jag eventuellt missuppfattade.(?)

Sedan när du tidigare sa det att jag borde ha kommentarer i min kod så "brukar" jag ha det när jag kodar ett språk som jag kan. Jag har kodat en del hemsidor och liknande tidigare och när man kodar i php(som hela detta forumet är kodat i.) Så är det ockås viktigt att man lägger in kommentarer för att man skall fatta vad man har kodat då man skall felsöka eller ändra i koden. Så jag är mycket väl medveten om hur viktig kommentarerna är i koden.

Sedan en sak till. Du sa det att det är enklare ifall man skriver OPTION_REG och liknande med binära siffror, det är klart det är. Ifall jag hade skrivit koden ifrån början så hade jag gjort det, men nu så har jag tagit grunden på koden ifrån ett exempel som hör till mikrobasic.

Sedan så får jag upprepa min fråga: Var "hoppar" main till interupten i min kod?
bearing
Inlägg: 11678
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Inlägg av bearing »

Om du har programmerat PHP kanske det är bättre att du byter till C när du ska programmera PICar eftersom C och PHP har samma syntax nästan.

När TMR0 går från 0xFF -> 0x00 sätts T0IF. Om GIE och T0IE är satta anropas interruptet, oavsett var i huvudprogrammet exekvering ligger.
Eftersom att du inte visste detta verkar det vara en god ide' att - som Sodjan skriver - i lugn och ro läsa (minst) delarna om interrupt och timers i databladet.
Användarvisningsbild
Icecap
Inlägg: 26685
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Och den "end-loop" som finns i programmeringsspråket gör finns i nära nog alla compilers men den är bara för att stoppa programmet från att "gå berserk", om alla delar av programmet aktiveras av interrupt kan man fint låta bli att göra en egen loop.

Men sant är att har man inte greppad detta med interrupt helt och fullt blir det mycket besvärligt att komma i mål.
Skriv svar