Você está na página 1de 30

Projeto

Cronmetro e Temporizador
Disciplina: EN3723 Lgica Programvel.

Discentes:
Fernando Henrique Gomes Zucatelli
Fernando Soler
Turma: A/Diurno
Prof Dr. Rodrigo Reina Muoz.

Santo Andr, 16 de Dezembro de 2014

Sumrio
1.
2.
3.
4.
5.
6.
7.
8.

INTRODUO .................................................................................................................. 2
OBJETIVOS ....................................................................................................................... 2
METODOLOGIA............................................................................................................... 2
PARTE EXPERIMENTAL ................................................................................................ 3
RESULTADOS E DISCUSSO ....................................................................................... 5
CONCLUSO .................................................................................................................. 12
REFERNCIAS BIBLIOGRFICAS ............................................................................. 12
ANEXOS .......................................................................................................................... 12
8.1. Programa principal ..................................................................................................... 12

1. INTRODUO
O projeto consiste na implementao de dois dispositivos, um cronmetro
simples e um temporizador, que conta o tempo de um valor pr-programado at
zero. Inicialmente ser apresentado por meio do visor de cristal lquido duas opes
ao usurio, uma para cada dispositivo. Caso o cronmetro seja selecionado, os
displays de sete segmentos passaro a contar, a partir de zero, at que um dos
seguintes comandos seja dado: pause, start ou reset. Caso o temporizador seja
escolhido, o usurio ter de inserir um tempo, a partir do qual os displays marcaro
o tempo at zero, com a possibilidade de reiniciar a contagem do valor previamente
definido durante o processo de temporizao ou mesmo aps o seu trmino.

2. OBJETIVOS
Descrever e implementar um cronmetro digital e um temporizador utilizando
os displays de 7 segmentos do kit FPGA da Altera DE2-115, dando ao usurio a
opo de escolher um dos dois e exibindo as informaes principais no visor de
cristal lquido.

3. METODOLOGIA
O clock de 50 MHz da mquina ser usado como base de tempo para o
contador de centsimos de segundos no cronmetro, o programa deve permitir ao
usurio parar a contagem sem zerar, permitindo reinici-la daquele mesmo ponto,
parar a exibio do tempo atual sem parar de contar como forma de verificar um
tempo parcial como tempo de uma volta e tambm zerar a contagem reiniciando
todo o processo.
Para o temporizador, o clock ser utilizado para decrementar o valor prprogramado pelo usurio em horas, minutos e segundos, at que se atinja o valor
zero, ou a contagem seja interrompida, ou reiniciada ao valor inicial ou caso seja
zerado.
Algumas mensagens do momento de funcionamento so exibidas no visor de
cristal lquido (LCD) como meio de informar ao usurio a funo que est sendo
executado

pelo

programa,

como

informe

dos

modos

de

operao

CRONOMETRO e TEMPORIZADOR, e no caso do temporizador os ajustes de


tempo com AJUSTE SEGUNDOS, AJUSTE MINUTOS, AJUSTE HORAS.

Inicialmente foi testado o programa do LCD individualmente e depois


desenvolvido de maneira independente o programa do cronometro e temporizador,
inserido seus estados e funes e depois o programa do LCD foi adaptado para ser
inserido dentro do programa principal, sendo apenas definido o texto a ser exibido
na tela de LCD de acordo com o estado atual.

4. PARTE EXPERIMENTAL
Para a navegao entre todas as funes, apresentamos a mquina de
estados dividida em 3 figuras. Na Figura 1 apresenta-se a principal diviso do
programa, entre a metade relativa ao cronmetro e ao temporizador quando a
mquina est ligado, enquanto ela est no estado desligado aparece no visor a
mensagem CRONOMETRO E TEMPORIZADOR (dividida em 2 linhas).
A Figura 2 exibe a mquina de estados relativa ao cronmetro, na qual a
varivel B (vetor de dados de entrada) formada pela combinao das posies de
todas as 5 chaves de comando com exceo da liga/desliga (on_off no programa) e
da de seleo de modo (cron_1:temp_0 no programa), sendo que a regio de cdigo
concorrente com o comando CASE permite realizar a troca de funes com
agilidade e tambm expandir o tamanho da mquina em uma atualizao futura.
A Figura 3 apresenta a parte da mquina de estados respectiva do
temporizador. O estado de contagem possui uma condio na entrada para
determinar se alguma contagem anterior j foi iniciada, se nenhuma contagem
anterior foi registrada ento o valor inicial da contagem salvo, este valor poder ser
recuperado caso o usurio deseje entrando no estado de reiniciar contagem, neste
estado a condio na entrada da contagem feita de forma dual, i.e., os valores
iniciais salvos no inicio do processo de contagem sero copiados nos valores atuais
de contagem, permitindo o rpido reinicio de uma nova temporizao. A varivel que
controla este procedimento tambm atualizada sempre que for realizado algum
ajuste de tempo. Durante os estados de ajuste dos tempos, os respectivos visores
piscaro para indicar que este o valor a ser ajustado e tambm facilitar o comando
de incrementar ou decrementar as unidades e dezenas com uso dos 4 botes do kit
definidos no vetor de dados de entrada A.

Figura 1 Trecho inicial da mquina de estados iniciando a operao quando ligada e selecionando
entre cronmetro (Cron) e temporizador (Temp).

Figura 2 Trecho da mquina de estados de referente ao cronmetro. Cada estado abaixo


selecionado pela combinao de B, todos os estados so assim acessveis entre si, as combinaes
no contempladas param a contagem e apenas exibem o valor atual.

Figura 3 Trecho da mquina de estados de referente ao temporizador. Cada estado abaixo


selecionado pela combinao de B, todos os estados so assim acessveis entre si, as combinaes
no contempladas param a contagem e apenas exibem o valor atual.

