|
|
| (19 révisions intermédiaires par le même utilisateur non affichées) |
| Ligne 1 : |
Ligne 1 : |
| | + | |
| | | | |
| | Ceci est le corrigé du TP [https://fr.wikiversity.org/wiki/Very_High_Speed_Integrated_Circuit_Hardware_Description_Language/Travail_pratique/TPs_ATTiny861_avec_Altera#TP6c_:_R.C3.A9alisation_du_r.C3.A9glage_de_l.27heure_de_r.C3.A9veil_par_le_processeur Réalisation du réglage de l'heure réveil par le processeur]. | | Ceci est le corrigé du TP [https://fr.wikiversity.org/wiki/Very_High_Speed_Integrated_Circuit_Hardware_Description_Language/Travail_pratique/TPs_ATTiny861_avec_Altera#TP6c_:_R.C3.A9alisation_du_r.C3.A9glage_de_l.27heure_de_r.C3.A9veil_par_le_processeur Réalisation du réglage de l'heure réveil par le processeur]. |
| | | | |
| − | Puisqu'il s'agit d'un processeur, nous donnons trois fichiers de correction :
| + | Voici une ressource complète de la correction du TP6c : [http://moutou.pagesperso-orange.fr/TinyReveilLCDTP6C.zip TinyReveilLCDTP6C.zip] |
| − | * fichier microcontroleur.vhd
| |
| − | * fichier lcd16x2_ctrl_demo.vhd
| |
| − | * un fichier d'exemple d'utilisation en C
| |
| − | | |
| − | ==Fichier microcontroleur.vhd==
| |
| − | <source lang=vhdl>
| |
| − | ----------------------------------------------------------------------------------
| |
| − | -- Company:
| |
| − | -- Engineer:
| |
| − | --
| |
| − | -- Create Date: 08:57:48 08/26/2014
| |
| − | -- Design Name:
| |
| − | -- Module Name: microcontroleur - microcontroleur_architecture
| |
| − | -- Project Name:
| |
| − | -- Target Devices:
| |
| − | -- Tool versions:
| |
| − | -- Description:
| |
| − | --
| |
| − | -- Dependencies:
| |
| − | --
| |
| − | -- Revision:
| |
| − | -- Revision 0.01 - File Created
| |
| − | -- Additional Comments:
| |
| − | --
| |
| − | ----------------------------------------------------------------------------------
| |
| − | library IEEE;
| |
| − | use IEEE.STD_LOGIC_1164.ALL;
| |
| − | use IEEE.STD_LOGIC_ARITH.ALL;
| |
| − | use IEEE.STD_LOGIC_UNSIGNED.ALL;
| |
| − | | |
| − | ---- Uncomment the following library declaration if instantiating
| |
| − | ---- any Xilinx primitives in this code.
| |
| − | --library UNISIM;
| |
| − | --use UNISIM.VComponents.all;
| |
| − | | |
| − | entity microcontroleur is
| |
| − | Port ( clk : in STD_LOGIC;
| |
| − | Rst : in STD_LOGIC;
| |
| − | sw : in STD_LOGIC_VECTOR (7 downto 0);
| |
| − | In_PINB : in STD_LOGIC_VECTOR (7 downto 0);
| |
| − | Led : out STD_LOGIC_VECTOR (7 downto 0);
| |
| − | lcd_e : out std_logic;
| |
| − | lcd_rs : out std_logic;
| |
| − | lcd_rw : out std_logic;
| |
| − | lcd_db : out std_logic_vector(7 downto 4)
| |
| − | );
| |
| − | end entity microcontroleur;
| |
| − | | |
| − | architecture microcontroleur_architecture of microcontroleur is
| |
| − | --Registres et PORTs de l'ATTiny861
| |
| − | constant OCR1A : std_logic_vector(5 downto 0) := "101101";
| |
| − | constant OCR1B : std_logic_vector(5 downto 0) := "101100";
| |
| − | constant PORTA : std_logic_vector(5 downto 0) := "011011";
| |
| − | constant DDRA : std_logic_vector(5 downto 0) := "011010";
| |
| − | constant PINA : std_logic_vector(5 downto 0) := "011001";
| |
| − | constant PORTB : std_logic_vector(5 downto 0) := "011000";
| |
| − | constant DDRB : std_logic_vector(5 downto 0) := "010111";
| |
| − | constant PINB : std_logic_vector(5 downto 0) := "010110";
| |
| − | constant ADCH : std_logic_vector(5 downto 0) := "000101";
| |
| − | constant ADCL : std_logic_vector(5 downto 0) := "000100";
| |
| − | --Registres non présents dans l'ATTiny861
| |
| − | constant UDR : std_logic_vector(5 downto 0) := "000011";
| |
| − | constant UCSRA : std_logic_vector(5 downto 0) := "000010";
| |
| − | constant UCSRB : std_logic_vector(5 downto 0) := "000001";
| |
| − | component mcu_core is
| |
| − | Port (
| |
| − | Clk : in std_logic;
| |
| − | Rst : in std_logic; -- Reset core when Rst='1'
| |
| − | En : in std_logic; -- CPU stops when En='0', could be used to slow down cpu to save power
| |
| − | -- PM
| |
| − | PM_A : out std_logic_vector(15 downto 0);
| |
| − | PM_Drd : in std_logic_vector(15 downto 0);
| |
| − | -- DM
| |
| − | DM_A : out std_logic_vector(15 downto 0); -- 0x00 - xxxx
| |
| − | DM_Areal : out std_logic_vector(15 downto 0); -- 0x60 - xxxx (same as above + io-adr offset)
| |
| − | DM_Drd : in std_logic_vector(7 downto 0);
| |
| − | DM_Dwr : out std_logic_vector(7 downto 0);
| |
| − | DM_rd : out std_logic;
| |
| − | DM_wr : out std_logic;
| |
| − | -- IO
| |
| − | IO_A : out std_logic_vector(5 downto 0); -- 0x00 - 0x3F
| |
| − | IO_Drd : in std_logic_vector(7 downto 0);
| |
| − | IO_Dwr : out std_logic_vector(7 downto 0);
| |
| − | IO_rd : out std_logic;
| |
| − | IO_wr : out std_logic;
| |
| − | -- OTHER
| |
| − | OT_FeatErr : out std_logic; -- Feature error! (Unhandled part of instruction)
| |
| − | OT_InstrErr : out std_logic -- Instruction error! (Unknown instruction)
| |
| − | );
| |
| − | end component mcu_core;
| |
| − | --PM
| |
| − | component pm is
| |
| − | Port (
| |
| − | Clk : in std_logic;
| |
| − | rst : in std_logic; -- Reset when Rst='1'
| |
| − | -- PM
| |
| − | PM_A : in std_logic_vector(15 downto 0);
| |
| − | PM_Drd : out std_logic_vector(15 downto 0)
| |
| − | );
| |
| − | end component pm;
| |
| − | | |
| − | component dm is
| |
| − | Port ( clk : in STD_LOGIC;
| |
| − | addr : in STD_LOGIC_VECTOR (15 downto 0);
| |
| − | dataread : out STD_LOGIC_VECTOR (7 downto 0);
| |
| − | datawrite : in STD_LOGIC_VECTOR (7 downto 0);
| |
| − | rd : in STD_LOGIC;
| |
| − | wr : in STD_LOGIC);
| |
| − | end component dm;
| |
| − |
| |
| − | component lcd16x2_ctrl_demo is
| |
| − | port (
| |
| − | clk : in std_logic;
| |
| − | Armkey : in std_logic;
| |
| − | HHMMAlarm : in std_logic_vector(15 downto 0);
| |
| − | HHMMCourante : out std_logic_vector(15 downto 0);
| |
| − | lcd_e : out std_logic;
| |
| − | lcd_rs : out std_logic;
| |
| − | lcd_rw : out std_logic;
| |
| − | lcd_db : out std_logic_vector(7 downto 4);
| |
| − | led_out : out std_logic);
| |
| − | end component lcd16x2_ctrl_demo;
| |
| − | | |
| − | signal PM_A : std_logic_vector(15 downto 0);
| |
| − | signal PM_Drd : std_logic_vector(15 downto 0);
| |
| − | -- DM
| |
| − | signal DM_A : std_logic_vector(15 downto 0); -- 0x00 - xxxx
| |
| − | signal DM_Areal : std_logic_vector(15 downto 0); -- 0x60 - xxxx (same as above + io-adr offset)
| |
| − | signal DM_Drd : std_logic_vector(7 downto 0);
| |
| − | signal DM_Dwr : std_logic_vector(7 downto 0);
| |
| − | signal DM_rd : std_logic;
| |
| − | signal DM_wr : std_logic;
| |
| − | -- IO
| |
| − | signal IO_A : std_logic_vector(5 downto 0); -- 0x00 - 0x3F
| |
| − | signal IO_Drd : std_logic_vector(7 downto 0);
| |
| − | signal IO_Dwr : std_logic_vector(7 downto 0);
| |
| − | signal IO_rd : std_logic;
| |
| − | signal IO_wr : std_logic;
| |
| − | | |
| − | signal IO_DrdA : std_logic_vector(7 downto 0);
| |
| − | signal IO_DrdB : std_logic_vector(7 downto 0);
| |
| − | | |
| − | signal s_HHMMAlarm, s_HHMMCourante : std_logic_vector(15 downto 0);
| |
| − |
| |
| − | begin
| |
| − | | |
| − | core : mcu_core Port map (
| |
| − | Clk => clk,
| |
| − | Rst => Rst,
| |
| − | En => '1',
| |
| − | -- PM
| |
| − | PM_A => PM_A,
| |
| − | PM_Drd => PM_Drd,
| |
| − | -- DM
| |
| − | DM_A => DM_A,
| |
| − | DM_Areal => DM_Areal,
| |
| − | DM_Drd => DM_Drd,
| |
| − | DM_Dwr => DM_Dwr,
| |
| − | DM_rd => DM_rd,
| |
| − | DM_wr => DM_wr,
| |
| − | -- IO
| |
| − | IO_A => IO_A,
| |
| − | IO_Drd => IO_Drd,
| |
| − | IO_Dwr => IO_Dwr,
| |
| − | IO_rd => IO_rd,
| |
| − | IO_wr => IO_wr,
| |
| − | -- OTHER
| |
| − | OT_FeatErr => open,
| |
| − | OT_InstrErr => open
| |
| − | );
| |
| − | | |
| − | prgmem : pm port map (
| |
| − | Clk => clk,
| |
| − | Rst => '0',
| |
| − | -- PM
| |
| − | PM_A => PM_A,
| |
| − | PM_Drd => PM_Drd
| |
| − | );
| |
| − |
| |
| − | datamem : dm port map (
| |
| − | clk => clk,
| |
| − | addr => DM_A,
| |
| − | dataread => DM_Drd,
| |
| − | datawrite => DM_Dwr,
| |
| − | rd => DM_rd,
| |
| − | wr => DM_wr
| |
| − | );
| |
| − |
| |
| − | lcdmanager: lcd16x2_ctrl_demo port map (
| |
| − | clk => clk,
| |
| − | Armkey => '0',
| |
| − | HHMMAlarm => s_HHMMAlarm,
| |
| − | HHMMCourante => s_HHMMCourante,
| |
| − | lcd_e => lcd_e,
| |
| − | lcd_rs => lcd_rs,
| |
| − | lcd_rw => lcd_rw,
| |
| − | lcd_db => lcd_db,
| |
| − | led_out => open);
| |
| − |
| |
| − | -- IO write process
| |
| − | --
| |
| − | iowr: process(CLK)
| |
| − | begin
| |
| − | if (rising_edge(CLK)) then
| |
| − | if (IO_wr = '1') then
| |
| − | case IO_A is
| |
| − | -- addresses for tiny861 device (use io.h).
| |
| − | --
| |
| − | when PORTA => -- PORTA=X"1B" (0X3B)
| |
| − | Led <= IO_Dwr;
| |
| − | when PORTB => -- PORTB=X"18" (0X38)
| |
| − | s_HHMMAlarm(7 downto 0) <= IO_Dwr;
| |
| − | when DDRB => -- PORTB=X"17" (0X37)
| |
| − | s_HHMMAlarm(15 downto 8) <= IO_Dwr;
| |
| − | -- when ADCL => -- PORTB=X"18" (0X38)
| |
| − | -- s_HHMMAlarm(23 downto 16) <= IO_Dwr;
| |
| − | -- when ADCH => -- PORTB=X"17" (0X37)
| |
| − | -- s_HHMMAlarm(31 downto 24) <= IO_Dwr;
| |
| − | when others =>
| |
| − | end case;
| |
| − | end if;
| |
| − | end if;
| |
| − | end process;
| |
| − |
| |
| − | -- IO read process
| |
| − | --
| |
| − | iord: process(IO_rd,IO_A,In_PINB,sw)
| |
| − | begin
| |
| − | -- addresses for tinyX6 device (use iom8.h).
| |
| − | --
| |
| − | if IO_rd = '1' then
| |
| − | case IO_A is
| |
| − | when PINA => IO_Drd <= sw; -- PINA=X"19" (0X39)
| |
| − | when PINB => IO_Drd <= In_PINB; -- PINB=X"16" (0X36)
| |
| − | when PORTB => IO_Drd <= s_HHMMCourante(7 downto 0); -- PORTB=X"18" (0X38)
| |
| − | when DDRB => IO_Drd <= s_HHMMCourante(15 downto 8); -- PINB=X"17" (0X37)
| |
| − | when others => IO_Drd <= X"AA";
| |
| − | end case;
| |
| − | end if;
| |
| − | end process;
| |
| − | | |
| − | end microcontroleur_architecture;
| |
| − | </source>
| |
| − | ==Fichier "lcd16x2_ctrl_demo.vhd"==
| |
| − | <source lang=vhdl>
| |
| − | -------------------------------------------------------------------------------
| |
| − | -- Title : Synthesizable demo for design "lcd16x2_ctrl"
| |
| − | -- Project :
| |
| − | -------------------------------------------------------------------------------
| |
| − | -- File : lcd16x2_ctrl_tb.vhd
| |
| − | -- Author : <stachelsau@T420>
| |
| − | -- Company :
| |
| − | -- Created : 2012-07-28
| |
| − | -- Last update: 2012-07-29
| |
| − | -- Platform :
| |
| − | -- Standard : VHDL'93/02
| |
| − | -------------------------------------------------------------------------------
| |
| − | -- Description: This demo writes writes a "hello world" to the display and
| |
| − | -- interchanges both lines periodically.
| |
| − | -------------------------------------------------------------------------------
| |
| − | -- Copyright (c) 2012
| |
| − | -------------------------------------------------------------------------------
| |
| − | -- Revisions :
| |
| − | -- Date Version Author Description
| |
| − | -- 2012-07-28 1.0 stachelsau Created
| |
| − | -------------------------------------------------------------------------------
| |
| − | | |
| − | library ieee;
| |
| − | use ieee.std_logic_1164.all;
| |
| − | | |
| − | -------------------------------------------------------------------------------
| |
| − | | |
| − | entity lcd16x2_ctrl_demo is
| |
| − | port (
| |
| − | clk : in std_logic;
| |
| − | Armkey : in std_logic;
| |
| − | HHMMAlarm : in std_logic_vector(15 downto 0);
| |
| − | HHMMCourante : out std_logic_vector(15 downto 0);
| |
| − | lcd_e : out std_logic;
| |
| − | lcd_rs : out std_logic;
| |
| − | lcd_rw : out std_logic;
| |
| − | lcd_db : out std_logic_vector(7 downto 4);
| |
| − | led_out : out std_logic);
| |
| − | | |
| − | end entity lcd16x2_ctrl_demo;
| |
| − | | |
| − | -------------------------------------------------------------------------------
| |
| − | | |
| − | architecture behavior of lcd16x2_ctrl_demo is
| |
| − | component CounterBCD is
| |
| − | port( EN: in std_logic;
| |
| − | Clock: in std_logic;
| |
| − | Reset: in std_logic;
| |
| − | ENO : out std_logic;
| |
| − | Output: out std_logic_vector(3 downto 0));
| |
| − | end component CounterBCD;
| |
| − |
| |
| − | component CounterModulo6 is
| |
| − | port( EN: in std_logic;
| |
| − | Clock: in std_logic;
| |
| − | Reset: in std_logic;
| |
| − | ENO : out std_logic;
| |
| − | Output: out std_logic_vector(3 downto 0));
| |
| − | end component CounterModulo6;
| |
| − |
| |
| − | component SequSonnerie IS
| |
| − | PORT(
| |
| − | clock,Key,Trip,ena :IN std_logic;
| |
| − | Ring :OUT std_logic
| |
| − | );
| |
| − | END component SequSonnerie;
| |
| − | --
| |
| − | signal timer : natural range 0 to 5000000 := 0;
| |
| − | signal eno10Hz, s_eno, s_eno2, s_eno3 : std_logic := '0';
| |
| − | signal line1 : std_logic_vector(127 downto 0);
| |
| − | signal line2 : std_logic_vector(127 downto 0);
| |
| − | signal s_data16 : std_logic_vector(15 downto 0);
| |
| − | signal s_eno2_heure : std_logic_vector(16 downto 8);
| |
| − | signal s_reset : std_logic;
| |
| − | signal egalite : std_logic;
| |
| − |
| |
| − | -- component generics
| |
| − | constant CLK_PERIOD_NS : positive := 20; -- 50 Mhz
| |
| − | | |
| − | -- component ports
| |
| − | signal rst : std_logic;
| |
| − | signal line1_buffer : std_logic_vector(127 downto 0);
| |
| − | signal line2_buffer : std_logic_vector(127 downto 0);
| |
| − | | |
| − | begin -- architecture behavior
| |
| − | | |
| − | -- component instantiation
| |
| − | DUT : entity work.lcd16x2_ctrl
| |
| − | generic map (
| |
| − | CLK_PERIOD_NS => CLK_PERIOD_NS)
| |
| − | port map (
| |
| − | clk => clk,
| |
| − | rst => rst,
| |
| − | lcd_e => lcd_e,
| |
| − | lcd_rs => lcd_rs,
| |
| − | lcd_rw => lcd_rw,
| |
| − | lcd_db => lcd_db,
| |
| − | line1_buffer => line1_buffer,
| |
| − | line2_buffer => line2_buffer);
| |
| | | | |
| − | rst <= '0';
| + | =Devoir surveillé de Decembre 2019= |
| | + | Vous allez partir de la correction du TP6c qui est donnée : [http://moutou.pagesperso-orange.fr/TinyReveilLCDTP6C.zip TinyReveilLCDTP6C.zip]. |
| | | | |
| − | -- see the display's datasheet for the character map
| + | '''<u>Indications</u>''' : |
| − | line1(127 downto 120) <= X"20";
| + | * Pour la mise à jour du contenu de la mémoire seulement, sans passer par un temps de recompilation complet de l’application (donc plus ou moins équivalent à data2mem), il faut valider l'option "'''use smart compilation'''". Pour y accéder : menu assignements => settings => compilation process settings => puis cocher l'option. Ne pas oublier de faire "apply" avant de quitter la fenêtre ! |
| − | line1(119 downto 112) <= X"20";
| |
| − | line1(111 downto 104) <= X"20";
| |
| − | line1(103 downto 96) <= X"20";
| |
| − | line1(95 downto 88) <= X"20";
| |
| − | line1(87 downto 84) <= X"3";
| |
| − | line1(83 downto 80) <= s_data16(15 downto 12);
| |
| − | line1(79 downto 76) <= X"3";
| |
| − | line1(75 downto 72) <= s_data16(11 downto 8);
| |
| − | line1(71 downto 64) <= X"3A";
| |
| − | line1(63 downto 60) <= X"3";
| |
| − | line1(59 downto 56) <= s_data16(7 downto 4);
| |
| − | line1(55 downto 52) <= X"3";
| |
| − | line1(51 downto 48) <= s_data16(3 downto 0);
| |
| − | line1(47 downto 40) <= X"20";
| |
| − | line1(39 downto 32) <= X"20";
| |
| − | line1(31 downto 24) <= X"20";
| |
| − | line1(23 downto 16) <= X"20";
| |
| − | line1(15 downto 8) <= X"20";
| |
| − | line1(7 downto 0) <= X"20";
| |
| | | | |
| − | line2(127 downto 120) <= X"20";
| + | Cette version est un peu améliorée pour l'occasion : vous avez la possibilité de suivre l'évolution de la machine d'états de la sonnerie du réveil à l'aide de trois leds vertes : |
| − | line2(119 downto 112) <= X"20";
| + | * complètement à droite allumée quand on est dans l'état Off |
| − | line2(111 downto 104) <= X"20";
| + | * deuxième led en partant de la droite allumée quand on est dans l'état Armed |
| − | line2(103 downto 96) <= X"20";
| + | * troisième led en partant de la droite allumée quand on est dans l'état Ringing |
| − | line2(95 downto 88) <= X"20";
| |
| − | line2(87 downto 84) <= X"3";
| |
| − | line2(83 downto 80) <= HHMMAlarm(15 downto 12);
| |
| − | line2(79 downto 76) <= X"3";
| |
| − | line2(75 downto 72) <= HHMMAlarm(11 downto 8);
| |
| − | line2(71 downto 64) <= X"3A";
| |
| − | line2(63 downto 60) <= X"3";
| |
| − | line2(59 downto 56) <= HHMMAlarm(7 downto 4);
| |
| − | line2(55 downto 52) <= X"3";
| |
| − | line2(51 downto 48) <= HHMMAlarm(3 downto 0);
| |
| − | line2(47 downto 40) <= X"20";
| |
| − | line2(39 downto 32) <= X"20";
| |
| − | line2(31 downto 24) <= X"20";
| |
| − | line2(23 downto 16) <= X"20";
| |
| − | line2(15 downto 8) <= X"20";
| |
| − | line2(7 downto 0) <= X"20";
| |
| | | | |
| − | line1_buffer <= line1; -- when switch_lines = '1' else line1;
| + | ==Réalisation du projet et premières questions== |
| − | line2_buffer <= line2; -- when switch_lines = '1' else line2;
| + | Le fichier C qui est compilé avec la correction est le suivant : |
| − | | |
| − | -- timer 10 Hz
| |
| − | process(clk)
| |
| − | begin
| |
| − | if rising_edge(clk) then
| |
| − | if timer = 0 then
| |
| − | timer <= 5000000;
| |
| − | else
| |
| − | timer <= timer - 1;
| |
| − | end if;
| |
| − | end if;
| |
| − |
| |
| − | end process;
| |
| − | eno10Hz <= '1' when timer = 0 else
| |
| − | '0';
| |
| − |
| |
| − |
| |
| − | MNUnit: CounterBCD port map(
| |
| − | EN => eno10Hz,
| |
| − | Clock => clk,
| |
| − | Reset => '0',
| |
| − | ENO => s_eno,
| |
| − | Output => s_data16(3 downto 0));
| |
| − | MNDiz: CounterModulo6 port map(
| |
| − | EN => s_eno,
| |
| − | Clock => clk,
| |
| − | Reset => '0',
| |
| − | ENO => s_eno2,
| |
| − | Output => s_data16(7 downto 4));
| |
| − | HHUnit: CounterBCD port map(
| |
| − | EN => s_eno2,
| |
| − | Clock => clk,
| |
| − | Reset => s_reset,
| |
| − | ENO => s_eno3,
| |
| − | Output => s_data16(11 downto 8));
| |
| − | HHDiz: CounterBCD port map(
| |
| − | EN => s_eno3,
| |
| − | Clock => clk,
| |
| − | Reset => s_reset,
| |
| − | ENO => open,
| |
| − | Output => s_data16(15 downto 12));
| |
| − | -- reset quand 23 est detecte par rebouclage
| |
| − | s_eno2_heure <= s_eno2 & s_data16(15 downto 8);
| |
| − | with s_eno2_heure select
| |
| − | s_reset <= '1' when "100100011",
| |
| − | '0' when others;
| |
| − | egalite <= '1' when HHMMAlarm = s_data16 else
| |
| − | '0';
| |
| − | SequenceurPourSonnerie: SequSonnerie PORT MAP(
| |
| − | clock => clk,
| |
| − | Key=> ArmKey,
| |
| − | Trip => egalite,
| |
| − | ena => eno10Hz,
| |
| − | Ring => led_out
| |
| − | );
| |
| − | HHMMCourante <= s_data16;
| |
| − | end architecture behavior;
| |
| − | | |
| − | library IEEE;
| |
| − | use IEEE.STD_LOGIC_1164.ALL;
| |
| − | use IEEE.STD_LOGIC_ARITH.ALL;
| |
| − | use IEEE.STD_LOGIC_UNSIGNED.ALL;
| |
| − | entity CounterBCD is
| |
| − | port( EN: in std_logic;
| |
| − | Clock: in std_logic;
| |
| − | Reset: in std_logic;
| |
| − | ENO : out std_logic;
| |
| − | Output: out std_logic_vector(3 downto 0));
| |
| − | end CounterBCD;
| |
| − |
| |
| − | architecture Behavioral of CounterBCD is
| |
| − | signal cmpt: std_logic_vector(3 downto 0);
| |
| − | signal s_en_cmpt: std_logic_vector(4 downto 0);
| |
| − | begin process(Clock,Reset)
| |
| − | begin
| |
| − | if(rising_edge(Clock)) then
| |
| − | if Reset='1' then
| |
| − | cmpt <= "0000";
| |
| − | elsif EN='1' then
| |
| − | if cmpt="1001" then
| |
| − | cmpt<="0000";
| |
| − | else
| |
| − | cmpt <= cmpt + 1;
| |
| − | end if;
| |
| − | end if;
| |
| − | end if;
| |
| − | end process;
| |
| − | Output <= cmpt;
| |
| − | s_en_cmpt <= en & cmpt;
| |
| − | with s_en_cmpt select
| |
| − | ENO <= '1' when "11001",
| |
| − | '0' when others;
| |
| − | end Behavioral;
| |
| − | | |
| − | library IEEE;
| |
| − | use IEEE.STD_LOGIC_1164.ALL;
| |
| − | use IEEE.STD_LOGIC_ARITH.ALL;
| |
| − | use IEEE.STD_LOGIC_UNSIGNED.ALL;
| |
| − | -- pour les dizaines de minutes
| |
| − | entity CounterModulo6 is
| |
| − | port( EN: in std_logic;
| |
| − | Clock: in std_logic;
| |
| − | Reset: in std_logic;
| |
| − | ENO : out std_logic;
| |
| − | Output: out std_logic_vector(3 downto 0));
| |
| − | end CounterModulo6;
| |
| − |
| |
| − | architecture Behavioral of CounterModulo6 is
| |
| − | signal cmpt: std_logic_vector(3 downto 0);
| |
| − | signal s_en_cmpt: std_logic_vector(4 downto 0);
| |
| − | begin process(Clock,Reset)
| |
| − | begin
| |
| − | if(rising_edge(Clock)) then
| |
| − | if Reset='1' then
| |
| − | cmpt <= "0000";
| |
| − | elsif EN='1' then
| |
| − | if cmpt="0101" then
| |
| − | cmpt<="0000";
| |
| − | else
| |
| − | cmpt <= cmpt + 1;
| |
| − | end if;
| |
| − | end if;
| |
| − | end if;
| |
| − | end process;
| |
| − | Output <= cmpt;
| |
| − | s_en_cmpt <= en & cmpt;
| |
| − | with s_en_cmpt select
| |
| − | ENO <= '1' when "10101",
| |
| − | '0' when others;
| |
| − | end Behavioral;
| |
| − | | |
| − | library IEEE;
| |
| − | use IEEE.STD_LOGIC_1164.ALL;
| |
| − | ENTITY SequSonnerie IS
| |
| − | PORT(
| |
| − | clock,Key,Trip,ena :IN std_logic;
| |
| − | Ring :OUT std_logic
| |
| − | );
| |
| − | END SequSonnerie;
| |
| − | ARCHITECTURE arch_SequSonnerie OF SequSonnerie IS
| |
| − | TYPE typetat IS (Armed, Off, Ringing);
| |
| − | SIGNAL etatp, etatf : typetat;
| |
| − | BEGIN
| |
| − | -- partie séquentielle
| |
| − | PROCESS (clock) BEGIN -- 1er process
| |
| − | IF Clock ='1' AND Clock'EVENT THEN
| |
| − | IF ena = '1' then
| |
| − | etatp <= etatf;
| |
| − | END IF;
| |
| − | END IF;
| |
| − | END PROCESS;
| |
| − | PROCESS(etatp) BEGIN --2eme process
| |
| − | CASE etatp IS
| |
| − | WHEN Off => IF key ='1' THEN etatf <= Armed;
| |
| − | ELSE etatf <= Off;
| |
| − | END IF;
| |
| − | WHEN Armed => IF Key = '0' THEN
| |
| − | etatf <= Off;
| |
| − | ELSIF Trip ='1' THEN
| |
| − | etatf <= Ringing;
| |
| − | ELSE etatf <= Armed;
| |
| − | END IF;
| |
| − | WHEN Ringing => IF Key ='0' THEN
| |
| − | etatf <= Off;
| |
| − | ELSE etatf <= Ringing;
| |
| − | END IF;
| |
| − | END CASE;
| |
| − | END PROCESS;
| |
| − | -- partie combinatoire
| |
| − | Ring <= '1' WHEN etatp=Ringing ELSE
| |
| − | '0';
| |
| − | END arch_SequSonnerie;
| |
| − | </source>
| |
| − | ==Fichier d'exemple en C==
| |
| | <source lang=c> | | <source lang=c> |
| | #include "avr/io.h" | | #include "avr/io.h" |
| Ligne 574 : |
Ligne 23 : |
| | #define F_CPU 16000000UL | | #define F_CPU 16000000UL |
| | #include "util/delay.h" | | #include "util/delay.h" |
| − |
| |
| − | //#include <stdio.h>
| |
| − | //#include <string.h>
| |
| − |
| |
| − | /*#define UCSRB _SFR_IO8(0x01)
| |
| − | #define UCSRA _SFR_IO8(0x02)
| |
| − | #define UDR _SFR_IO8(0x03)
| |
| − | // UCSRA
| |
| − | #define RXC 7
| |
| − | #define TXC 6
| |
| − | #define UDRE 5
| |
| − | //UCSRB
| |
| − | #define RXEN 4
| |
| − | #define TXEN 3
| |
| − | */
| |
| − | void incrementBCD(uint16_t *cnt);
| |
| − | void decrementBCD(uint16_t *cnt);
| |
| − | void incrementHHMM(uint16_t *hh_mm);
| |
| − | void decrementHHMM(uint16_t *hh_mm);
| |
| − |
| |
| − | int main (void) {
| |
| − | uint8_t ch=128, switchs;
| |
| − | uint16_t heure_courante, heure_reveil = 0;
| |
| − | while(1) {
| |
| − | // echo simple
| |
| − | // PORTA = ch;
| |
| − | ch >>= 1;
| |
| − | if (ch == 0) ch = 128;
| |
| − | switchs = PINA;
| |
| − | if ((switchs & 0x03) == 3)
| |
| − | decrementHHMM(&heure_reveil);
| |
| − | if ((switchs & 0x03) == 2)
| |
| − | incrementHHMM(&heure_reveil);
| |
| − |
| |
| − | PORTB = heure_reveil & 0x00FF;
| |
| − | DDRB = (heure_reveil & 0xFF00)>>8;
| |
| − | heure_courante = DDRB;
| |
| − | heure_courante <<= 8;
| |
| − | heure_courante += PORTB;
| |
| − | if ((switchs & 0x04) == 0x04) {
| |
| − | // a remplacer par == mais pour nos tests rapides ...
| |
| − | if (heure_courante > heure_reveil)
| |
| − | PORTA = 0xFF;
| |
| − | } else
| |
| − | PORTA = 0;
| |
| − | _delay_ms(300); // on défiler les valeurs
| |
| − | }
| |
| − | return 0;
| |
| − | }
| |
| − |
| |
| − | void incrementBCD(uint16_t *cnt) {
| |
| − | (*cnt)++;
| |
| − | if ((*cnt & 0x000F) > 0x0009) *cnt += 6;
| |
| − | if ((*cnt & 0x00F0) > 0x0090) *cnt += 0x0060;
| |
| − | if ((*cnt & 0x00F0) > 0x0900) *cnt += 0x0600;
| |
| − | if ((*cnt & 0x00F0) > 0x9000) *cnt += 0x6000;
| |
| − | }
| |
| − |
| |
| − | void decrementBCD(uint16_t *cnt) {
| |
| − | (*cnt)--;
| |
| − | if ((*cnt & 0x000F) == 0x000F) *cnt -= 6;
| |
| − | if ((*cnt & 0x00F0) == 0x00F0) *cnt -= 0x0060;
| |
| − | if ((*cnt & 0x0F00) == 0x0F00) *cnt -= 0x0600;
| |
| − | if ((*cnt & 0xF000) == 0xF000) *cnt -= 0x6000;
| |
| − | }
| |
| | | | |
| | void incrementHHMM(uint16_t *hh_mm) { | | void incrementHHMM(uint16_t *hh_mm) { |
| Ligne 651 : |
Ligne 35 : |
| | *hh_mm = 0x0000; | | *hh_mm = 0x0000; |
| | } | | } |
| − | | + | |
| | void decrementHHMM(uint16_t *hh_mm) { | | void decrementHHMM(uint16_t *hh_mm) { |
| | (*hh_mm)--; | | (*hh_mm)--; |
| Ligne 663 : |
Ligne 47 : |
| | *hh_mm = 0x2359; | | *hh_mm = 0x2359; |
| | } | | } |
| | + | |
| | + | int main (void) { |
| | + | unsigned char ch=128; |
| | + | uint16_t hh_mmSonnerie = 0x0123, hh_mmCourante=0; |
| | + | PORTA=0; |
| | + | while(1) { |
| | + | // chenillard (non actif) |
| | + | //PORTA = ch; |
| | + | ch >>= 1; |
| | + | if (ch == 0) ch = 128; |
| | + | // gestion incrementation heure réveil |
| | + | if (PINA & 0x01) { |
| | + | incrementHHMM(&hh_mmSonnerie); |
| | + | _delay_ms(10); |
| | + | } |
| | + | // mise à jour heure courante |
| | + | hh_mmCourante = ADCH; |
| | + | hh_mmCourante <<= 8; |
| | + | hh_mmCourante += ADCL; |
| | + | |
| | + | // sortie Heure sonnerie sur afficheur |
| | + | PORTB = hh_mmSonnerie; |
| | + | DDRB = hh_mmSonnerie >> 8; |
| | + | |
| | + | } |
| | + | return 0; |
| | + | } |
| | </source> | | </source> |
| | + | |
| | + | '''Répondre aux questions suivantes :''' |
| | + | * Faire le projet et constater le fonctionnement |
| | + | * si la ligne <source lang=c> uint16_t hh_mmSonnerie = 0x0123, hh_mmCourante=0; </source> est changée en <source lang=c> uint16_t hh_mmSonnerie = 0x0645, hh_mmCourante=0; </source>, pouvez vous donner l'heure de réveil (de sonnerie) qui apparaîtra sur l'écran LCD ? |
| | + | * quelle touche est responsable de l'incrémentation de l'heure réveil si PINA lit les 8 switchs de poids forts ? |
| | + | * pouvez-vous ajouter la décrémentation de l'heure réveil en utilisant une autre touche et faire constater à l'enseignant |
| | + | |
| | + | ==Modification matérielle== |
| | + | [[Fichier:LAB_VHDL_Tiny861_12.png]] |
| | + | |
| | + | On désire utiliser le mécanisme de sonnerie qui est présent dans le code source de la correction. Il s'agit d'un composant appelé "SequSonnerie" qui est présent dans le fichier "lcd16x2_ctrl_demo.vhd". Ce mécanisme est complètement indépendant du processeur et l'on désire maintenant donner la possibilité au processeur d'interagir avec lui : |
| | + | * Le processeur procédera à l'armement en écrivant dans le registre ADCL conformément au schéma |
| | + | * La sonnerie sera lue à l'aide du registre PORTA conformément au schéma |
| | + | |
| | + | L'ensemble des modifications est en rouge sur le schéma. |
| | + | |
| | + | Faire constater à l'enseignant la compilation correcte de votre partie matérielle. |
| | + | |
| | + | ==Modification logicielle== |
| | + | A partir des modifications matérielles réalisées dans la section précédente, on vous demande : |
| | + | * de modifier votre programme pour que l'utilisation de sw2 arme ou pas le réveil (faire constater avec les leds vertes) |
| | + | * de modifier le programme pour que lorsque la sonnerie est activée par votre automate, vous allumez une led rouge à l'aide du PORTA et que cette led rouge qui représente la sonnerie s'éteigne quant vous désarmez le réveil. |
| | + | * de modifier le programme pour avoir un réglage séparé des heures et des minutes. |