You are on page 1of 10

Relatrio Trabalho Sistemas Digitais Teclado

Nomes: Augusto Corra e Vinicius Campanharo Professora: Dra. Eliete Maria de Oliveira Caldeira

Introduo
O trabalho consiste na implementao de um teclado PS2. A ideia apertar uma tecla e faz-la aparecer no monitor. Como existem teclas estendidas (ctrl, shift ou setas do teclado, por exemplo), o protocolo PS2 informa de formas diferentes qual tecla foi pressionada. No trabalho tivemos que entender o funcionamento do protocolo, utilizar um cdigo j pronto dele e implementar a parte que recebe e reconhece a tecla pressionada para que aparea no vdeo. Fizemos as teclas h e a aparecer, assim como reconhecer que a seta <- foi pressionada. Para aparecer na tela, utilizamos o cdigo do vdeo desenvolvido no Laboratrio 5. O protocolo envia sempre 11 bits, a saber: 1 start bit, 1 stop bit, 1 parity bit e 8 bits de dados que informam o cdigo hexadecimal da tecla pressionada. Quando uma tecla solta, F0 enviado. No caso das teclas estendidas, antes do F0 enviado tambm o cdigo E0. E, aps o F0, enviado novamente o cdigo da tecla que foi pressionada inicialmente.

Desenvolvimento
O cdigo pronto, retirado do livro, foi o arquivo ps2_rx.vhd. O que ele faz filtrar a tecla pressionada, ou seja, em 8 ciclos de relgio ele verifica se ps2c (key clock), que vem do teclado, igual 1. Ele faz essa verificao para que no haja lixo na transmisso do cdigo da tecla pressionada. Aps isso, ele pega o valor de ps2d (key data) que referente tecla que foi pressionada. A tecla a, por exemplo, manda o cdigo 1C ao ser pressionada. Caso a tecla seja segurada por muito tempo, o teclado ficar mandando o cdigo 1C sempre. O ps2d enviar bit a bit o cdigo 1C (00011100 2). Ao final, quando a tecla for solta, ser enviado o cdigo F0, no caso da tecla a, ou, no caso da tecla <- ser enviado o seu respectivo cdigo, finalizando com E0 F0, conforme j explicado anteriormente. Ao final do envio dos cdigos da tecla pressionada, enviado um sinal de rx_done_tick. Quando igual 1, significa que o cdigo foi todo enviado atravs da sada dout. Aps o envio de dout, tivemos ento que receber esse cdigo e interpret-lo para que haja a exibio na tela. A idia simples: quando rx_done_tick igual 1, dout nos dar um valor que ser referente tecla pressionada e tambm quando a tecla for solta. Criamos ento um case que verifica o valor de dout. Caso seja "00011100", ento a tecla pressionada foi a. Enquanto a tecla no solta, ou seja, enquanto dout no vier com outro valor, ento a_press ser igual 1. Criamos esse signal para que ele nos informe quando a tecla est sendo pressionada para imprimirmos na tela. Quando a tecla solta, ento o valor de dout ser F0, ou seja, "11110000". Logo, a flag solta ser igual 1. Logo adiante j verificamos quando a tecla solta, ou seja, se ela for igual 1, ento devemos verificar qual tecla foi solta (para o caso de pressionarmos mais de uma tecla ao mesmo tempo). Se for a tecla a, ento a_press ser 0. Fazemos todo esse procedimento para a tecla h tambm.

No caso de teclas estendidas, verificamos quando dout ser igual E0, ou seja "11100000". Quando isso acontecer, criamos uma flag chamada estendida que ser setada como 1. Ento, verificamos qual a tecla. Neste trabalho, apenas verificamos a tecla <-, cujo cdigo hexadecimal 6B, ou seja, "01101011". Criamos ento o signal seta_press. Logo aps, verificamos quando a tecla estendida ser solta. Se solta for igual 1, ento verificamos qual foi solta e a apagamos (no nosso caso, seta_press<=0).

