Sida 1 av 2
16F690, sätta en utgång till hög...
Postat: 1 oktober 2011, 14:43:59
av mickeliten
Hej.
Nu kommer en fråga från en glad amatör. En mycket glad amatör med betoning på amatör!
Jag ska ha en lysdiod att lysa när jag trycker på en knapp (PORTA.3).
Men mina kunskaper är begränsade till att få den att lysa så länge knappen är intryckt.
Jag vill att vid en puls från knappen så ska lysdioden gå hög som på en set-reset-vippa typ.
Hur sjutton får jag PORTC.0 att stanna hög?
Kod: Markera allt
#include "delays.c"
#pragma config |= 0x00D4
void delay10(char n);
void main( void)
{
TRISC.0 = 0;
TRISA.3 = 1;
while(1)
{
if ( PORTA.3 == 0 )
PORTC.0 = 1;
else
PORTC.0 = 0;
}
{
nop();
}
}
Hälsningar Micke.

Re: 16F690, sätta en utgång till hög...
Postat: 1 oktober 2011, 15:09:27
av Rick81
Du får lägga till en extra variabel för att detektera flanken.
Tex:
Kod: Markera allt
char edgeDetect = 0;
if(PORTC3 == 0)
{
edgeDetect = 0;
}
else if(PORTC3 == 1 && edgeDetect == 0)
{
edgeDetect = 1;
PORTC.0 = !PORTC.0; // Toggla LED
}
I koden gjorde jag så varje pulse togglar dvs går från släck till tänd eller tänd till släckt
Re: 16F690, sätta en utgång till hög...
Postat: 1 oktober 2011, 15:13:56
av sodjan
Hur skulle det fungera om du skriver ner det på papper ?
Rick81's kod fungerar inte alls. Eller, ja, den "fungerar" men
sannolikt inte som du vill...

Lysdioden kommer att byta
läge helt okontrollerat.
Ditt program måste "minnas" hur både utgången och ingången
såg ut "förra gången" i loopen. Sedan måste du läsa på om
kontaktstudsar när det gäller mekaniska kontakter, det
måste du ta hänsyn till.
Du måste alltså först se till att du har kod som *unikt* kan
identifiera ett "tryck" på knappen inkl "släpp" av knappen.
Det normala är att ha en timer som genererar ett avbrott med
lämpligt intervall, kanske 10 eller 100 ms. Då har man en tidbas
att utgå från. 3-4 på varandra stabila lägen kan anses som
ett "avstudsat" läge.
Sedan, varje gång ovanstående inträffar, byta läga på RC0.
Antingen har du en variabel (flagga) i koden som håller reda
på läger på RC0 eller så läsr du bara av den direkt när det är
dags att byta läge.
Om RC0 = 0
- Sätt RC0 = 1
- Annars sätt RC0 = 0
Eller något sådant...
Re: 16F690, sätta en utgång till hög...
Postat: 1 oktober 2011, 15:27:32
av mickeliten
Tack för svaren.
Hmm, jag får faktiskt inte till det.
Jag har så begränsade kunskaper i C. Jag tänkte att detta att blinka en LED kunde vara ett bra
ställe att börja men jag vet inte...?
Jag lyckas bara att få till att den lyser medans jag håller knappen intryckt.
Det kan jag ju lösa med en återfjädrande knapp och en LED lika bra.
Nånstans ska man väl börja å...