5. RESULTADOS E DISCUSSO
Entre a Figura 4 e a Figura 9 apresentam-se as informaes vistas no visor
LCD para os principais estados da mquina de estado
A Figura 4 mostra estado inicial desligado da mquina, aps ela ser ligada, a
opo selecionada ser mostrada no LCD.

Na Figura 5 o visor LCD mostra somente a palavra CRONOMETRO indicando


que a funo cronmetro foi selecionada. Neste ponto a mquina de estados est
esperando o comando start para iniciar a contagem.
A Figura 6 mostra que a opo temporizador foi escolhida, assim, a prxima
etapa ajustar o tempo que se deseja contar.
A Figura 7 mostra o ajuste de segundos do temporizador, os dois displays de
sete segmentos referentes aos segundos piscam, indicando que esto sendo
alterados. A alterao pode ocorrer de unidades ou dezenas, tanto para cima quanto
para baixo, portanto possvel percorrer grandes escalas de tempo com grande
facilidade.
A Figura 8, por sua vez indica o ajuste dos minutos. Assim como no ajuste dos
segundos, os displays de sete segmentos referentes aos minutos piscam, indicando
que esto sendo alterados.
Por fim, a Figura 9 mostra o ajuste das horas, que funciona exatamente como
os ajustes de minutos e segundos.
Para selecionar qual ordem de magnitude ser ajustada, uma chave dentre um
conjunto de trs tem de ser acionada, sendo que cada chave corresponde s horas,
minutos ou segundos.

Figura 4 Visor LCD com nome do projeto indicando que a mquina est no estado desligada.

Figura 5 Visor LCD com apenas CRONOMETRO em exibio.

Figura 6 Visor LCD com apenas TEMPORIZADOR em exibio.

Figura 7 Visor LCD com TEMPORIZADOR e AJUSTE SEGUNDOS em exibio.

Figura 8 Visor LCD com TEMPORIZADOR e AJUSTE MINUTOS em exibio.

Figura 9 Visor LCD com TEMPORIZADOR e AJUSTE HORAS em exibio.

O programa funcionou corretamente navegando dentro da mquina de estados


e sem erros na exibio dos valores nos Displays Hexadecimais.
O tempo contado sofreu pouca alterao quando comparado com outros
cronmetros de relgios e celulares, indicando que a programao baseada no clock
da mquina foi feita de forma satisfatria com pouco desvio em termo de passos no
processo de contagem alterando o valor real em relao ao desejado.
A Figura 10 apresenta a disposio fsica dos pinos utilizados na interface.

Figura 10 Configurao dos pinos.

Sendo:
A On_off.
B Reinicio de contagem.
C Ajuste das horas do temporizador.
D Zera a contagem do cronmetro / Ajuste dos minutos do temporizador.
E Ajuste dos segundos do temporizador.

10

F Inicia a contagem do cronmetro / Disparo do temporizador