E se quisermos deixar a tecla permanentemente escrita na tela?


Seria simplesmente, no apagarmos a tecla. Ou seja, a_press, h_press e seta_press no iriam voltar ao valor igual 0. Ficariam em 1 sempre. Faramos toda a verificao de tecla pressionada, tecla solta, tecla sendo segurada por muito tempo, mas aps ela ser solta, a flag que diz que ela deve ser impressa na tela, continuaria como 1. Ou seja, continuaria a aparecendo na tela.

O desenho na tela
Para desenharmos a tecla pressionada, utilizamos o cdigo do video do laboratrio 5, que varre toda a tela, pixel a pixel, somando hc e vc. Criamos duas constantes, x e y, que iro determinar o comeo de onde sero pintadas as teclas pressionadas. O que fazemos verificar quando que vc = y, para comear a pintura. Para cada valor de vc, fazemos a verificao de hc. Quando ele for igual determinados valores, iremos pintar a tela. Esses valores que diro o formato do desenho na tela. Por exemplo, para pintar a letra H: quando vc est em uma determinada posio y, verificamos onde est hc. Se estiver na posio x-5 ou x+5 ento esses pixels sero pintados. Faremos exatamente a mesma coisa, mas agora para a posio y + 1 e assim por diante. Quando chegarmos ao meio da letra H, pintaremos tudo entre hc maior ou igual x-5 e hc menor ou igual x+5. Depois continuamos at o fim da letra. Um exemplo simplificado passo-a-passo est abaixo (comea em vc=y e segue): vc = y vc = y+1 vc = y+2 vc = y+3 vc = y+4 vc = y+5 vc = y+6

. .

. .

. . .

. . .

. . . . . . .......

. . . . . . ....... . .

. . . . . . ....... . . . .

. . . . . . ....... . . . . . .

Fazemos da mesma forma a letra A. A tecla correspondente <- fizemos simplificado e no escrevemos exatamente o desenho de uma seta para esquerda. Fizemos algo apenas para comprovar que foi apertado uma tecla estendida.

Cdigo
Segue o cdigo do nosso projeto: library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity video is Port ( clk : in STD_LOGIC; rst : in STD_LOGIC; hs : out STD_LOGIC; vs : out STD_LOGIC; ps2_d,ps2_c: in STD_LOGIC; r : out STD_LOGIC_VECTOR (2 downto 0); g : out STD_LOGIC_VECTOR (2 downto 0); b : out STD_LOGIC_VECTOR (1 downto 0)); end video;

architecture Behavioral of video is signal hc: integer range 0 to 800; signal vc: integer range 0 to 521; signal util,flag: std_logic; signal x: integer := 400; signal y: integer := 250; signal rx_en,rx_done_tick: std_logic; signal solta, extendida: std_logic; signal dout: std_logic_vector(7 downto 0); signal a_press, h_press, seta_press, pintaA, pintaH, pintaSETA: std_logic;

begin rx_en <= '1'; rteclado: entity work.ps2_rx port map( clk, rst, ps2_d, ps2_c, rx_en, rx_done_tick, dout); process(clk, rst) begin if rst = '1' then a_press <= '0'; h_press <= '0'; solta <= '0'; elsif rising_edge(clk) then if (rx_done_tick = '1') then case dout is when "00011100" => if (solta = '0') then a_press <= '1'; end if; when "00110011" => if (solta = '0') then h_press <= '1'; end if; when "11110000" => solta <= '1'; when "11100000" => extendida <= '1'; when others => null; end case; if solta = '1' then case dout is when "00011100" => a_press <= '0'; solta <='0'; when "00110011" => h_press <= '0'; solta <='0'; when others => null; end case; end if; if extendida = '1' then case dout is when "01101011" => seta_press <= '1'; when others => null; end case; if solta = '1' then case dout is

