|
|
Ligne 3 : |
Ligne 3 : |
| 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/TinyReveilLCDStart.zip TinyReveilLCDStart.zip] |
− | * fichier microcontroleur.vhd
| |
− | * fichier lcd16x2_ctrl_demo.vhd
| |
− | * un fichier d'exemple d'utilisation en C
| |
| | | |
− | ==Fichier microcontroleur.vhd== | + | =Devoir surveillé de Novembre 2019= |
− | <source lang=vhdl>
| + | Vous allez partir de la correction qui est donnée en ressource juste au dessus. |
− | ----------------------------------------------------------------------------------
| + | ==Réalisation du projet et premières questions== |
− | -- Company:
| + | Le fichier C qui est compilé avec la correction est le suivant : |
− | -- 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';
| |
− | | |
− | -- see the display's datasheet for the character map
| |
− | line1(127 downto 120) <= X"20";
| |
− | 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";
| |
− | line2(119 downto 112) <= X"20";
| |
− | line2(111 downto 104) <= X"20";
| |
− | line2(103 downto 96) <= X"20";
| |
− | 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;
| |
− | line2_buffer <= line2; -- when switch_lines = '1' else line2;
| |
− | | |
− | -- 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 575 : |
Ligne 14 : |
| #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 652 : |
Ligne 26 : |
| *hh_mm = 0x0000; | | *hh_mm = 0x0000; |
| } | | } |
− | | + | |
| void decrementHHMM(uint16_t *hh_mm) { | | void decrementHHMM(uint16_t *hh_mm) { |
| (*hh_mm)--; | | (*hh_mm)--; |
Ligne 664 : |
Ligne 38 : |
| *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) { |
| + | // echo simple |
| + | //PORTA = ch; |
| + | ch >>= 1; |
| + | if (ch == 0) ch = 128; |
| + | if (PINA & 0x01) { |
| + | incrementHHMM(&hh_mmSonnerie); |
| + | _delay_ms(10); |
| + | } |
| + | if (PINA & 0x02) { |
| + | decrementHHMM(&hh_mmSonnerie); |
| + | _delay_ms(10); |
| + | } |
| + | hh_mmCourante = ADCH; |
| + | hh_mmCourante <<= 8; |
| + | hh_mmCourante += ADCL; |
| + | if (PINA & 0x04) { |
| + | if (hh_mmSonnerie == hh_mmCourante) PORTA = 1; |
| + | } else PORTA=0; |
| + | PORTB = hh_mmSonnerie; |
| + | DDRB = hh_mmSonnerie >> 8; |
| + | // on défiler les valeurs |
| + | } |
| + | return 0; |
| + | } |
| + | </source> |
| + | |
| + | '''Répondre aux questions suivantes :''' |
| + | * Faire le projet et constater le fonctionnement |
| + | * si la ligne <source lang=c> uint16_t hh_mmSonnerie = 0x0645, hh_mmCourante=0; </source> est changée en <source lang=c> uint16_t hh_mmSonnerie = 0x0123, 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 ? |
| + | * quelle touche est responsable de la décrémentation de l'heure réveil ? |
| + | * quelle touche est utilisée pour l'armement du réveil ? |
| + | * comment fais-je pour arrêter le réveil de sonner ? |
| + | |
| + | ==Modification matérielle== |
| + | |
| + | Le défaut de la réalisation de la solution présentée est la comparaison en C entre l'heure de sonnerie et l'heure réveil : |
| + | <source lang=c> |
| + | if (PINA & 0x04) { |
| + | if (hh_mmSonnerie == hh_mmCourante) |
| + | PORTA = 1; |
| + | } else |
| + | PORTA=0; |
| </source> | | </source> |
| + | En effet la présence de _delay_ms pendant le réglage de l'heure réveil peut faire que l'on manque cette égalité : il suffit qu'elle arrive à un moment différent de l'exécution de cette instruction en C. |