Sunteți pe pagina 1din 44

Sisteme

Incorporate
Proiect
Realizarea unei versiuni
simplificate
a celebrului joc Tetris

Elevi :

Stana Adelina gr 4.2


Teban Mihai gr 4.2

Enuntul proiectului

Realizarea unei versiuni simplificate a celebrului joc Tetris


folosind un microcontroler ATmega16A (2 studeni).
Caracteristici:
Se vor defini 3 sau 4 tipuri de piese de joc Tetris, la alegerea
studenilor .
Se va utiliza o matrice cu LED-uri (de dimensiune 8*8 sau
mai mare) pentru afiarea pieselor de joc, care au o micare
constant de cdere, pn n momentul n care acestea
ajung la baza ecranului.
In momentul n care la baza ecranului exist 2 linii complete
(toate LED-urile aprinse), acestea vor disprea pentru a face
loc noilor piese, iar variabila ce reprezint scorul juctorului
va fi incrementat cu o anumit valoare.
Deplasarea la stnga sau la dreapta a unei piese se va
realiza prin acionarea cte unui buton corespunztor
fiecrui sens (o apsare corespunde unei deplasri cu o
poziie).
Se va implementa funcionalitatea de rotire a unei piese de
joc, la apsarea unui buton.

A. Scurta descriere a senzorilor folositi

si a circuitului
dedicat utilizat pentru realizarea
proiectului.

1. ATmega16A
Acesta are 32 intrari/iesiri digitale , un oscilator la 16MHz, o conexiune pe USB, o
mufa de alimentare si un buton de reset. Consta intr-o platforma de mici dimensiuni (6.8
cm / 5.3 cm in cea mai des intalnita varianta) construita in jurul unui procesor de
semnal si este capabila de a prelua date din mediul inconjurator printr-o serie de
senzori si de a efectua actiuni asupra mediului prin intermediul luminilor, motoarelor,
servomotoare, si alte tipuri de dispozitive mecanice.
Procesorul este capabil sa ruleze cod scris intr-un limbaj de programare care este
foarte similar cu limbajul C++.

Descrierile pinilor

Nume
VCC
GND
Port A
(PA7:PA0)
Port B
(PB7:PB0)

Port C
(PC7:PC0)
Port D
(PD7:PD0)
/RESET

XTAL1
XTAL2
AVCC

AREF

Descriere
Digital supply voltage.
Ground.
Portul A servete ca intrre analogica la A / D Converter. Portul
A servete, de asemenea, ca un port I/O de 8 bii bidirecional n
cazul n care convertor A / D nu este utilizat.
Port B este un port I/O de 8 bii bidirecionali cu rezistene
interne pull-up (selecionat pentru fiecare bit). Pinii portului B
sunt tri-declarati atunci cnd o condiie de resetare devine
active , chiar dac clockul nu se execut.
Port C este un port I/O de 8 bii bidirecionali .
Port D este un port I/O de 8 bii bidirecionali . Tampoanele de
iesire ale portului D au caracteristici de actionare simetrice atat
cu capacitatea surs cat si cu high sink .
Reset Input . Un nivel sczut pe acest pin mai mult dect
lungimea minim de puls va genera o resetare , chiar dac
clockul nu se execut .
Intrare pentru amplificatorul inversor i intrarea pentru
clockul circuitul de operare .
Iesire din Oscilator.
AVCC este PIN-ul de tensiune de alimentare pentru Port A iA / D
Converter . Trebuie conectat extern la VCC , chiar
dac ADC nu este folosit . Dac se utilizeaz ADC , ar trebui s
fie conectat la VCC printr-un filtru low-pass .
AREF este PIN-ul de referin analogica pentru A / D Converter.

2. 2x Matrice de LED-uri 8X8, inlantuibila

MOD-LED 8x8 este o


matrice (de dimensiune
50 x 50
mm) de leduri inlantuibila care iti
permite sa obtii afisaje
cu
led-uri de orice .
Atunci
cnd vorbim despre o
matrice
de leduri 88 ne referim
la numrul de rnduri X coloane pe care aceasta le deine. Astfel
o matrice led 88 va avea 8 rnduri cu cte 8 leduri sau 8
coloane cu cte 8 leduri. n total o matrice 88 are 64 de leduri.
Putem spune c pe o matrice de leduri de 88 exist 64 de pixeli,
fiecare pixel formndu-se la intersecia unui rnd cu o coloan.
Pentru a tii cum putem aprinde sau stinge unul din cei 64 de
pixeli este foarte important s urmrim specificaiile
productorului (schema electrica).

3.Bread Board
Un Breadboard, numit si protoboard, reprezinta o baza de
constructie pentru realizarea de prototipuri in electronica.
Termenul de breadboard este deobicei utilizat pentru a face
referire la faptul ca acest gen de placa nu necesita lipituri pentru
a realiza conexiunea elementelor (fiind de genul plugboard).
Datorita faptului ca elementele nu trebuie lipite pe placa, aceasta
poate fi refolosita. Acest lucru faciliteaza crearea de noi
prototipuri temporare si de diferite design-uri de circuite.
Un breadboarb consta dintr-un bloc perforat care are clipuri de
staniu sau bronz fosforos sau nichel sub perforatii . Clipurile sunt