when "01101011" => seta_press <= '0'; solta <='0'; extendida <= '0'; when others => null; end case; end if; end if; end if; end if; end process; process(clk, rst) variable clk25mhz: std_logic; begin if rst = '1' then clk25mhz := '0'; hc <= 0; vc <= 0; elsif rising_edge(clk) then if clk25mhz = '1' then hc <= hc + 1; if hc = 800 then hc <= 0; vc <= vc + 1; if vc = 521 then vc <= 0; end if; end if; clk25mhz := '0'; else clk25mhz := '1'; end if; end if; end process; hs <= '0' when hc < 128 else '1'; vs <= '0' when vc < 2 else '1'; util <= '1' when hc >= 144 and hc < 784 and vc >=31 and vc < 511 else '0'; process (pintaA, a_press, pintaH, h_press) begin if (h_press = '1') then if (vc = y and (hc = x-5 or hc = x+5)) or (vc = y+1 and (hc = x-5 or hc = x+5)) or (vc = y+2 and (hc = x-5 or hc = x+5)) or (vc = y+3 and (hc = x-5 or hc = x+5)) or

(vc = y+4 and (hc = x-5 or hc = x+5)) or (vc = y+5 and (hc >= x-5 and (hc < x+5 or hc = x+5))) or (vc = y+6 and (hc = x-5 or hc = x+5)) or (vc = y+7 and (hc = x-5 or hc = x+5)) or (vc = y+8 and (hc = x-5 or hc = x+5)) or (vc = y+9 and (hc = x-5 or hc = x+5)) or (vc = y+10 and (hc = x-5 or hc = x+5)) then pintaH <= '1'; else pintaH <= '0'; end if; end if; if (a_press = '1') then if (vc = y and hc = x+15) or (vc = y+1 and (hc = x-1+15 or hc = x+1+15)) or (vc = y+2 and (hc = x-2+15 or hc = x+2+15)) or (vc = y+3 and (hc = x-3+15 or hc = x+3+15)) or (vc = y+4 and (hc = x-4+15 or hc = x+4+15)) or (vc = y+5 and (hc >= x-5+15 and (hc < x+5+15 or hc = x+5+15))) or (vc = y+6 and (hc = x-6+15 or hc = x+6+15)) or (vc = y+7 and (hc = x-7+15 or hc = x+7+15)) or (vc = y+8 and (hc = x-8+15 or hc = x+8+15)) or (vc = y+9 and (hc = x-9+15 or hc = x+9+15)) or (vc = y+10 and (hc = x-10+15 or hc = x+10+15)) then pintaA <= '1'; else pintaA <= '0'; end if; end if; if (seta_press = '1') then if (vc = y+11 and (hc = x-10 or hc = x+10)) or (vc = y+12 and (hc = x-9 or hc = x+11)) or (vc = y+13 and (hc = x-8 or hc = x+12)) or (vc = y+14 and (hc = x-7 or hc = x+13)) or (vc = y+15 and (hc = x-6 or hc = x+14)) or (vc = y+16 and (hc = x-5 or hc = x+15)) then pintaSETA <= '1'; else pintaSETA <= '0'; end if; end if; end process;

process(util, pintaA) begin if util = '1' then if pintaA = '1' then r <= "000"; g <= "000"; b <= "00"; elsif pintaH = '1' then r <= "000"; g <= "000"; b <= "00"; elsif pintaSETA = '1' then r <= "000"; g <= "000"; b <= "00"; else r <= "111"; g <= "111"; b <= "11"; end if; else r <= "000"; g <= "000"; b <= "00"; end if; end process; end Behavioral;

Concluso
A maior dificuldade no trabalho foi entender o funcionamento do protocolo, pois acreditvamos que, ao apertar a tecla, simplesmente o cdigo da tecla j iria diretamente. Demoramos um pouco para entender o funcionamento do rx_done_tick. Aps isso, ficou fcil desenvolver o trabalho, pois j tnhamos em mente tudo que queramos fazer.

You might also like