G Seleciona
eciona o modo de operao (Cronmetro
(Cronmetro ou temporizador).
H Acrscimo
rscimo de dezenas.
I Acrscimo de unidades.
J Decrscimo de dezenas.
K Decrscimo de unidades.

Ainda a combinao BCDE zera a contagem do temporizador e a combinao


EF continua a contagem do cronometro sem exibir nos displays.

Figura 11 Configurao dos pinos no Pin Planner. Conjunto de botes A, B, clock_maquina,


seletor entre cronmetro
cron
e temporizador e barramentos de dados do
d LCD.

Figura 12 Configurao dos pinos no Pin Planner. Variveis


veis de controle do LCD, chave geral do
sistema e sadas
sa
indicadoras do estado atual q.

11

Figura 13 Configurao dos pinos no Pin Planner. Variveis do display hexadecimal.

Figura 14 Configurao dos pinos no Pin Planner. Variveis do display hexadecimal.

12

6. CONCLUSO
O projeto permitiu englobar diversos aspectos da programao em VHDL como
mquinas de estados, sub-rotinas atravs do comando PROCEDURE para
simplificar a execuo de aes comuns a diversos trechos dos cdigos e estruturas
de seleo. Assim, ficou evidente a facilidade que a linguagem de alto nvel oferece
ao se projetar e implementar circuitos com funes variadas. Alm de que com o uso
do software Quartus a implementao fsica tambm muito simples, bastando
apenas associar as entradas e sadas do sistema com pinos fsicos do chip.

7. REFERNCIAS BIBLIOGRFICAS
DE2 115 Altera, Manual do Usurio. Disponvel em:
<ftp://ftp.altera.com/up/pub/Altera_Material/13.0/Boards/DE2115/DE2_115_User_Manual.pdf>. Acesso em 04 de Nov. 2014.

8. ANEXOS
8.1.

Programa principal

========================================
LIBRARY IEEE;
USE IEEE.STD_logic_1164.all;
USE IEEE.STD_LOGIC_ARITH.all;
USE IEEE.STD_LOGIC_UNSIGNED.all;

ENTITY Projeto_1_real_11_2 IS
PORT (clock_maquina

: IN BIT; -- relogio borda subida

cron_1_temp_0, on_off

: IN BIT; -- chaves de selecao

A
: IN BIT_VECTOR (3 DOWNTO 0);
B
: IN BIT_VECTOR (4 DOWNTO 0);
q
: BUFFER BIT_VECTOR (5 DOWNTO 0); --indicador do estado nos LEDs verdes
clkout_1, clkout_2, clkout_3 : BUFFER BIT;
HEX_0, HEX_1, HEX_2, HEX_3

: BUFFER BIT_VECTOR (6 DOWNTO 0);

HEX_4, HEX_5, HEX_6, HEX_7

: BUFFER BIT_VECTOR (6 DOWNTO 0);

--);

--PORT( -- LCD
LCD_RS, LCD_E
LCD_RW
LCD_ON

: OUT STD_LOGIC;
: OUT STD_LOGIC;
: OUT STD_LOGIC;

13

-- LCD_BLON

: OUT STD_LOGIC; Como nao ha backlight no Display de LCD, este

-- Com, CLK

: IN STD_LOGIC; -- CLK aqui vale por clock_maquina

parametro nao sera usado.

-- exec_lcd

: BUFFER STD_LOGIC;

BUS_DADOS

: INOUT STD_LOGIC_VECTOR(7 DOWNTO 0)

);
END Projeto_1_real_11_2;

ARCHITECTURE maquina_estados_geral OF Projeto_1_real_11_2 IS

-- Cron e Temp
TYPE

st

IS

(decresce,

temp,

cron_parado_exibe_Tc,

cron_parado_exibe_Tc_e,

cron_cont_exibe_Tc_e,

cron_cont_exibe_Tc, cron, selecao); -- novo tipo definido


SIGNAL estado_cron_temp : st;
-- LCD
TYPE letras_string IS ARRAY ( 0 TO 31 ) OF STD_LOGIC_VECTOR( 7 DOWNTO 0 );
TYPE TIPOS_DE_ESTADO IS
(SEGURA,FUNC_SET,LIGA_DISPLAY,DESLIGA_DISPLAY,LIMPA_DISPLAY,MODE_SET,Print_String,
LINE2,RETURN_HOME,DROP_LCD_E,RESET1,RESET2,RESET3);

SIGNAL estado, prox_comando

: TIPOS_DE_ESTADO;

SIGNAL Texto_LCD

: letras_string;

SIGNAL VALOR_BUS_DADOS, Prox_Letra

: STD_LOGIC_VECTOR(7 DOWNTO 0);

SIGNAL CLK2

STD_LOGIC_VECTOR(19 DOWNTO 0);


SIGNAL CONTA_LETRAS

: STD_LOGIC_VECTOR(4 DOWNTO

0);
SIGNAL CLK2_HABILITAR,LCD_RW_INT

: STD_LOGIC;

SIGNAL LETRAS_LINHA1, LETRAS_LINHA2 : STD_LOGIC_VECTOR(127 DOWNTO 0);

PROCEDURE soma_tempo(VARIABLE T_7, T_6, T_5, T_4, T_3, T_2, T_1, T_0: INOUT INTEGER RANGE 0 TO 9) IS
BEGIN
T_0 := T_0 + 1;
IF T_0 = 10 THEN
T_0

:= 0;

T_1

:= T_1 + 1;

IF T_1 = 10 THEN
T_1

:= 0;

T_2

:= T_2 + 1;

IF T_2 = 10 THEN
T_2

:= 0;

T_3 := T_3 + 1;
IF T_3 = 6 THEN
T_3

:= 0;

T_4 := T_4 + 1;
IF T_4 = 10 THEN
T_4

:= 0;

T_5 := T_5 + 1;
IF T_5 = 6 THEN
T_5

:= 0;

14

T_6 := T_6 + 1;
IF T_6 = 10 THEN
T_6

:= 0;

T_7 := T_7 + 1;
END IF;
END IF;
END IF;
END IF;
END IF;
END IF;
END IF;

END soma_tempo;
-PROCEDURE sub_tempo(VARIABLE T_7, T_6, T_5, T_4, T_3, T_2, T_1, T_0: INOUT INTEGER RANGE -1 TO 9) IS
-- Apenas copiada a rotina soma_tempo
BEGIN
IF T_7 = 0 AND T_6 = 0 AND T_5 = 0 AND T_4 = 0 AND T_3 = 0 AND T_2 = 0 AND T_1 = 0 AND T_0 = 0 THEN
--CONTADOR ZERADO
ELSE
T_0 := T_0 - 1;
IF T_0 = -1 AND (T_7 /= 0 OR T_6 /= 0 OR T_5 /= 0 OR T_4 /= 0 OR T_3 /= 0 OR T_2 /= 0 OR T_1 /=
0)THEN --testar com zero e depois mudar para -1
T_0

:= 9;

T_1

:= T_1 - 1;

IF T_1 = -1 THEN
T_1

:= 9;

T_2

:= T_2 - 1;

IF T_2 = -1 THEN
T_2

:= 9;

T_3 := T_3 - 1;
IF T_3 = -1 THEN
T_3

:= 5;

T_4 := T_4 - 1;
IF T_4 = -1 THEN
T_4

:= 9;

T_5 := T_5 - 1;
IF T_5 = -1 THEN
T_5

:= 5;

T_6 := T_6 - 1;
IF T_6 = -1 THEN
T_6

:= 9;

T_7 := T_7 - 1;
END IF;
END IF;
END IF;
END IF;
END IF;
END IF;
END IF;
END IF;

15

END sub_tempo;
-PROCEDURE zera_tempo(VARIABLE T_7, T_6, T_5, T_4, T_3, T_2, T_1, T_0: INOUT INTEGER RANGE 0 TO 9) IS
BEGIN
T_7 := 0; T_6:= 0; T_5:= 0; T_4:= 0; T_3:= 0; T_2:= 0; T_1 := 0; T_0 := 0;

END zera_tempo;
-PROCEDURE grava_tempo_inicial(
CONSTANT T_7, T_6, T_5, T_4, T_3, T_2, T_1, T_0: IN INTEGER RANGE 0 TO 9;
VARIABLE T_i_7, T_i_6, T_i_5, T_i_4, T_i_3, T_i_2, T_i_1, T_i_0 : OUT INTEGER RANGE 0 TO 9) IS
BEGIN
T_i_7 := T_7; T_i_6 := T_6;
T_i_5 := T_5; T_i_4 := T_4;
T_i_3 := T_3; T_i_2 := T_2;
T_i_1 := T_1; T_i_0 := T_0;
END grava_tempo_inicial;
-PROCEDURE verifica_9_soma(VARIABLE T_0: INOUT INTEGER RANGE 0 TO 9) IS
BEGIN
IF T_0 >= 9 THEN
T_0 := 0;
ELSE
T_0 := T_0 + 1;
END IF;
END verifica_9_soma;
-PROCEDURE verifica_5_soma(VARIABLE T_0: INOUT INTEGER RANGE 0 TO 9) IS
BEGIN
IF T_0 >= 5 THEN
T_0 := 0;
ELSE
T_0 := T_0 + 1;
END IF;
END verifica_5_soma;
-PROCEDURE verifica_9_sub(VARIABLE T_0: INOUT INTEGER RANGE 0 TO 9) IS
BEGIN
IF T_0 <= 0 THEN
T_0 := 9;
ELSE
T_0 := T_0 - 1;
END IF;
END verifica_9_sub;
-PROCEDURE verifica_5_sub(VARIABLE T_0: INOUT INTEGER RANGE 0 TO 9) IS
BEGIN
IF T_0 <= 0 THEN
T_0 := 5;
ELSE
T_0 := T_0 - 1;

16

END IF;
END verifica_5_sub;
--

PROCEDURE Exibe_HEX_all(
CONSTANT T_7, T_6, T_5, T_4, T_3, T_2, T_1, T_0: IN INTEGER RANGE 0 TO 10;
SIGNAL HEX_7, HEX_6, HEX_5, HEX_4, HEX_3, HEX_2, HEX_1, HEX_0 : INOUT BIT_VECTOR (6 DOWNTO 0))
IS

BEGIN
CASE T_0 IS
WHEN 0 => HEX_0 <= NOT("0111111");
WHEN 1 => HEX_0 <= NOT("0000110");
WHEN 2 => HEX_0 <= NOT("1011011");
WHEN 3 => HEX_0 <= NOT("1001111");
WHEN 4 => HEX_0 <= NOT("1100110");
WHEN 5 => HEX_0 <= NOT("1101101");
WHEN 6 => HEX_0 <= NOT("1111101");
WHEN 7 => HEX_0 <= NOT("0000111");
WHEN 8 => HEX_0 <= NOT("1111111");
WHEN 9 => HEX_0 <= NOT("1100111");
WHEN OTHERS => HEX_0 <= NOT("0000000");
END CASE;
CASE T_1 IS
WHEN 0 => HEX_1 <= NOT("0111111");
WHEN 1 => HEX_1 <= NOT("0000110");
WHEN 2 => HEX_1 <= NOT("1011011");
WHEN 3 => HEX_1 <= NOT("1001111");
WHEN 4 => HEX_1 <= NOT("1100110");
WHEN 5 => HEX_1 <= NOT("1101101");
WHEN 6 => HEX_1 <= NOT("1111101");
WHEN 7 => HEX_1 <= NOT("0000111");
WHEN 8 => HEX_1 <= NOT("1111111");
WHEN 9 => HEX_1 <= NOT("1100111");
WHEN OTHERS => HEX_1 <= NOT("0000000");
END CASE;
CASE T_2 IS
WHEN 0 => HEX_2 <= NOT("0111111");
WHEN 1 => HEX_2 <= NOT("0000110");
WHEN 2 => HEX_2 <= NOT("1011011");
WHEN 3 => HEX_2 <= NOT("1001111");
WHEN 4 => HEX_2 <= NOT("1100110");
WHEN 5 => HEX_2 <= NOT("1101101");
WHEN 6 => HEX_2 <= NOT("1111101");
WHEN 7 => HEX_2 <= NOT("0000111");
WHEN 8 => HEX_2 <= NOT("1111111");
WHEN 9 => HEX_2 <= NOT("1100111");
WHEN OTHERS => HEX_2 <= NOT("0000000");
END CASE;
CASE T_3 IS
WHEN 0 => HEX_3 <= NOT("0111111");

17

WHEN 1 => HEX_3 <= NOT("0000110");


WHEN 2 => HEX_3 <= NOT("1011011");
WHEN 3 => HEX_3 <= NOT("1001111");
WHEN 4 => HEX_3 <= NOT("1100110");
WHEN 5 => HEX_3 <= NOT("1101101");
WHEN 6 => HEX_3 <= NOT("1111101");
WHEN 7 => HEX_3 <= NOT("0000111");
WHEN 8 => HEX_3 <= NOT("1111111");
WHEN 9 => HEX_3 <= NOT("1100111");
WHEN OTHERS => HEX_3 <= NOT("0000000");
END CASE;
CASE T_4 IS
WHEN 0 => HEX_4 <= NOT("0111111");
WHEN 1 => HEX_4 <= NOT("0000110");
WHEN 2 => HEX_4 <= NOT("1011011");
WHEN 3 => HEX_4 <= NOT("1001111");
WHEN 4 => HEX_4 <= NOT("1100110");
WHEN 5 => HEX_4 <= NOT("1101101");
WHEN 6 => HEX_4 <= NOT("1111101");
WHEN 7 => HEX_4 <= NOT("0000111");
WHEN 8 => HEX_4 <= NOT("1111111");
WHEN 9 => HEX_4 <= NOT("1100111");
WHEN OTHERS => HEX_4 <= NOT("0000000");
END CASE;
CASE T_5 IS
WHEN 0 => HEX_5 <= NOT("0111111");
WHEN 1 => HEX_5 <= NOT("0000110");
WHEN 2 => HEX_5 <= NOT("1011011");
WHEN 3 => HEX_5 <= NOT("1001111");
WHEN 4 => HEX_5 <= NOT("1100110");
WHEN 5 => HEX_5 <= NOT("1101101");
WHEN 6 => HEX_5 <= NOT("1111101");
WHEN 7 => HEX_5 <= NOT("0000111");
WHEN 8 => HEX_5 <= NOT("1111111");
WHEN 9 => HEX_5 <= NOT("1100111");
WHEN OTHERS => HEX_5 <= NOT("0000000");
END CASE;
CASE T_6 IS
WHEN 0 => HEX_6 <= NOT("0111111");
WHEN 1 => HEX_6 <= NOT("0000110");
WHEN 2 => HEX_6 <= NOT("1011011");
WHEN 3 => HEX_6 <= NOT("1001111");
WHEN 4 => HEX_6 <= NOT("1100110");
WHEN 5 => HEX_6 <= NOT("1101101");
WHEN 6 => HEX_6 <= NOT("1111101");
WHEN 7 => HEX_6 <= NOT("0000111");
WHEN 8 => HEX_6 <= NOT("1111111");
WHEN 9 => HEX_6 <= NOT("1100111");
WHEN OTHERS => HEX_6 <= NOT("0000000");
END CASE;
CASE T_7 IS

18

WHEN 0 => HEX_7 <= NOT("0111111");


WHEN 1 => HEX_7 <= NOT("0000110");
WHEN 2 => HEX_7 <= NOT("1011011");
WHEN 3 => HEX_7 <= NOT("1001111");
WHEN 4 => HEX_7 <= NOT("1100110");
WHEN 5 => HEX_7 <= NOT("1101101");
WHEN 6 => HEX_7 <= NOT("1111101");
WHEN 7 => HEX_7 <= NOT("0000111");
WHEN 8 => HEX_7 <= NOT("1111111");
WHEN 9 => HEX_7 <= NOT("1100111");
WHEN OTHERS => HEX_7 <= NOT("0000000");
END CASE;
END Exibe_HEX_all;

--BEGIN
-LCD_ON <= '1';
-- Dados do LCD bidirecional
BUS_DADOS <= VALOR_BUS_DADOS WHEN LCD_RW_INT = '0' ELSE "ZZZZZZZZ";

-- Proximo letra da frase no LCD


Prox_Letra <= Texto_LCD(CONV_INTEGER(CONTA_LETRAS));
LCD_RW <= LCD_RW_INT;
-maq_est: PROCESS (clkout_2)
VARIABLE Tt_h1, Tt_h2, Tt_m2, Tt_s2, Tt_cs1, Tt_cs2

: INTEGER RANGE 0 TO 9;

VARIABLE Tt_m1, Tt_s1


: INTEGER RANGE 0 TO 5;

VARIABLE Tt_i_7, Tt_i_6, Tt_i_5, Tt_i_4, Tt_i_3

: INTEGER RANGE 0 TO 9;

VARIABLE Tt_i_2, Tt_i_1, Tt_i_0


INTEGER RANGE 0 TO 9;

VARIABLE Tc_h1, Tc_h2, Tc_m2, Tc_s2, Tc_cs1, Tc_cs2 : INTEGER RANGE 0 TO 9;


VARIABLE Tc_m1, Tc_s1
: INTEGER RANGE 0 TO 5;

VARIABLE Disparo_Temporizador
: BIT;
VARIABLE Pisca_Contador
: INTEGER RANGE 0 TO 20;
VARIABLE A_Aux_Contador
: INTEGER RANGE 0 TO 30;
BEGIN
IF on_off = '0' THEN
estado_cron_temp <= selecao;
Exibe_HEX_all( 0, 0, 0, 0, 0, 0, 0, 0,

19

HEX_7,

HEX_6,

HEX_5,

HEX_4,

HEX_3,

HEX_2, HEX_1, HEX_0);

zera_tempo(Tc_h1, Tc_h2, Tc_m1, Tc_m2, Tc_s1, Tc_s2, Tc_cs1, Tc_cs2);


zera_tempo(Tt_h1, Tt_h2, Tt_m1, Tt_m2, Tt_s1, Tt_s2, Tt_cs1, Tt_cs2);
Pisca_Contador := 0;
A_Aux_Contador

:= 0;

Disparo_Temporizador := '0';

Texto_LCD <= (
-- Escrita na primeira linha do display de LCD
-- "

"

X"20",X"20",X"43",X"52",X"4F",X"4E",X"4F",X"4D",X"45",X"54",X"52",X"4F",X"20",X"45",X"20",X"20",
-- Escrita na segunda linha do display de LCD - FRASE: "PASSO"
-- "
R

T
R

"

X"20",X"20",X"54",X"45",X"4D",X"50",X"4F",X"52",X"49",X"5A",X"41",X"44",X"4F",X"52",X"20",X"20");

ELSIF (clkout_2'EVENT and clkout_2 = '1') THEN


-- maquinas de estados
IF (cron_1_temp_0 = '1') THEN
CASE estado_cron_temp IS
-- maquinas do cronometro
-- seleciona na primeira passagem
WHEN cron => --0001
CASE B IS
-- contagem interrompida
WHEN "00000" =>
Exibe_HEX_all( Tc_h1, Tc_h2, Tc_m1, Tc_m2,
Tc_s1, Tc_s2, Tc_cs1, Tc_cs2,

HEX_7, HEX_6, HEX_5, HEX_4, HEX_3, HEX_2, HEX_1, HEX_0);

Texto_LCD <= (
-- "
O

"

X"20",X"20",X"20",X"43",X"52",X"4F",X"4E",X"4F",X"4D",X"45",X"54",X"52",X"4F",X"20",X"20",X"20",

X"20",X"20",X"20",X"20",X"20",X"20",X"20",X"20",X"20",X"20",X"20",X"20",X"20",X"20",X"20",X"20");

-- contagem
WHEN "00001" =>
soma_tempo(Tc_h1, Tc_h2, Tc_m1, Tc_m2,
Tc_s1, Tc_s2, Tc_cs1, Tc_cs2);
Exibe_HEX_all( Tc_h1, Tc_h2, Tc_m1, Tc_m2,
Tc_s1, Tc_s2, Tc_cs1, Tc_cs2,

20

HEX_7, HEX_6, HEX_5, HEX_4, HEX_3, HEX_2, HEX_1, HEX_0);

-- contagem continua mas sem ser exibida


WHEN "00011" =>
soma_tempo(Tc_h1, Tc_h2, Tc_m1, Tc_m2,
Tc_s1, Tc_s2, Tc_cs1, Tc_cs2);

-- zerando a contagem
WHEN "00100" =>
zera_tempo(Tc_h1, Tc_h2, Tc_m1, Tc_m2,
Tc_s1, Tc_s2, Tc_cs1, Tc_cs2);
Exibe_HEX_all( Tc_h1, Tc_h2, Tc_m1, Tc_m2,
Tc_s1, Tc_s2, Tc_cs1, Tc_cs2,

HEX_7, HEX_6, HEX_5, HEX_4, HEX_3, HEX_2, HEX_1, HEX_0);

-- Tratamento de excecoes
WHEN OTHERS =>
Exibe_HEX_all( Tc_h1, Tc_h2, Tc_m1, Tc_m2,
Tc_s1, Tc_s2, Tc_cs1, Tc_cs2,

HEX_7, HEX_6, HEX_5, HEX_4, HEX_3, HEX_2, HEX_1, HEX_0);

END CASE;
WHEN OTHERS =>
estado_cron_temp <= cron;
END CASE;
ELSE
CASE estado_cron_temp IS
-- maquinas do temporizador
-- seleciona na primeira passagem
WHEN temp =>
CASE B IS
-- contagem interrompida
WHEN "00000" =>
Exibe_HEX_all( Tt_h1, Tt_h2, Tt_m1, Tt_m2,
Tt_s1, Tt_s2, Tt_cs1, Tt_cs2,

HEX_7, HEX_6, HEX_5, HEX_4, HEX_3, HEX_2, HEX_1, HEX_0);

Texto_LCD <= (
-- "
E

T
O

"

X"20",X"20",X"54",X"45",X"4D",X"50",X"4F",X"52",X"49",X"5A",X"41",X"44",X"4F",X"52",X"20",X"20",

X"20",X"20",X"20",X"20",X"20",X"20",X"20",X"20",X"20",X"20",X"20",X"20",X"20",X"20",X"20",X"20");

21

-- decrementar
WHEN "00001" =>
IF (Disparo_Temporizador = '0')THEN
Disparo_Temporizador := '1';
grava_tempo_inicial(Tt_h1,

Tt_h2,

Tt_m1, Tt_m2, Tt_s1, Tt_s2, Tt_cs1, Tt_cs2,

Tt_i_7, Tt_i_6, Tt_i_5, Tt_i_4, Tt_i_3, Tt_i_2, Tt_i_1, Tt_i_0);


END IF;
sub_tempo(Tt_h1, Tt_h2, Tt_m1, Tt_m2, Tt_s1,
Tt_s2, Tt_cs1, Tt_cs2);
Exibe_HEX_all( Tt_h1, Tt_h2, Tt_m1, Tt_m2,
Tt_s1, Tt_s2, Tt_cs1, Tt_cs2,

HEX_7, HEX_6, HEX_5, HEX_4, HEX_3, HEX_2, HEX_1, HEX_0);

-- incrementa segundos
WHEN "00010" =>
IF Pisca_Contador <= 10 THEN
Exibe_HEX_all( Tt_h1, Tt_h2, Tt_m1,
Tt_m2, 10, 10, Tt_cs1, Tt_cs2,

HEX_7, HEX_6, HEX_5, HEX_4, HEX_3, HEX_2, HEX_1, HEX_0);


ELSE
IF

(A(0)

NOT('1'))

AND

(A_Aux_Contador >= 20) ) THEN


verifica_9_sub(Tt_s2);
A_Aux_Contador := 0;
END IF;
IF

(A(1)

NOT('1'))

AND

(A_Aux_Contador >= 20) ) THEN