adesea numite puncte de legtur sau punctele de contact.


Numrul de puncte de legtur este de multe ori dat n caietul de
sarcini al breadboard. Distana dintre clemele este de obicei de
0,1 in (2,54 mm).

4.Multiplexorul DG409
DG409 este un multiplexor analogic cu 8 canale facut
pentru a conecta una dintre cele opt intrri la o ieire comun
determinat printr-o adres pe 2 bii (A0, A1).
Canalul ON conduce la fel de bine curentul in ambele directii
la fel de bine . In starea off fiecare canal blocheaza voltajul . O
functie (EN) permite utilizatorului sa reseteze multiplexor /
demultiplexorul . Toate intrrile de control, adresa (Ax)
i enable (EN) sunt compatibile TTL.
Schema bloc :

Tabelul de adevar :
A2
X
0
0
1
1

A1
x
0
1
0
1

A0
X
0
1
0
1

EN
0
1
1
1
1

ON
SWITCH

None
1
2
3
4

5.Protocolul de comunicatie folosit - UART


Conexiunea este de tip UART (universal asynchronous
receiver/transmitter) care translateaza date din forma paralela in
forma serial si invers .UART ia bytes de date si tramsmite bitii
individuali intr-un mod secvential . La destinaie, un al doilea
UART re-asambleaz biii n octei complet. Fiecare UART conine
un registru de deplasare, care este metoda fundamental de
conversie ntre formele de seriala i paralela. Transmiterea seriala
de informaii digitale (bii) printr-un singur fir sau alt mediu este
mai puin costisitoare dect transmiterea n paralel prin mai multe
fire.

6. USB to Serial Bridge Controller - PL-2303HX

PL-2303HX ofer o soluie convenabil pentru conectarea


unui RS232, ca dispozitiv serial asincron fullduplex pentru orice Serial Bus (USB) host
capabil universal. PL-2303HX poate simula
portul COM tradiional pe majoritatea sistemelor
de operare care permitand aplicaiilor existente , bazate
pe portul COM sa migreze cu uurin . Profitnd de modul
USB de transferare in masa tampoane mari de date, precum
i de control automat de debit, PL-2303HX este capabil s
ating randament mai mare comparativ cu UART tradiionale
(Universal Asincron Receptor Emitor) porturi.

7.

Pin

Name

Description

TXD

Serial Port (Transmitted Data)

DTR_N

Serial Port (Data Terminal Ready)

RTS_N

Serial Port (Request To Send)

VDD_325

RS232 VDD. The power pin for the serial port signals. When
the serial port is 3.3V, this should be 3.3V. When the serial port
is 2.5V, this should be 2.5V. The range can be from 1.8V~3.3V.

RXD

6
7

RI_N
GND

Ground

NC

No Connection

DSR_N

Serial Port (Received Data)


Serial Port (Ring Indicator); or Auxiliary General Purpose I/O

Serial Port (Data Set Ready); or Auxiliary General Purpose I/O


Serial Port (Data Carrier Detect); or Auxiliary General Purpose
10

DCD_N
Serial Port (Clear to Send); or Auxiliary General Purpose I/O

11

CTS_N

12

SHTD_N

RS232 Transceiver Shut Down Control

13

GP3

Auxiliary GPIO Pin 3 (Default output high mode)

14

GP2

Auxiliary GPIO Pin 2 (Default output high mode)

15

DP

USB Port D+ signal

16

DM

USB Port D- signal

17

VO_33

Regulator Power Output, 3.3V

18

GND

Ground

19

RESET_N

External System Reset (Active Low)

20

VDD_5

USB Port VBUS, 5V Power. (6.5V for OTPROM writing voltage).

21

NC

No Connection

22

GP0

General Purpose I/O Pin 0

23

GP1

General Purpose I/O Pin 1

24

NC

No Connection

25

GND

Ground

26

TEST

Test mode control

27

NC

No Connection

28

Reserved

Reserved pin (Must be floating)

Programatorul AVRISP mkII

Programeaza Flash si EEPROM


Suporta tensiuni int de la 1.8V la 5.5V
Viteza reglabila de programare ISP (50Hz la 8MHz frecven )
USB compatibil (viteza maxima, 12Mbps) 2.0
Alimentat de la USB, nu are nevoie de surs de alimentare extern
Protecie interfa int
Protecie la scurtcircuit

B. Schema completa a sistemului :

C. Cod
#include
#include
#include
#include

"algorithm.h"
"matrix.h"
"figure.h"
"UART.h"

U8_T speed = 0;
S8_T row = 0;
S8_T column = 0;
S8_T last_row = 0;
S8_T last_column = 0;

U8_T fig_init = 0;
U16_T counter = 0;
U16_T timer = SPEED; //10000 ~ 1 sec
U16_T score = 0;
U8_T figure_number = 0;
U8_T figure_position = 0;
U8_T matrix[16][8] = {{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0}};
U8_T figure[4][4] = {{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}};