Re: 16F690, sätta en utgång till hög...
Postat: 1 oktober 2011, 15:33:08
av sodjan
Jo, men mycket mer kan du inte göra med 5-6 rader kod !
För att få den funktion som du vill så gissar jag på minst 20,
kanske det dubbla, antalet rader inkl avstuds o.s.v.
Jag tror att du gör missen att försöka ta det hela på en gång.
Ta en sak i sänder. Börja med att få en säker avläsning av
knappen. Eller skit i knappen och lysdioden helt. Börja med
lite grunder d.v.s timers, interrupt o.s.v. Du verkar ju just
nu inte ha läst på speciellt mycket.
Re: 16F690, sätta en utgång till hög...
Postat: 1 oktober 2011, 15:50:33
av Rick81
För att ta hänsyn till studsar borde du kunna göra något i denna stilen:
Kod: Markera allt
char edgeDetect = 0;
char counter = 0;
char lastRC3 = 0;
if(PORTC3 == lastRC3)
{
if(counter > 10)
{
if(PORTC3 == 0)
{
edgeDetect = 0;
}
else if(PORTC3 == 1 && edgeDetect == 0)
{
edgeDetect = 1;
PORTC.0 = !PORTC.0; // Toggla LED
}
}
else
{
counter++;
}
}
else
{
counter = 0;
lastRC3 = PORTC3;
}
Re: 16F690, sätta en utgång till hög...
Postat: 1 oktober 2011, 16:08:40
av jesse
Det gäller att tänka ut vad som händer vid olika tillstånd.
Kolla den första koden som rick81 skrev. Försök sätta dig in i vad den gör. Hänger du med vad variabeln edgeDetect gör?
Om du inte orkar programmera avstuds just nu (det som gör att Sodjan inte tror att det exemplet fungerar) så använd en kondensator som avstudsare - dvs. sätt en 100nF kondensator mellan ingång och GND. Det brukar fungera ganska bra. (Dock inte superbra så det rekommenderas inte som enda åtgärd om du ska bygga något permanent)
Med kondensatorn så bör det funka med den enkla koden.
Är det någon speciell instruktion som du inte förstår?
Re: 16F690, sätta en utgång till hög...
Postat: 1 oktober 2011, 16:14:17
av sodjan
Nej, det tror jag inte alls fungerar.
Counter hinner sannolikt räkna till 10 flera gånger
för varje gång som kontakten studsar. Det måste till
en tidsfaktor. Notera att en kontakt som studsar under
kanske 50 ms är en väldigt långsam process jämfört
med processorn som kör flera instruktioner varje *us*,
den hinner tusentals instruktioner under *varje* studs!
Antingen delayloopar eller delay() funktioner (inte så snyggt)
eller (bättre) så sköts det i en avbrotts/interrupt rutin styrt
av en timer. Det är inte mycket som kan göras utan timers så
det finns ingen större anledning att inte läsa på lite om det.
Re: 16F690, sätta en utgång till hög...
Postat: 1 oktober 2011, 16:21:17
av mickeliten
Ja jag vet att jag måste läsa på mycket.
Jag skulle behöva läsa och lära mig hur C fungerar.
Jag kan i princip ingenting. Till och med svårt att veta vart man ska sätta { och ; etc...
Jag har hittat ett par sidor som jag tror kan ge nåt.
Ni får ju gärna fylla på med nybörjartips.
Det är som sagt inte bara kretsen jag behöver lära mig.
Hälsningar Micke
Re: 16F690, sätta en utgång till hög...
Postat: 1 oktober 2011, 16:32:56
av sodjan
Om du nu ändå har problem med C i sig också, så vet jag inte om det
är så klokt att försöka med allt på en gång. Du vet ju knappt hur
processorn fungerar heller, eller hur ?
Jag är övertygad om att det hela kommer att gå bättre, och i ett
hanterbart tempo, om du börjar med att försöka förstå processorn
genom att programmera i assembler !
Ett sådant exempel som du nu vill göra blir ungefär samma mängd
kod i assembler och du slipper att *samtidigt* försöka lära dig C.
Samt att du även förstår hur processorn fungerar.
För grunderna i C så är det enklare att ta ett Visual C Express
eller liknande.
Re: 16F690, sätta en utgång till hög...
Postat: 1 oktober 2011, 16:35:17
av sodjan
En annan sak, varför har du valt just RA3 som ingång för knappen ?
Vad är det för hårdvara ? PICkit2 Starter Kit ?
Har du kollat "PICkit 2 Lesson 6 - Switch Debounce" ?
Re: 16F690, sätta en utgång till hög...
Postat: 1 oktober 2011, 16:57:18
av Rick81
Det går bra att sätta gränsvärdet på counter till ex 250. Om inte det
räcker så är det bara att göra om till unsigned int så går den till 65360. Och då måste signalen ha samma värde i minst 65 ms.
Testa detta först det är lättare än timers.
Re: 16F690, sätta en utgång till hög...
Postat: 1 oktober 2011, 17:06:49
av mickeliten
sodjan,
ja du har rätt. Jag vet inte hur en processor jobbar. Sambons lillebror har försökt förklara ett och annat
för mig, men jag är mer som en gammal hund tror jag.
Det är PICKit2 jag använder så jag kör med det lilla experimentkortet som följde med och
där sitter knappen på RA3.
Nä det kanske är bättre att jag läser på assembler istället nu i början.
Jag tänkte att det kanske var vettigt att börja med samma som sambons lillebror brukar köra eftersom
jag trodde han skulle kunna lära mig, men begränsningarna sitter hos mig.

Re: 16F690, sätta en utgång till hög...
Postat: 1 oktober 2011, 17:14:23
av sodjan
> och där sitter knappen på RA3.
OK. RA3 fungerar (finns) bara om man stänger av MCLR (reset).
Det har andra sido effekter. Knappen på kortet ser jag primärt som
reset knapp. Om man vet vad man gör så går det bra att använda
den som generell "knapp".
> Sambons lillebror har försökt förklara ett och annat
Det borde gå mycket enklare för den som sitter bredvid.
Vad sa han om just detta "problem" ?
Sen så tycker jag att du har lite negativ inställning till det hela.
Det underlättar defintivt inte.
Man jag vet inte om det är meningsfullt att försöka lappa ihop
den där lilla kodsnutten, det blev lite fel från början.
Re: 16F690, sätta en utgång till hög...
Postat: 1 oktober 2011, 17:22:40
av mickeliten
Nej då jag har inte negativ inställning. Det är väl bara det att man vill att allt ska falla på plats på en gång.
Man vet ju att allt tar sin tid att lära sig, men man vill helst inte inse det.
Men får man nöta lite med det här också så kommer det väl mer och mer.
Det är svårt i början att veta vilken ände man ska börja i, särskilt när man inte har
några direkta baskunskaper.