verifica_9_soma(Tt_s2);
A_Aux_Contador := 0;
END IF;
IF

(A(2)

NOT('1'))

AND

(A_Aux_Contador >= 20) ) THEN


verifica_5_sub(Tt_s1);
A_Aux_Contador := 0;
END IF;
IF

(A(3)

NOT('1'))

AND

(A_Aux_Contador >= 20) ) THEN


verifica_5_soma(Tt_s1);
A_Aux_Contador := 0;
END IF;
Exibe_HEX_all( Tt_h1, Tt_h2, Tt_m1,
Tt_m2, Tt_s1, Tt_s2, Tt_cs1, Tt_cs2,

HEX_7, HEX_6, HEX_5, HEX_4, HEX_3, HEX_2, HEX_1, HEX_0);

22

END IF;
Pisca_Contador := Pisca_Contador + 1;
A_Aux_Contador := A_Aux_Contador + 1;
Disparo_Temporizador := '0';
Texto_LCD <= (
-- "
E

T
O

"

X"20",X"20",X"54",X"45",X"4D",X"50",X"4F",X"52",X"49",X"5A",X"41",X"44",X"4F",X"52",X"20",X"20",
-U
E
S

S
G

T
U

"

E
N

S
D

"

X"20",X"41",X"4A",X"55",X"53",X"54",X"45",X"20",X"53",X"45",X"47",X"55",X"4e",X"44",X"4f",X"53");

