PIC Opg 5 Løsning

Fra HTX Arduino
Spring til navigation Spring til søgning

Denne side gennemgår løsningen for PIC Opgave 5 - Flip-flops

Løsningsforslag for Flip-flop.

Generelt er alle løsningerne laved med den sædvanlig opstartskode til en PIC16F684, og selve funktionen realiseret i et forever loop.

include 16f684

-- Setup pic
pragma target clock 4_000_000
pragma target WDT DISABLED
pragma target OSC INTOSC_NOCLKOUT
pragma target PWRTE ENABLED
pragma target MCLR INTERNAL
pragma target CP DISABLED
pragma target CPD DISABLED
pragma target BROWNOUT ENABLED
pragma target IESO DISABLED
pragma target FCMEN DISABLED

include delay
--
enable_digital_io()                -- disable analog I/O (if any)
--
-- IO definitioner
porta_direction = all_input
portc_direction = all_output
--
alias Q  is pin_c0
alias Q_not  is pin_c1

Q_not = ! Q
-- Main loop
forever loop
   -- Flip-flop koden her
end loop

Som man kan se defineres udgangen Q til Q og den inverterede udgang Q til Q_not. Lige inden man går ind i forever-loopet sættes Q_not til det inverterede af Q.

Der er forskellige typer flip-flop, men generelt for alle typer er det at de indeholder et hukommelses-element. Det fremgår ikke så tydeligt af løsningerne, da de alle anvender portens indbyggede hukommelse (at en portben bliver stående på det niveau det er sat til, hvis man ikke gør noget ved det).

Koden som jal-filer

Alle eksemplerne kan hentes i denne ZIP-fil.

RS-flip-flop

Som man kan læse i sandhedstabellen under RS-flip-flop, så er der to indgange, en Set (S) og en Reset (R), hvor S sætter udgangen Q til høj, og R sætter udgangen Q til lav. Q_not er normalt det modsatte af Q. Hvis man både setter og resetter er udgangen udefineret, og i koden her er det valgt at sætte både Q og Q_not til høj.

I initialiseringen defineres de to indgange R og S:

alias R is pin_A0
alias S is pin_A1

Funktionen af RS-flip-flopen er realiseret med følgende kode:

35   if S then
36      if ! R then
37         Q = high
38         Q_not = low
39      else
40         Q = high
41         Q_not = high
42      end if
43   else
44      if R then
45         Q = low
46         Q_not = high
47      end if
48   end if

Linje 35 tester om S-benet er sat, og linje 36 tester så om R-benet ikke er sat, hvis begge dele er tilfældet, så stiller linje 37-38 udgangene, så flip-flopen er sat.

Linje 39-42 udføres hvis begge indgange er sat (og sætter begge udgange høje).

Linje 43 er hvis S-benet ikke er sat, hvor man så i linje 44 tester om R-benet er at, og hvis det er så stiller linje 45-46 udgangene, så flip-flippen er resat.

Linje 47-48 er afslutningerne på hhv. R sætningen og S sætningen.

Hele koden ligger i filen RS-FF.jal inde i ZIP-filen.

D-flip-flop

Som det kan ses i sandhedstabellen unde D-flip-flop, så er der en data-indgang D og en clock-indgang CLK. Når CLK går fra lav til høj, så sættes udgangen Q til det niveau D har, og Q_not sættes til det inverterede.

Indgangene er defineret som følger:

alias D is pin_A2
alias CLK is pin_A3

For at registrere om CLK laver et skift fra lav til høj (positivt gående kant), så kan man læse en mekanisme under Trykknap#Forkant der giver en generel måde at gøre det på, dette kræver en variabel som vi definerer her, og sætter til det niveau som CLK har i starten af programmet:

var bit CLK_last = CLK

Hele koden inde i forever-loopet til D-flip-flopen ser ud som følger:

37   if CLK then
38      if ! CLK_last then
39         Q = D
40         Q_not = ! D
41      end if
42      CLK_last = high
43   else
44      CLK_last = low
45   end if

Hovedparten af koden: linje 37-38 og linje 41-45 drejer sig om at finde ud af om det er en forkant. Linje 39-40 er det der udføres når man har fundet en forkant.

Hele koden ligger i filen D-FF.jal inde i ZIP-filen.

JK-flip-flop

Som det kan ses i sandhedstabellen unde JK-flip-flop, så er der to data-indgange J og K samt en clock-indgang CLK. Når CLK går fra lav til høj, så stilles udgangen Q ud fra de niveauer J og K har, og Q_not sættes til det inverterede.

  • Hvis både J og K er lave, så sker der ikke noget på udgangene, de forbliver det samme.
  • Hvis J er høj og K er lav, så sættes Q høj.
  • Hvis K er høj og J er lav, så sættes Q lav.
  • Hvis både J og K er høje, så toggler udgangen (høj bliver til lav, og lav bliver til høj)