void process_game()
{
counter++;
if (fig_init == 0)
{
figure_init();
}
if (counter > timer)
{
if (timer > 2000)
{
timer = timer - 20;
}
if (fig_init == 1)

{
USART_WriteChar(score);
figure_change_position(nothing);
}
}
if (counter % 5 == 0)
{
matrix_clear();
matrix_display();
}
}
U8_T figure_random()
{
return (rand()+1+figure_number)%4;
}
void figure_copy(U8_T fig[4][4])
{
U8_T i = 0;
U8_T j = 0;
for (i=0; i<4; i++)
{
for (j=0; j<4; j++)
{
figure[i][j] = fig[i][j];
}
}
}
void figure_init()
{
if (fig_init == 0)
{
USART_WriteChar(score);
figure_number = figure_random();
figure_position = 0;
fig_init = 1;
row = -1;
column = 3;
last_row = -1;
last_column = 3;

}
switch(figure_number)
{
case 0:
{
switch(figure_position)
{
case 0:
{
figure_copy(figure1A);
break;
}
case 1:
{
figure_copy(figure1B);
break;
}
case 2:
{
figure_copy(figure1C);
break;
}
case 3:
{
figure_copy(figure1D);
break;
}
}
break;
}
case 1:
{
switch(figure_position)
{
case 0:
{
figure_copy(figure2A);
break;
}
case 1:
{
figure_copy(figure2B);
break;
}
case 2:
{
figure_copy(figure2C);

break;
}
case 3:
{
figure_copy(figure2D);
break;
}
}
break;
}
case 2:
{
switch(figure_position)
{
case 0:
{
figure_copy(figure3A);
break;
}
case 1:
{
figure_copy(figure3B);
break;
}
case 2:
{
figure_copy(figure3C);
break;
}
case 3:
{
figure_copy(figure3D);
break;
}
}
break;
}
case 3:
{
switch(figure_position)
{
case 0:
{
figure_copy(figure4A);
break;
}
case 1:
{

figure_copy(figure4B);
break;
}
case 2:
{
figure_copy(figure4C);
break;
}
case 3:
{
figure_copy(figure4D);
break;
}
}
break;
}
default:
{
}
}
}
void matrix_figure_clear()
{
S8_T i = 0;
S8_T j = 0;
for (i=last_row; i>=last_row-3 && i>=0; i--)
{
for (j=last_column; j<=last_column+3 && j<=7; j++)
{
if (figure[3-(last_row-i)][j-last_column] == 1)
{
matrix[i][j] = 0;
}
}
}
}
void matrix_figure_fill()
{
S8_T i = 0;
S8_T j = 0;
last_row = row;
last_column = column;

for (i=row; i>=row-3 && i>=0; i--)


{
for (j=column; j<=column+3 && j<=7; j++)
{
if (figure[3-(row-i)][j-column] == 1)
{
matrix[i][j] = figure[3-(row-i)][j-column];
}
}
}
}
void matrix_reset()
{
U8_T i = 0;
U8_T j = 0;
for (i=0; i<16; i++)
{
for (j=0; j<8; j++)
{
matrix[i][j] = 0;
}
}
row = -1;
column = 3;
last_row = -1;
last_column = 3;
}
void matrix_full_row_check()
{
S8_T i = 0;
S8_T j = 0;
S8_T k = 0;
U8_T complete = 0;
i = 15;
while (i>0)
{
complete = 1;
for (j=0; j<8; j++)
{
if (matrix[i][j] == 0)

{
complete = 0;
}
}
if (complete == 1)
{
k = i;
while (k>0)
{
for (j=0; j<8; j++)
{
matrix[k][j] = matrix[k-1][j];
}
k--;
}
i = 15;
score = score + 10;
}
else
{
i--;
}
}
}
void figure_change_position(U8_T position)
{
switch (position)
{
case 255: //do nothing
{
}
case nothing: // nothing pressed
{
if (counter > timer)
{
counter = 0;
S8_T i = 0;
U8_T j = 0;
U8_T forbidden = 0;
matrix_figure_clear();

for (i=row+1; i>=row-2 && i>=0; i--)


{
for (j=column; j<=column+3 && j<=7; j++)
{
if ((matrix[i][j] == 1) && (figure[3-(row+1-i)][jcolumn] == 1))
{
forbidden = 1;
}
}
}
if ((forbidden == 0) && (row<15))
{
row++;
matrix_figure_clear();
matrix_figure_fill();
}
else
{
matrix_figure_fill();
matrix_full_row_check();
fig_init = 0;
figure_init();
}
}
break;
}
case down: // pressed down
{
U8_T i = row + 1;
U8_T j = 0;
U8_T forbidden = 0;
while ((forbidden == 0) && (row < 15))
{
for (j=column; j<=column+3; j++)
{
if ((matrix[i][j] == 1) && (figure[3][j-column] == 1))
{
forbidden = 1;
}
}
if (forbidden == 0)
{
row++;

i++;
matrix_figure_clear();
matrix_figure_fill();
}
}
fig_init = 0;
matrix_full_row_check();
figure_init();
break;
}
case left: // pressed left
{
S8_T i = 0;
S8_T j = 0;
U8_T forbidden = 0;
if (column > 0)
{
j = column - 1;
for (i=row; i>=row-3 && i>=0; i--)
{
if ((matrix[i][j] == 1) && (figure[3-(row-i)][0] == 1))
{
forbidden = 1;
}
}
if (forbidden == 0)
{
column--;
matrix_figure_clear();
matrix_figure_fill();
}
}
break;
}
case right: // pressed right
{
S8_T i = 0;
S8_T j = 0;
U8_T forbidden = 0;
U8_T fig_last_column = 0;
for (j=3; j>0; j--)
{

for (i=0; i<4; i++)


{
if (figure[i][j] == 1)
{
fig_last_column = j;
break;
}
}
if (fig_last_column != 0)
{
break;
}
}
if (column <= 3 + (3-fig_last_column))
{
j = column + fig_last_column + 1;
for (i=row; i>=row-3 && i>=0; i--)
{
if ((matrix[i][j] == 1) && (figure[3-(row-i)]
[fig_last_column] == 1))
{
forbidden = 1;
}
}
if (forbidden == 0)
{
column++;
matrix_figure_clear();
matrix_figure_fill();
}
}
break;
}
case rotate: // pressed rotate
{
if (figure_position < 3)
{
figure_position++;
}
else
{
figure_position = 0;
}

matrix_figure_clear();
figure_init();
matrix_figure_fill();
break;
}
case reset:
{
timer = SPEED;
score = 0;
matrix_reset();
break;
}
default:
{
timer = SPEED;
score = 0;
matrix_reset();
break;
}
}
}