-- incrementa minutos
WHEN "00100" =>
IF Pisca_Contador <= 10 THEN
Exibe_HEX_all( Tt_h1, Tt_h2, 10, 10,
Tt_s1, Tt_s2, Tt_cs1, Tt_cs2,

HEX_7, HEX_6, HEX_5, HEX_4, HEX_3, HEX_2, HEX_1, HEX_0);


ELSE
IF

(A(0)

NOT('1'))

AND

(A_Aux_Contador >= 20) ) THEN


verifica_9_sub(Tt_m2);
A_Aux_Contador := 0;
END IF;
IF

(A(1)

NOT('1'))

AND

(A_Aux_Contador >= 20) ) THEN


verifica_9_soma(Tt_m2);
A_Aux_Contador := 0;
END IF;
IF

(A(2)

NOT('1'))

AND

(A_Aux_Contador >= 20) ) THEN


verifica_5_sub(Tt_m1);
A_Aux_Contador := 0;
END IF;
IF

(A(3)

NOT('1'))

AND

(A_Aux_Contador >= 20) ) THEN


verifica_5_soma(Tt_m1);
A_Aux_Contador := 0;
END IF;
Exibe_HEX_all( Tt_h1, Tt_h2, Tt_m1,
Tt_m2, Tt_s1, Tt_s2, Tt_cs1, Tt_cs2,

HEX_7, HEX_6, HEX_5, HEX_4, HEX_3, HEX_2, HEX_1, HEX_0);


