Cuprins:
- Pasul 1: Detalii rapide și materiale
- Pasul 2: Conectarea hardware-ului
- Pasul 3: Explicație tehnică: Ecran
- Pasul 4: Explicație tehnică: Modificarea informațiilor afișate
- Pasul 5: Cod
Video: VHDL Basys3: Connect 4 Joc: 5 pași
2024 Autor: John Day | [email protected]. Modificat ultima dată: 2024-01-30 11:44
Introducere:
Acesta este un joc de logică digitală Connect 4 proiectat în VHDL folosind software-ul Vivado și programat pe placa Basys3. Construcția și proiectarea acestui proiect sunt intermediare, dar noii veniți pot copia pașii și construi jocul digital.
Jocul funcționează ca jocul Connect 4. Jucătorii își pot deplasa cursorul pe ecran folosind butoanele stânga și dreapta găsite pe tablă. Apăsarea butonului din mijloc de pe tablă va determina jucătorul să plaseze marcajul pe acea coloană și apoi va deveni rândul următorului jucător. Odată ce un jucător câștigă, jocul poate fi resetat apăsând butonul sus de pe tablă.
Pasul 1: Detalii rapide și materiale
Detalii tehnice rapide:
-
Utilizează trei seturi de conexiuni PMOD pe placă (JA, JB, JC)
- 8 pini (cu excepția pinilor Vcc și GND) utilizați pentru fiecare conector PMOD
- JA - Controlul rândurilor
- JB - Controlul coloanelor verzi
- JC - Controlul coloanelor roșii
-
Ceasul ecranului funcționează la 960Hz
Doar 8 LED-uri sunt aprinse la un moment dat. Ecranul se reîmprospătează la o viteză de ceas suficient de rapidă încât să ne dea iluzia că mai mult de 8 LED-uri sunt aprinse la un moment dat
- Butonul ceas funcționează la 5Hz; Opțional, poate fi amendat prin editarea codului VHDL.
- Rezistența internă a tablourilor Darlington este suficientă pentru a preveni arderea LED-urilor
Jocul este construit folosind următoarele componente și instrumente:
- (1) Consiliul Basys3
- (2) LED Matrix Bi-color 8x5:
- (2) ULN2803 - Matrice de tranzistori Darlington - Foaie de date
- Bobine de sârmă
- Sârme jumper
- Stripper de sârmă
- Panouri (pătratul mare ar trebui să fie suficient)
- Multimetru și sursă de alimentare (depanare)
Pasul 2: Conectarea hardware-ului
Instrucțiuni:
Cablarea proiectului poate fi extrem de complicată, vă rugăm să vă luați timp și să verificați dacă toate conexiunile sunt corecte, setate la rând.
Proiectul implică utilizarea a două ecrane LED, dar sunt combinate pentru a forma un ecran mare. Acest lucru se poate realiza conectând toate rândurile la același punct. Deoarece fiecare ecran este bicolor, rândurile roșii și verzi ale unui ecran trebuie, de asemenea, legate de rândurile roșii și verzi ale celuilalt ecran. Procedând astfel, putem controla toate rândurile cu doar 8 pini. Ceilalți 16 pini sunt utilizați pentru a controla coloanele afișajului. Cei 8 pini ai pot fi conectați direct prin cabluri jumper la conectorii pmod. Conexiunile Pmod merg mai întâi la intrarea ULN2083A, iar ieșirea ULN2083A este conectată direct la coloana de pe ecran. Deoarece designul este 8x8, unele coloane nu vor fi conectate fizic.
- JA: Conexiuni la rând: rândul 1 la JA: 1 la rândul 8 pentru JA: 10.
- JA: Conexiuni de coloană roșie:
- JC: Conexiuni coloane verzi
Vă rugăm să consultați imaginile postate pentru a afla ce pini corespund cu care rânduri / coloane.
Notă: Tranzistoarele au rezistențe încorporate, astfel încât LED-urile nu necesită rezistență suplimentară pentru a fi conectate la ele în serie.
Pasul 3: Explicație tehnică: Ecran
Ecranul funcționează asupra persistenței vederii. Ecranul este răcoritor atât de rapid, încât ochiul uman nu poate detecta vizibil faptul că unele LED-uri sunt rapid oprite și aprinse. De fapt, încetinind ceasul afișajului, se poate observa intermitent.
Afișajul pornește toate cele opt rânduri în funcție de datele stocate pentru aceste rânduri, iar afișajul pornește pe o coloană. Apoi trece rapid la următoarea intrare de date pentru cele opt rânduri și pornește următoarea coloană - în timp ce toate celelalte coloane sunt dezactivate. Acest proces continuă cu o viteză de ceas suficient de rapidă încât pâlpâirea LED-ului devine neobservabilă.
Stocarea datelor pentru afișaj este inițializată imediat după arhitectură în fișierul VHDL în modul următor:
semnal RedA, RedB, RedC, RedD, RedE, RedF, RedG, RedH: std_logic_vector (7 downto 0): = "00000000";
semnal GreenA, GreenB, GreenC, GreenD, GreenE, GreenF, GreenG, GreenH: std_logic_vector (7 downto 0): = "00000000"; - Date de rând în funcție de coloană: VERDE
Urmează un mic fragment al procesului care controlează matricea afișajului LED.
- Proces care controlează afișarea matricei LED: proces (ColCLK) - 0 - 16 pentru a reîmprospăta atât variabila matricei 8X8 RED, cât și 8x8 GREEn RowCount: interval întreg 0 la 16: = 0; începe if (rising_edge (ColCLK)) atunci if (RowCount = 0) atunci DORow <= RedA; - Date de rând pentru coloana DOCol corespunzătoare <= "1000000000000000"; - Declanșator coloană - Repetați acest cod până la "0000000000000001" - Treceți la RedB, RedC … GreenA, GreenB … GreenH
La sfârșitul GreenH, chiar înainte ca procesul să se încheie, acest fragment este inclus pentru a reseta RowCount la zero.
if (RowCount = 15) atunci - Reporniți reîmprospătarea din coloana A RowCount: = 0; else RowCount: = RowCount + 1; - Treceți prin coloane la sfârșit dacă;
Acum, pentru a explica ceasul care se află în lista de sensibilitate a procesului de afișare. Placa Basys3 are un ceas intern care funcționează la 100MHz. Pentru scopurile noastre, acesta este un ceas prea rapid, așa că va trebui să împărțim acest ceas la un ceas de 960Hz folosind următorul proces.
- Procesul ceasului funcționează la 960Hz CLK Divizor: proces (CLK) variabilă clkcount: interval întreg de la 0 la 52083: = 0; începeți dacă (rising_edge (CLK)) atunci clkcount: = clkcount + 1; if (clkcount = 52083) atunci ColCLK <= not (ColCLK); clkcount: = 0; incheie daca; incheie daca; sfarsitul procesului;
Pasul 4: Explicație tehnică: Modificarea informațiilor afișate
În codul VHDL, informațiile sau datele care vor fi afișate pe ecran sunt controlate de procesul cursorului, care are un ceas diferit în lista sa de sensibilitate. Acest cod s-a numit BtnCLK, un ceas conceput pentru a minimiza dezactivarea butoanelor atunci când acestea sunt apăsate. Aceasta este inclusă astfel încât, dacă este apăsat un buton, cursorul din rândul de sus nu se deplasează foarte repede peste coloane.
- Procesul de ceas funcționează la 5 Hz. Buton CLK: proces (CLK) variabilă btnclkcount: interval întreg de la 0 la 10000001: = 0; începe if (rising_edge (CLK)) atunci if (btnclkcount = 10000000) atunci btnclkcount: = 0; BtnCLK <= nu (BtnCLK); else btnclkcount: = btnclkcount + 1; incheie daca; incheie daca; sfarsitul procesului;
Cu ieșirea de semnal BtnCLK a acestui proces, putem explica acum procesul cursorului. Procesul cursorului are doar BtnCLK în lista sa de sensibilitate, dar în blocul de cod, starea butoanelor este verificată și acest lucru va determina modificarea datelor pentru RedA, RedB … GreenH. Iată un fragment al codului cursorului, care include blocul de resetare și blocul pentru prima coloană.
cursor: variabilă proces (BtnCLK) OCursorCol: STD_LOGIC_VECTOR (2 până la 0): = "000"; - OCursorCol ține evidența variabilei coloanei anterioare NCursorCol: STD_LOGIC_VECTOR (2 până la 0): = "000"; - NCursorCol stabilește noua coloană a cursorului - Condiția RESET (butonul UP) - Tabloul este șters pentru ca jocul să poată reporni dacă (rising_edge (BtnCLK)) atunci dacă (RST = '1') atunci RedA <= "00000000"; RedB <= "00000000"; RedC <= "00000000"; RedD <= "00000000"; RedE <= "00000000"; RedF <= "00000000"; RedG <= "00000000"; RedH <= "00000000"; GreenA <= "00000000"; GreenB <= "00000000"; GreenC <= "00000000"; GreenD <= "00000000"; GreenE <= "00000000"; GreenF <= "00000000"; GreenG <= "00000000"; GreenH if (Lbtn = '1') atunci NCursorCol: = "111"; - Coloana H elsif (Rbtn = '1') apoi NCursorCol: = "001"; - Coloana B elsif (Cbtn = '1') apoi NCursorCol: = OCursorCol; - Coloana rămâne aceeași NTurnState <= not (TurnState); - Declanșează rândul următorului jucător - Verifică coloana actuală de jos în sus și pornește primul LED care nu este aprins. Culoarea depinde de culoarea cursorului jucătorului curent. pentru ck în 7 bucle până la 1 dacă [RedA (0) = '1') și (RedA (ck) = '0') și (GreenA (ck) = '0') apoi RedA (Ck) <= '1'; RedA (0) <= '0'; IEȘIRE; incheie daca;
dacă (GreenA (0) = '1') și (RedA (ck) = '0') și (GreenA (ck) = '0') atunci
GreenA (Ck) <= '1'; GreenA (0) - Red Player GreenA (0) <= '0'; if (NCursorCol = OCursorCol) atunci - Dacă nu a fost apăsat nimic RedA (0) <= '1'; elsif (NCursorCol = "111") atunci - Dacă Lbtn a fost apăsat RedH (0) <= '1'; RedA (0) <= '0'; elsif (NCursorCol = "001") apoi - Iff Rbtn a fost apăsat pe RedB (0) <= '1'; RedA (0) - Green Player RedA (0) <= '0'; if (NCursorCol = OCursorCol) atunci GreenA (0) <= '1'; elsif (NCursorCol = "111") apoi GreenH (0) <= '1'; GreenA (0) <= '0'; elsif (NCursorCol = "001") apoi GreenB (0) <= '1'; GreenA (0) <= '0'; incheie daca; caz final;
Rețineți, prima afirmație de caz numită: OCursorCol (care înseamnă Old Cursor Column) este începutul mașinii cu stări finite. Fiecare coloană a afișajului este tratată ca o stare proprie în FSM. Există 8 coloane, astfel încât un set de numere binare pe 3 biți a fost utilizat pentru a identifica fiecare coloană ca stare. Modul în care se mută FSM între stare depinde de butonul care este apăsat. În fragmentul de mai sus, dacă este apăsat butonul din stânga, FSM se va deplasa la „111”, care ar fi ultima coloană a afișajului. Dacă este apăsat butonul din dreapta, FSM se va deplasa la „001”, care ar fi a doua coloană a afișajului.
Dacă butonul din mijloc este apăsat, FSM NU se va muta într-o stare nouă, ci va declanșa o schimbare a semnalului TurnState, care este un semnal de un bit pentru a nota rândul jucătorului. În plus, butonul din mijloc va rula un bloc de cod care verifică dacă există un rând gol în partea de jos până în partea de sus. Se va încerca să plaseze un marker în rândul inferior, neumplut. Amintiți-vă, acesta este un joc de conectare cu patru.
În declarația de caz imbricată numită: TurnState, modificăm care este culoarea cursorului și pentru ce coloană din primul rând dorim să schimbăm datele, astfel încât procesul de afișare să reflecte schimbarea.
Repetăm acest cod de bază pentru celelalte șapte cazuri. Diagrama FSM poate fi utilă pentru a înțelege modul în care se schimbă stările.
Pasul 5: Cod
Acesta este codul funcțional pentru Connect 4 care poate fi compilat în VHDL utilizând software-ul Vivado.
O constrângere este, de asemenea, furnizată pentru a vă permite să începeți jocul.
Am furnizat o diagramă bloc care explică modul în care intrările și ieșirile fiecărui proces sunt interconectate.
Recomandat:
Dispozitive Arduino Connect multiple I2C: 6 pași
Arduino Connect Multiple I2C Devices: În acest tutorial vom învăța cum să conectăm mai multe module cu o conexiune I2C la arduino. Urmăriți videoclipul! În cazul nostru vom folosi 4 afișaje OLED ca exemplu, dar puteți utiliza orice alte module I2C / senzori dacă doriți. Notă: 4 afișaje OLED co
Joc Simon - Joc distractiv !: 5 pași
Joc Simon - Joc distractiv !: Referință: Aici După un weekend lung, trebuie să fii cu adevărat greu să îndeplinești toate sarcinile și munca de care ești responsabil. Este timpul să ne antrenăm creierul, nu-i așa? Pe lângă acele jocuri plictisitoare și fără sens, există și un joc numit Simon Game
Controler de joc DIY bazat pe Arduino - Controler de joc Arduino PS2 - Jucând Tekken cu DIY Arduino Gamepad: 7 pași
Controler de joc DIY bazat pe Arduino | Controler de joc Arduino PS2 | Jucând Tekken cu DIY Arduino Gamepad: Bună, băieți, jocul este întotdeauna distractiv, dar jocul cu propriul controler personalizat DIY este mai distractiv
Cronometru de bază folosind placa VHDL și Basys3: 9 pași
Cronometru de bază folosind placa VHDL și Basys3: Bine ați venit la instrucțiunile despre cum să construiți un cronometru folosind placa de bază VHDL și Basys 3. Suntem încântați să vă împărtășim proiectul nostru! Acesta a fost un proiect final pentru cursul CPE 133 (Digital Design) la Cal Poly, SLO în toamna anului 2016. Proiectul pe care îl construim
Consola de joc Arduino Pocket + A-Maze - Joc Maze: 6 pași (cu imagini)
Arduino Pocket Game Console + A-Maze - Maze Game: Bine ați venit la primul meu instructable! Proiectul pe care vreau să îl împărtășesc astăzi este jocul de labirint Arduino, care a devenit o consolă de buzunar la fel de capabilă ca Arduboy și consolele similare bazate pe Arduino. Poate fi intermitent cu jocurile mele (sau ale dvs.) viitoare datorită expo