U8_T
U8_T
U8_T
U8_T

line1 = 0;
column1 = 0;
line2 = 8;
column2 = 0;

void matrix_display()
{
U8_T gasit1 = 0;
U8_T gasit2 = 0;
while (line1<8)
{
while ((column1<8) && (gasit1 == 0))
{
if (matrix[line1][column1] == 1)
{
activate_led_matrix1(column1 + 1, 8 - line1);
gasit1 = 1;
column1++;
break;
}
else
{
column1++;

}
}
if (gasit1 == 1)
{
break;
}
else
{
column1 = 0;
}
line1++;
}
if (line1 > 7)
{
line1 = 0;
}
while (line2<16)
{
while ((column2<8) && (gasit2 == 0))
{
if (matrix[line2][column2] == 1)
{
activate_led_matrix2(column2 + 1, 16 - line2);
gasit2 = 1;
column2++;
break;
}
else
{
column2++;
}
}
if (gasit2 == 1)
{
break;
}
else
{
column2 = 0;
}
line2++;
}

if (line2 > 15)


{
line2 = 8;
}
}

/*
* figure.h
*
* Created: 4/27/2015 10:04:27 PM

#include "common.h
#ifndef FIGURE_H_
#define FIGURE_H_
////////////////////////////////////////////////////////////////////////////////
U8_T figure1A[4][4] = {{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 1, 0},
{1, 1, 1, 0}};
U8_T figure1B[4][4] = {{0, 0, 0, 0},
{1, 0, 0, 0},
{1, 0, 0, 0},
{1, 1, 0, 0}};
U8_T figure1C[4][4] = {{0, 0, 0, 0},
{0, 0, 0, 0},
{1, 1, 1, 0},
{1, 0, 0, 0}};
U8_T figure1D[4][4] = {{0, 0, 0, 0},
{1, 1, 0, 0},
{0, 1, 0, 0},
{0, 1, 0, 0}};

////////////////////////////////////////////////////////////////////////////////
U8_T figure2A[4][4] = {{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 1, 0, 0},
{1, 1, 1, 0}};
U8_T figure2B[4][4] = {{0, 0, 0, 0},
{1, 0, 0, 0},
{1, 1, 0, 0},
{1, 0, 0, 0}};
U8_T figure2C[4][4] = {{0, 0, 0, 0},
{0, 0, 0, 0},
{1, 1, 1, 0},
{0, 1, 0, 0}};
U8_T figure2D[4][4] = {{0, 0, 0, 0},
{0, 1, 0, 0},
{1, 1, 0, 0},
{0, 1, 0, 0}};
////////////////////////////////////////////////////////////////////////////////
U8_T figure3A[4][4] = {{0, 0, 0, 0},
{0, 0, 0, 0},
{1, 1, 0, 0},
{0, 1, 1, 0}};
U8_T figure3B[4][4] = {{0, 0, 0, 0},
{0, 1, 0, 0},
{1, 1, 0, 0},
{1, 0, 0, 0}};
U8_T figure3C[4][4] = {{0, 0, 0, 0},
{0, 0, 0, 0},
{1, 1, 0, 0},
{0, 1, 1, 0}};
U8_T figure3D[4][4] = {{0, 0, 0, 0},
{1, 0, 0, 0},
{1, 1, 0, 0},
{0, 1, 0, 0}};

////////////////////////////////////////////////////////////////////////////////
U8_T figure4A[4][4] = {{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{1, 1, 1, 1}};
U8_T figure4B[4][4] = {{1, 0, 0, 0},
{1, 0, 0, 0},
{1, 0, 0, 0},
{1, 0, 0, 0}};
U8_T figure4C[4][4] = {{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{1, 1, 1, 1}};
U8_T figure4D[4][4] = {{1, 0, 0, 0},
{1, 0, 0, 0},
{1, 0, 0, 0},
{1, 0, 0, 0}};
////////////////////////////////////////////////////////////////////////////////

#endif /* FIGURE_H_ */