END IF;
Pisca_Contador := Pisca_Contador + 1;

23

A_Aux_Contador := A_Aux_Contador + 1;
Disparo_Temporizador := '0';
Texto_LCD <= (
-- "
E

T
O

"

X"20",X"20",X"54",X"45",X"4D",X"50",X"4F",X"52",X"49",X"5A",X"41",X"44",X"4F",X"52",X"20",X"20",
-J
M

U
I

S
U

T
T

"

E
O

"

X"20",X"41",X"4A",X"55",X"53",X"54",X"45",X"20",X"4d",X"49",X"4e",X"55",X"54",X"4f",X"53",X"20");

-- incrementa horas
WHEN "01000" =>
IF Pisca_Contador <= 10 THEN
Exibe_HEX_all(

10,

10,

Tt_m1,

Tt_m2, Tt_s1, Tt_s2, Tt_cs1, Tt_cs2,

HEX_7, HEX_6, HEX_5, HEX_4, HEX_3, HEX_2, HEX_1, HEX_0);


ELSE
IF

(A(0)

NOT('1'))

AND

(A_Aux_Contador >= 20) ) THEN


verifica_9_sub(Tt_h2);
A_Aux_Contador := 0;
END IF;
IF

(A(1)

NOT('1'))

AND

(A_Aux_Contador >= 20) ) THEN