Indgangene er defineret som følger:

alias CLK is pin_A3
alias J is pin_A4
alias K is pin_A5

For at registrere om CLK laver et skift fra lav til høj (positivt gående kant), bruges samme princip som ved D-flip-flopen igen med mekanismen fra Trykknap#Forkant.

Hele koden inde i forever-loopet til JK-flip-flopen ser ud som følger:

38   if CLK then
39      if ! CLK_last then
40         if J then
41            if K then
42               Q = Q_not
43               Q_not = ! Q
44            else
45               Q = high
46               Q_not = low
47            end if
48         else
49            if K then
50               Q = low
51               Q_not = high
52            end if
53         end if
54      end if
55      CLK_last = high
56   else
57      CLK_last = low
58   end if
59   delay_1ms(10)  -- Hindrer det meste prel

Hovedparten af koden: linje 38-39 og linje 54-58 drejer sig om at finde ud af om det er en forkant. Linje 40-41 finder toggle-delen og linje 42-43 løser Toggle-delen (at udgangen skifter). Linje 44-47 er der hvor J er høj og K er lav, så de sætter Q høj. Linje 48-53 er der hvor K er høj og J er lav, så der sættes Q lav. Hvis både J og K er lave, så skal flip-flopen ikke reagere, så det er ikke skrevet i koden.

En ting mere, som ikke var med i D-flip-flopen, er at man kan modtage to CLK-pulser lige efter hinanden.(det vil blot sætte samme niveau to gange på D-flip-flopen). Ved JK-flip-flopen kan det skabe problemer når den er i toggle-mode, og det er faktisk et reelt problem, som det er skitseret ved Trykknap#Prel, nemlig at når en kontakt laver forbindelse, så kan den lige idet den gør det have en overgang, hvor der skiftevis er forbindelse, og skiftevis ikke er det, det vil gøre at når den toggler, så vil den kunne modtage et lige antal, og dermed lande i samme tilstand (altså ikke toggle). Dette er forhindret ved at lægge et delay ind i loopet på 10 millisekunder, hvilket gør at det mest almindelige prel er overstået, uden at brugeren kan mærke den korte forsinkelse.

Hele koden ligger i filen JK-FF.jal inde i ZIP-filen.

Inde ved koderne ligger der også en JK-RS-FF.jal, som er en kombination af en JK-flip-flop og en RS-flip-flop, som også er realiseret i digitale kredse (de anvendes normalt ved at R eller S holder styr op opstarten, så man ved hvilken stilling den står i som udgangspunkt).

Toggle-flip-flop

Som det kan ses i sandhedstabellen unde Toggle-flip-flop, så er der en indgang T, der angiver om den skal toggle og en clock-indgang CLK. Når CLK går fra lav til høj, så inverteres udgangen Q hvis T er høj, og Q_not sættes til det modsatte. Hvis T er lav sker der ingenting

Indgangene er defineret som følger:

alias T is pin_A2
alias CLK is pin_A3

For at registrere om CLK laver et skift fra lav til høj (positivt gående kant), som beskrevet ved D- og JK-flip-flop.

Hele koden inde i forever-loopet til Toggle-flip-flopen ser ud som følger:

36   if CLK then
37      if ! CLK_last then
38         if T then
39            Q = Q_not     -- Toggel output hvis T er høj
40            Q_not = ! Q
41         end if
42      end if
43      CLK_last = high
44   else
45      CLK_last = low
46   end if
47   delay_1ms(10)  -- Hindrer det meste prel

Hovedparten af koden: linje 36-36 og linje 42-46 drejer sig om at finde ud af om det er en forkant. Linje 38-41 er det der udføres når man har fundet en forkant, hvor den toggler udgangene, hvis T er høj, og ellers sker der ikke mere.

Som beskrevet ved JK-flip-flop, så er der sat 10 ms delay ind, for at mindske indvirkningen af prel.

Hele koden ligger i filen T-FF.jal inde i ZIP-filen.

Alle typer i et program

For lige at illustrere en måde at lægge flere programmer ind i samme PIC, så er det lavet et all-FF.jal.

Alle indgangene er defineret som følger:

alias R is pin_A0
alias S is pin_A1
alias D is pin_A2
alias T is pin_A2
alias CLK is pin_A3
alias J is pin_A0
alias K is pin_A1
alias skift is pin_A4