/*
* matrice.c
*
*/
#include "matrix.h"
void matrix_init()
{
DDRA = 0xFF;

DDRC = 0xFF;
PORTA = 0x00;
PORTC = 0x00;
}
void matrix_clear()
{
PORTA = 0x00;
PORTC = 0x00;
}
void activate_led_line_matrix1(U8_T line)
{
switch (line)
{
case 1:
{
PORTA |= (1 << VCC1A);
break;
}
case 2:
{
PORTA |= (1 << VCC1A) |
break;
}
case 3:
{
PORTA |= (1 << VCC1A) |
break;
}
case 4:
{
PORTA |= (1 << VCC1A) |
break;
}
case 5:
{
PORTA |= (1 << VCC1B);
break;
}
case 6:
{
PORTA |= (1 << VCC1B) |

(1 << VCC1A0);

(1 << VCC1A1);

(1 << VCC1A0) | (1 << VCC1A1);

(1 << VCC1A0);

break;
}
case 7:
{
PORTA |= (1 << VCC1B) | (1 << VCC1A1);
break;
}
case 8:
{
PORTA |= (1 << VCC1B) | (1 << VCC1A0) | (1 << VCC1A1);
break;
}
}
}
void activate_led_column_matrix1(U8_T column)
{
switch (column)
{
case 1:
{
PORTA |= (1 << GND1A);
break;
}
case 2:
{
PORTA |= (1 << GND1A) | (1 << GND1A0);
break;
}
case 3:
{
PORTA |= (1 << GND1A) | (1 << GND1A1);
break;
}
case 4:
{
PORTA |= (1 << GND1A) | (1 << GND1A0) | (1 << GND1A1);
break;
}
case 5:
{
PORTA |= (1 << GND1B);
break;
}

case 6:
{
PORTA |= (1 << GND1B) | (1 << GND1A0);
break;
}
case 7:
{
PORTA |= (1 << GND1B) | (1 << GND1A1);
break;
}
case 8:
{
PORTA |= (1 << GND1B) | (1 << GND1A0) | (1 << GND1A1);
break;
}
}
}
void activate_led_matrix1(U8_T line, U8_T column)
{
PORTA = 0x00;
activate_led_line_matrix1(line);
activate_led_column_matrix1(column);
}
void activate_led_line_matrix2(U8_T line)
{
switch (line)
{
case 1:
{
PORTC |= (1 << VCC2A);
break;
}
case 2:
{
PORTC |= (1 << VCC2A) | (1 << VCC2A0);
break;
}
case 3:
{
PORTC |= (1 << VCC2A) | (1 << VCC2A1);
break;
}

case 4:
{
PORTC
break;
}
case 5:
{
PORTC
break;
}
case 6:
{
PORTC
break;
}
case 7:
{
PORTC
break;
}
case 8:
{
PORTC
break;
}

|= (1 << VCC2A) | (1 << VCC2A0) | (1 << VCC2A1);

|= (1 << VCC2B);

|= (1 << VCC2B) | (1 << VCC2A0);

|= (1 << VCC2B) | (1 << VCC2A1);

|= (1 << VCC2B) | (1 << VCC2A0) | (1 << VCC2A1);

}
}
void activate_led_column_matrix2(U8_T column)
{
switch (column)
{
case 1:
{
PORTC |= (1 << GND2A);
break;
}
case 2:
{
PORTC |= (1 << GND2A) | (1 << GND2A0);
break;
}
case 3:
{

PORTC |= (1 << GND2A) | (1 << GND2A1);


break;
}
case 4:
{
PORTC
break;
}
case 5:
{
PORTC
break;
}
case 6:
{
PORTC
break;
}
case 7:
{
PORTC
break;
}
case 8:
{
PORTC
break;
}

|= (1 << GND2A) | (1 << GND2A0) | (1 << GND2A1);

|= (1 << GND2B);

|= (1 << GND2B) | (1 << GND2A0);

|= (1 << GND2B) | (1 << GND2A1);

|= (1 << GND2B) | (1 << GND2A0) | (1 << GND2A1);

}
}
void activate_led_matrix2(U8_T line, U8_T column)
{
PORTC = 0x00;
activate_led_line_matrix2(line);
activate_led_column_matrix2(column);
}

Interfata din C#