verifica_9_soma(Tt_h2);
A_Aux_Contador := 0;
END IF;
IF

(A(2)

NOT('1'))

AND

(A_Aux_Contador >= 20) ) THEN


verifica_9_sub(Tt_h1);
A_Aux_Contador := 0;
END IF;
IF

(A(3)

NOT('1'))

AND

(A_Aux_Contador >= 20) ) THEN


verifica_9_soma(Tt_h1);
A_Aux_Contador := 0;
END IF;
Exibe_HEX_all( Tt_h1, Tt_h2, Tt_m1,
Tt_m2, Tt_s1, Tt_s2, Tt_cs1, Tt_cs2,

HEX_7, HEX_6, HEX_5, HEX_4, HEX_3, HEX_2, HEX_1, HEX_0);


END IF;
Pisca_Contador := Pisca_Contador + 1;
A_Aux_Contador := A_Aux_Contador + 1;
Disparo_Temporizador := '0';
Texto_LCD <= (

24

-- "
E

T
O

"

X"20",X"20",X"54",X"45",X"4D",X"50",X"4F",X"52",X"49",X"5A",X"41",X"44",X"4F",X"52",X"20",X"20",
-U

"

J
H

"

X"20",X"20",X"41",X"4A",X"55",X"53",X"54",X"45",X"20",X"48",X"4f",X"52",X"41",X"53",X"20",X"20");

-- reiniciar a contagem
WHEN "10000" =>
IF (Disparo_Temporizador = '1')THEN
Disparo_Temporizador := '0';
grava_tempo_inicial(Tt_i_7,

Tt_i_6,

Tt_i_5, Tt_i_4, Tt_i_3, Tt_i_2, Tt_i_1, Tt_i_0,

Tt_h1, Tt_h2, Tt_m1, Tt_m2, Tt_s1, Tt_s2, Tt_cs1, Tt_cs2); --retorna o tempo inicial
para o tempo atual
END IF;
Exibe_HEX_all( Tt_h1, Tt_h2, Tt_m1, Tt_m2,
Tt_s1, Tt_s2, Tt_cs1, Tt_cs2,

HEX_7, HEX_6, HEX_5, HEX_4, HEX_3, HEX_2, HEX_1, HEX_0);

-- zerar a contagem
WHEN "11110" =>
zera_tempo(Tt_h1,

Tt_h2,

Tt_m1,

Tt_m2,

Tt_s1, Tt_s2, Tt_cs1, Tt_cs2);


Exibe_HEX_all( Tt_h1, Tt_h2, Tt_m1, Tt_m2,
Tt_s1, Tt_s2, Tt_cs1, Tt_cs2,

HEX_7, HEX_6, HEX_5, HEX_4, HEX_3, HEX_2, HEX_1, HEX_0);

-- Tratamento de excecoes
WHEN OTHERS =>
Exibe_HEX_all( Tt_h1, Tt_h2, Tt_m1, Tt_m2,
Tt_s1, Tt_s2, Tt_cs1, Tt_cs2,

HEX_7, HEX_6, HEX_5, HEX_4, HEX_3, HEX_2, HEX_1, HEX_0);

END CASE;

WHEN OTHERS =>


estado_cron_temp <= temp;
END CASE;
END IF;

25

END IF;
END PROCESS maq_est;

-- Fracionadores de clock
-- 1 : 1000 , 50MHz -> 50KHz
contador_1: PROCESS (clock_maquina)
VARIABLE counter_1

: INTEGER RANGE 0 TO 1000;