Den sidste indgang skift er til at skifte mellem de 4 typer flip-flop.

Internet i programmet er typerne defineret som tal på følgende måde:

const RS_FF = 0
const D_FF  = 1
const JK_FF = 2
const T_FF  = 3

Til at håndtere hvilken type det er, og til at finde kanten af skift er der defineret en byte og en bit som følger:

var byte type = RS_FF
var bit skift_last = skift

Hele koden inde i forever-loopet indeholder de 4 koder fra det foregående sat op som en CASE-struktur, men først håndteres skiftet mellem de 4 typer. Starten af koden ser ud som følgende:

52   portc = (portc & 0b1111_0011) | type << 2
53   if skift then
54      if ! skift_last then
55         type = (type + 1) & 0b0000_0011
56      end if
57      skift_last = high
58   else
59      skift_last = low
60   end if
61   CASE type OF
62     RS_FF : BLOCK

Linje 52 udlæser på bit 2 og bit 3 hvilen type det er der vises (binært tal fra 0-3) Linje 53-54 og linje 56-60 drejer sig om at finde ud af om der er en forkant på skift-inputtet. Linje 55 tæller typen en op når man har fundet en forkant.

På denne måde kan man skifte til den flip-flop man ønsker, og teste den, og så skifte videre til en anden type.

Linje 61-62 er lige starten af CASE-strukturen, der går på type. Den første BLOCK er koden til RS-flip-flopen, go så kommer det ellers der efter. Hele koden ligger i filen all-FF.jal inde i ZIP-filen.

Der er også lavet en version all2-FF.jal, der har præcist den samme funktion, men som bare viser at man kan genbruge den kode der detekterer CLK-indgangen, så den ikke skal laves for de 3 typer der har en CLK-indgang.

PIC
PIC-Typer PIC16F84 - PIC12F675 - PIC16F628 - PIC16F684 - PIC16F690 - PIC16F877 - PIC18F2550
Programmeringsbegreber Maskinkode - Mikrocontroller
Programmeringsmiljø PIC-brænder - UsbPicProg - Analog indgang - ICSP


Digitale Opgaver
Kombinatorisk Logik Opgave 1a - Opgave 1b - Opgave 2 - Opgave 3 - Opgave 4 - Opgave 5 - Opgave 6 - Opgave 7 - Opgave 8 - Opgave 9 - Opgave 10
Sekvensiel Logik Opgave 11 - Opgave 12 - Opgave 13 - Opgave 14
Analoge Opgaver
Modstande og Ohms lov Modstands Opgave 1 - Modstands Opgave 2 - Modstands Opgave 3 - Modstands Opgave 4 - Modstands Opgave 5 - Modstands Opgave 6 - Modstands Opgave 7 - Modstands Opgave 8 - Modstands Opgave 9 - Modstands Opgave 10
Kondensator og Spole Kondensator opgaver 1 - Kondensator DC opgave 1 - Kondensator AC opgave 1 - Spolen 1 - Seriekobling og parallelkobling - Spolen 2 - Beregning af spoleværdier (selvinduktionen) - Spolen 3 - Tidskonstant for RL-led - Spolen 4 - Beregning af induktiv-reaktansen
Operationsforstærker Opamp Opgave 1 - Opamp Opgave 2 - Opamp Opgave 3
Diverse Opgaver Opgaver Diagram - Opgaver Transformator - Transistor opgave - Zenerdiode Opgave 1
Programmerings Opgaver
Arduino Arduino Blink - Arduino Opgave 01 - Blink - Arduino Button - Analog Out - Arduino StateChangeDetection - Arduino termometer - Arduino termostat - Arduino udgangsforstærkning
PIC PIC Opgave 1 - Blink - PIC Opgave 2 - Gates - PIC Opgave 3 - Udvidet blink - PIC Opgave 4 - Kombinatorik - PIC Opgave 5 - Flip-flops - PIC Opgave 6 - Løbelys - PIC Opgave 6a - kontakt - PIC Opgave 7 - Udvidet løbelys - PIC Opgave 8 - Sekventielle kredsløb - PIC Opgave 9 - Multivibratorer - PIC Opgave 10 - Samtidighed - PIC Opgave 11 - Tastatur - PIC Opgave 12 - Display - PIC Opgave 13 - A-D converter - PIC Opgave 14 - Interrupt - PIC Opgave 15 - Seriel komm - PIC Opgave 16 - Lyskryds - PIC Opgave 17 - Tyverialarm
PIC Opgave Løsninger PIC Opg 1 Løsning - PIC Opg 2 Løsning - PIC Opg 3 Løsning - PIC Opg 4 Løsning - PIC Opg 5 Løsning