Cod C# :
#region Namespace Inclusions
using System;
using System.Linq;
using System.Data;
using System.Text;
using System.Drawing;
using System.IO.Ports;
using System.Windows.Forms;
using System.ComponentModel;
using System.Collections.Generic;
using SerialPortTerminal.Properties;
using System.Threading;
using System.IO;
#endregion
namespace SerialPortTerminal
{
#region Public Enumerations
public enum DataMode { Text, Hex }
public enum LogMsgType { Incoming, Outgoing, Normal, Warning, Error };
#endregion
public partial class frmTerminal : Form
{
#region Local Variables

// The main control for communicating through the RS-232 port


private SerialPort comport = new SerialPort();
// Various colors for logging info
private Color[] LogMsgTypeColor = { Color.Blue, Color.Green, Color.Black, Color.Orange,
Color.Red };
// Temp holder for whether a key was pressed
private bool KeyHandled = false;
private Settings settings = Settings.Default;
#endregion
#region Constructor
public frmTerminal()
{
// Load user settings
settings.Reload();
// Build the form
InitializeComponent();
// Restore the users settings
InitializeControlValues();
// Enable/disable controls based on the current state
EnableControls();
// When data is recieved through the port, call this method
comport.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
comport.PinChanged += new
SerialPinChangedEventHandler(comport_PinChanged);
this.myDelegate = new AddDataDelegate(AddDataMethod);
}
void comport_PinChanged(object sender, SerialPinChangedEventArgs e)
{
// Show the state of the pins
UpdatePinState();
}

#endregion

private void UpdatePinState()


{
this.Invoke(new ThreadStart(() => {
// Show the state of the pins
chkCD.Checked = comport.CDHolding;
chkCTS.Checked = comport.CtsHolding;
chkDSR.Checked = comport.DsrHolding;
}));
}

#region Local Methods


/// <summary> Save the user's settings. </summary>
private void SaveSettings()
{
settings.BaudRate = int.Parse(cmbBaudRate.Text);
settings.DataBits = int.Parse(cmbDataBits.Text);

cmbStopBits.Text);

settings.DataMode = CurrentDataMode;
settings.Parity = (Parity)Enum.Parse(typeof(Parity), cmbParity.Text);
settings.StopBits = (StopBits)Enum.Parse(typeof(StopBits),
settings.PortName = cmbPortName.Text;
settings.ClearOnOpen = chkClearOnOpen.Checked;
settings.ClearWithDTR = chkClearWithDTR.Checked;

settings.Save();

/// <summary> Populate the form's controls with default settings. </summary>
private void InitializeControlValues()
{
cmbParity.Items.Clear(); cmbParity.Items.AddRange(Enum.GetNames(typeof(Parity)));
cmbStopBits.Items.Clear(); cmbStopBits.Items.AddRange(Enum.GetNames(typeof(StopBits)));
cmbParity.Text = settings.Parity.ToString();
cmbStopBits.Text = settings.StopBits.ToString();
cmbDataBits.Text = settings.DataBits.ToString();
cmbParity.Text = settings.Parity.ToString();
cmbBaudRate.Text = settings.BaudRate.ToString();
CurrentDataMode = settings.DataMode;
RefreshComPortList();
chkClearOnOpen.Checked = settings.ClearOnOpen;
chkClearWithDTR.Checked = settings.ClearWithDTR;
// If it is still avalible, select the last com port used
if (cmbPortName.Items.Contains(settings.PortName)) cmbPortName.Text =

settings.PortName;
else if (cmbPortName.Items.Count > 0) cmbPortName.SelectedIndex =
cmbPortName.Items.Count - 1;
else
{
MessageBox.Show(this, "There are no COM Ports detected on this computer.\nPlease install a
COM Port and restart this app.", "No COM Ports Installed", MessageBoxButtons.OK,
MessageBoxIcon.Error);
this.Close();
}
}
/// <summary> Enable/disable controls based on the app's current state. </summary>
private void EnableControls()
{
// Enable/disable controls based on whether the port is open or not
gbPortSettings.Enabled = !comport.IsOpen;
txtSendData.Enabled = btnSend.Enabled = comport.IsOpen;
//chkDTR.Enabled = chkRTS.Enabled = comport.IsOpen;
if (comport.IsOpen) btnOpenPort.Text = "&Close Port";
else btnOpenPort.Text = "&Open Port";
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Left)

txtSendData.Text = "2";
SendData();
return true;

}
if (keyData == Keys.Right)
{
txtSendData.Text = "3";
SendData();
return true;
}
if (keyData == Keys.Down)
{
txtSendData.Text = "1";
SendData();
return true;
}
if (keyData == Keys.Space)
{
txtSendData.Text = "4";
SendData();
return true;
}
if (keyData == Keys.R)
{
txtSendData.Text = "5";
SendData();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
/// <summary> Send the user's data currently entered in the 'send' box.</summary>
private void SendData()
{
if (CurrentDataMode == DataMode.Text)
{
// Send the user's text straight out the port
comport.Write(txtSendData.Text);
// Show in the terminal window the user's text
Log(LogMsgType.Outgoing, txtSendData.Text + "\n");
}
else
{
try
{
// Convert the user's string of hex digits (ex: B4 CA E2) to a byte array
byte[] data = HexStringToByteArray(txtSendData.Text);
// Send the binary data out the port
comport.Write(data, 0, data.Length);
// Show the hex digits on in the terminal window
Log(LogMsgType.Outgoing, ByteArrayToHexString(data) + "\n");
}
catch (FormatException)
{

// Inform the user if the hex string was not properly formatted
Log(LogMsgType.Error, "Not properly formatted hex string: " + txtSendData.Text + "\n");
}

}
txtSendData.SelectAll();
}

/// <summary> Log data to the terminal window. </summary>


/// <param name="msgtype"> The type of message to be written. </param>
/// <param name="msg"> The string containing the message to be shown. </param>
private void Log(LogMsgType msgtype, string msg)
{
rtfTerminal.Invoke(new EventHandler(delegate
{
rtfTerminal.SelectedText = string.Empty;
rtfTerminal.SelectionFont = new Font(rtfTerminal.SelectionFont, FontStyle.Bold);
rtfTerminal.SelectionColor = LogMsgTypeColor[(int)msgtype];
rtfTerminal.AppendText(msg);
rtfTerminal.ScrollToCaret();
}));
}
/// <summary> Convert a string of hex digits (ex: E4 CA B2) to a byte array. </summary>
/// <param name="s"> The string containing the hex digits (with or without spaces).
</param>
/// <returns> Returns an array of bytes. </returns>
private byte[] HexStringToByteArray(string s)
{
s = s.Replace(" ", "");
byte[] buffer = new byte[s.Length / 2];
for (int i = 0; i < s.Length; i += 2)
buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16);
return buffer;
}
/// <summary> Converts an array of bytes into a formatted string of hex digits (ex: E4 CA
B2)</summary>
/// <param name="data"> The array of bytes to be translated into a string of hex digits.
</param>
/// <returns> Returns a well formatted string of hex digits with spacing. </returns>
private string ByteArrayToHexString(byte[] data)
{
StringBuilder sb = new StringBuilder(data.Length * 3);
foreach (byte b in data)
sb.Append(Convert.ToString(b, 16).PadLeft(2, '0').PadRight(3, ' '));
return sb.ToString().ToUpper();
}
#endregion
#region Local Properties
private DataMode CurrentDataMode
{
get
{
if (rbHex.Checked) return DataMode.Hex;
else return DataMode.Text;
}
set

if (value == DataMode.Text) rbText.Checked = true;


else rbHex.Checked = true;

}
}
#endregion