BEGIN
IF (clock_maquina'EVENT and clock_maquina = '1') THEN
IF (counter_1 = 1000) THEN
counter_1 := 0;
clkout_1 <= '1';
ELSE
counter_1:= counter_1 + 1;
clkout_1 <= '0';
END IF;
END IF;
END PROCESS contador_1;

-- 1 : 1000 , 50KHz -> 100Hz


contador_2: PROCESS (clkout_1)
VARIABLE counter_2

: INTEGER RANGE 0 TO 500;

BEGIN
IF (clkout_1'EVENT and clkout_1 = '1') THEN
IF (counter_2 = 500) THEN
counter_2 := 0;
clkout_2 <= '1';
ELSE
counter_2:= counter_2 + 1;
clkout_2 <= '0';
END IF;
END IF;
END PROCESS contador_2;

-- 50Hz -> 10Hz = 10^-1s


contador_3: PROCESS (clkout_2)
VARIABLE counter_3

: INTEGER RANGE 0 TO 10;

BEGIN
IF (clkout_2'EVENT and clkout_2 = '1') THEN
IF (counter_3 = 10) THEN
counter_3 := 0;
clkout_3 <= '1';
ELSE
counter_3:= counter_3 + 1;
clkout_3 <= '0';
END IF;
END IF;
END PROCESS contador_3;

-- Visualizacao dos estados

26

q <=

B & cron_1_temp_0;

--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--%%%%%%%%%%%% Display LCD %%%%%%%%%%%%%
--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

---PROCEDURE executa_lcd(SIGNAL Texto_LCD : letras_string) IS


-- BEGIN
-- Maquina de estados do lcd
PROCESS (clock_maquina, on_off)
BEGIN
IF on_off = '1' AND (B /= "00000" AND q /= "010000" AND q /= "001000" AND q /= "000100") THEN
estado <= RESET1;
VALOR_BUS_DADOS <= X"38";
prox_comando <= RESET2;
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
-CLK2 <= X"00000";
CLK2_HABILITAR <= '0';
-ELSIF clock_maquina'EVENT AND clock_maquina = '1' THEN
-- Envia os dados para o display LCD
-IF CLK2 < X"0F424" THEN
CLK2 <= CLK2 + 1;
CLK2_HABILITAR <= '0';
ELSE
CLK2 <= X"00000";
CLK2_HABILITAR <= '1';
END IF;
-IF CLK2_HABILITAR = '1' THEN
CASE estado IS
--Define transferencia de funcao de 8 bits e 2 linhas com fonte 5x8
WHEN RESET1 =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
VALOR_BUS_DADOS <= X"38";
estado <= DROP_LCD_E;
prox_comando <= RESET2;
CONTA_LETRAS <= "00000";
WHEN RESET2 =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
VALOR_BUS_DADOS <= X"38";
estado <= DROP_LCD_E;

27

prox_comando <= RESET3;


WHEN RESET3 =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
VALOR_BUS_DADOS <= X"38";
estado <= DROP_LCD_E;
prox_comando <= FUNC_SET;
WHEN FUNC_SET =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
VALOR_BUS_DADOS <= X"38";
estado <= DROP_LCD_E;
prox_comando <= DESLIGA_DISPLAY;

-- Rotina para desliga o display


WHEN DESLIGA_DISPLAY =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
VALOR_BUS_DADOS <= X"08";
estado <= DROP_LCD_E;
prox_comando <= LIMPA_DISPLAY;

--Rotina para limpa display


WHEN LIMPA_DISPLAY =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
VALOR_BUS_DADOS <= X"01";
estado <= DROP_LCD_E;
prox_comando <= LIGA_DISPLAY;

-- Rotina para liga display


WHEN LIGA_DISPLAY =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
VALOR_BUS_DADOS <= X"0C";
estado <= DROP_LCD_E;
prox_comando <= MODE_SET;

-- Rotina para definir o modo de escrita


WHEN MODE_SET =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
VALOR_BUS_DADOS <= X"06";
estado <= DROP_LCD_E;
prox_comando <= Print_String;

28

-- Escreve o caracter hexadecimal na primeira posio do LCD


WHEN Print_String =>
estado <= DROP_LCD_E;
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW_INT <= '0';
IF Prox_Letra(7 DOWNTO 4) /= X"0" THEN
VALOR_BUS_DADOS <= Prox_Letra;
ELSE

-- Converte o valor 4 bit para ASC2 hexadecimal


IF (Prox_Letra(3 DOWNTO 0) > 9) THEN
VALOR_BUS_DADOS <= X"4" & (Prox_Letra(3
DOWNTO 0)-9);
ELSE
VALOR_BUS_DADOS <= X"3" & Prox_Letra(3
DOWNTO 0);
END IF;
END IF;
estado <= DROP_LCD_E;

-- Loop que envia 32 caracteres para o LCD


IF (CONTA_LETRAS < 31) AND (Prox_Letra /= X"FE") THEN
CONTA_LETRAS <= CONTA_LETRAS +1;
ELSE
CONTA_LETRAS <= "00000";
END IF;
IF CONTA_LETRAS = 15 THEN
prox_comando <= line2;
ELSIF (CONTA_LETRAS = 31) OR (Prox_Letra = X"FE") THEN
prox_comando <= return_home;
ELSE
prox_comando <= Print_String;
END IF;
-- Define a escrita para a linha 2
WHEN LINE2 =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
VALOR_BUS_DADOS <= X"C0";
estado <= DROP_LCD_E;
prox_comando <= Print_String;
-- Volta a escrita para a linha 1
WHEN RETURN_HOME =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
VALOR_BUS_DADOS <= X"80";
estado <= DROP_LCD_E;
prox_comando <= Print_String;

29

WHEN DROP_LCD_E =>


LCD_E <= '0';
estado <= SEGURA;
WHEN SEGURA =>
estado <= prox_comando;
END CASE;
END IF;
END IF;
END PROCESS;
--END executa_lcd;
--

END maquina_estados_geral;

========================================