#region Event Handlers


private void lnkAbout_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
// Show the user the about dialog
(new frmAbout()).ShowDialog(this);
}
private void frmTerminal_Shown(object sender, EventArgs e)
{
Log(LogMsgType.Normal, String.Format("Application Started at {0}\n", DateTime.Now));
}
private void frmTerminal_FormClosing(object sender, FormClosingEventArgs e)
{
// The form is closing, save the user's preferences
SaveSettings();
}
private void rbText_CheckedChanged(object sender, EventArgs e)
{ if (rbText.Checked) CurrentDataMode = DataMode.Text; }
private void rbHex_CheckedChanged(object sender, EventArgs e)
{ if (rbHex.Checked) CurrentDataMode = DataMode.Hex; }
private void cmbBaudRate_Validating(object sender, CancelEventArgs e)
{ int x; e.Cancel = !int.TryParse(cmbBaudRate.Text, out x); }
private void cmbDataBits_Validating(object sender, CancelEventArgs e)
{ int x; e.Cancel = !int.TryParse(cmbDataBits.Text, out x); }
private void btnOpenPort_Click(object sender, EventArgs e)
{
bool error = false;
// If the port is open, close it.
if (comport.IsOpen) comport.Close();
else
{
// Set the port's settings
comport.BaudRate = int.Parse(cmbBaudRate.Text);
comport.DataBits = int.Parse(cmbDataBits.Text);
comport.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cmbStopBits.Text);
comport.Parity = (Parity)Enum.Parse(typeof(Parity), cmbParity.Text);
comport.PortName = cmbPortName.Text;
try
{

// Open the port


comport.Open();

}
catch (UnauthorizedAccessException) { error = true; }
catch (IOException) { error = true; }

catch (ArgumentException) { error = true; }


if (error) MessageBox.Show(this, "Could not open the COM port.
Most likely it is already in use, has been removed, or is unavailable.", "COM Port Unavalible",
MessageBoxButtons.OK, MessageBoxIcon.Stop);
else
{
// Show the initial pin states
UpdatePinState();
chkDTR.Checked = comport.DtrEnable;
chkRTS.Checked = comport.RtsEnable;
}
}
// Change the state of the form's controls
EnableControls();
// If the port is open, send focus to the send data box
if (comport.IsOpen)
{
txtSendData.Focus();
if (chkClearOnOpen.Checked) ClearTerminal();
}
}
private void btnSend_Click(object sender, EventArgs e)
{ SendData(); }
public delegate void AddDataDelegate(char myString);
public AddDataDelegate myDelegate;
public void AddDataMethod(char myString)
{
decimal decValue = myString;
}

textBoxScore.Text = decValue.ToString();

private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)


{
// If the com port has been closed, do nothing
if (!comport.IsOpen) return;
// This method will be called when there is data waiting in the port's buffer
// Determain which mode (string or binary) the user is in
if (CurrentDataMode == DataMode.Text)
{
// Read all the data waiting in the buffer
string data = comport.ReadExisting();
char dec = data[0];
textBoxScore.Invoke(this.myDelegate, new Object[] { dec });
// Display the text to the user in the terminal
Log(LogMsgType.Incoming, data);
}
else

// Obtain the number of bytes waiting in the port's buffer


int bytes = comport.BytesToRead;
// Create a byte array buffer to hold the incoming data
byte[] buffer = new byte[bytes];
// Read the data from the port and store it in our buffer
comport.Read(buffer, 0, bytes);
// Show the user the incoming data in hex format
Log(LogMsgType.Incoming, ByteArrayToHexString(buffer));

}
}
private void txtSendData_KeyDown(object sender, KeyEventArgs e)
{
// If the user presses [ENTER], send the data now
if (KeyHandled = e.KeyCode == Keys.Enter) { e.Handled = true; SendData(); }
}
private void txtSendData_KeyPress(object sender, KeyPressEventArgs e)
{ e.Handled = KeyHandled; }
#endregion
private void chkDTR_CheckedChanged(object sender, EventArgs e)
{
comport.DtrEnable = chkDTR.Checked;
if (chkDTR.Checked && chkClearWithDTR.Checked) ClearTerminal();
}
private void chkRTS_CheckedChanged(object sender, EventArgs e)
{
comport.RtsEnable = chkRTS.Checked;
}
private void btnClear_Click(object sender, EventArgs e)
{
ClearTerminal();
}
private void ClearTerminal()
{
rtfTerminal.Clear();
}
private void tmrCheckComPorts_Tick(object sender, EventArgs e)
{
// checks to see if COM ports have been added or removed
// since it is quite common now with USB-to-Serial adapters
RefreshComPortList();
}
private void RefreshComPortList()
{
// Determain if the list of com port names has changed since last checked
string selected = RefreshComPortList(cmbPortName.Items.Cast<string>(),
cmbPortName.SelectedItem as string, comport.IsOpen);

// If there was an update, then update the control showing the user the list

of port names

if (!String.IsNullOrEmpty(selected))
{
cmbPortName.Items.Clear();
cmbPortName.Items.AddRange(OrderedPortNames());
cmbPortName.SelectedItem = selected;
}
}
private string[] OrderedPortNames()
{
// Just a placeholder for a successful parsing of a string to an integer
int num;
// Order the serial port names in numberic order (if possible)
return SerialPort.GetPortNames().OrderBy(a => a.Length > 3 &&
int.TryParse(a.Substring(3), out num) ? num : 0).ToArray();
}
private string RefreshComPortList(IEnumerable<string> PreviousPortNames, string
CurrentSelection, bool PortOpen)
{
// Create a new return report to populate
string selected = null;
// Retrieve the list of ports currently mounted by the operating system
(sorted by name)

string[] ports = SerialPort.GetPortNames();

// First determain if there was a change (any additions or removals)


bool updated = PreviousPortNames.Except(ports).Count() > 0 ||
ports.Except(PreviousPortNames).Count() > 0;
// If there was a change, then select an appropriate default port
if (updated)
{
// Use the correctly ordered set of port names
ports = OrderedPortNames();
// Find newest port if one or more were added
string newest =
SerialPort.GetPortNames().Except(PreviousPortNames).OrderBy(a => a).LastOrDefault();
// If the port was already open... (see logic notes and reasoning in
Notes.txt)

if (PortOpen)
{
if (ports.Contains(CurrentSelection)) selected =

CurrentSelection;
}
else
{

else if (!String.IsNullOrEmpty(newest)) selected = newest;


else selected = ports.LastOrDefault();

if (!String.IsNullOrEmpty(newest)) selected = newest;


else if (ports.Contains(CurrentSelection)) selected =
CurrentSelection;

else selected = ports.LastOrDefault();

}
// If there was a change to the port list, return the recommended default

selection
}

return selected;

private void label3_Click(object sender, EventArgs e)


{
}
}

Bibliografie

Multiplexor DG408 - http://www.vishay.com/docs/70062/dg408.pdf


Registru de shiftare http://www.wvshare.com/datasheet/TI_PDF/SN74HC164.PDF
ATmega16A - http://www.atmel.com/Images/Atmel-8154-8-bitAVR-ATmega16A_Datasheet.pdf
USB to Serial Bridge Controller
-http://www.prolific.com.tw/UserFiles/files/ds_pl2303HXD_v1_4_4.p
df
AVRISP mkII - http://www.atmel.com/tools/avrispmkii.aspx