Cours:TP printempsM4209 TP 6c Corr : Différence entre versions

De troyesGEII
Aller à : navigation, rechercher
m
m (Devoir surveillé de Decembre 2019)
 
(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.

Version actuelle datée du 12 décembre 2019 à 09:56


Ceci est le corrigé du TP Réalisation du réglage de l'heure réveil par le processeur.

Voici une ressource complète de la correction du TP6c : TinyReveilLCDTP6C.zip

Devoir surveillé de Decembre 2019

Vous allez partir de la correction du TP6c qui est donnée : TinyReveilLCDTP6C.zip.

Indications :

  • 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 !

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 :

  • complètement à droite allumée quand on est dans l'état Off
  • deuxième led en partant de la droite allumée quand on est dans l'état Armed
  • troisième led en partant de la droite allumée quand on est dans l'état Ringing

Réalisation du projet et premières questions

Le fichier C qui est compilé avec la correction est le suivant :

#include "avr/io.h" 
#undef F_CPU 
#define F_CPU 16000000UL 
#include "util/delay.h" 

void incrementHHMM(uint16_t *hh_mm) {
  (*hh_mm)++;
      if ((*hh_mm & 0x000F) > 0x0009)
      *hh_mm += 0x0006;
      if ((*hh_mm & 0x00F0) > 0x0050)
      *hh_mm += 0x00A0;
      if ((*hh_mm & 0x0F00) > 0x0900)
      *hh_mm += 0x0600;
      if ((*hh_mm & 0xFF00) > 0x2300)
      *hh_mm = 0x0000;
}
 
void decrementHHMM(uint16_t *hh_mm) {
  (*hh_mm)--;
      if ((*hh_mm & 0x000F) == 0x000F)
      *hh_mm -= 0x0006;
      if ((*hh_mm & 0x00F0) == 0x00F0)
      *hh_mm -= 0x00A0;
      if ((*hh_mm & 0x0F00) == 0x0F00)
      *hh_mm -= 0x0600;
      if ((*hh_mm & 0xFFFF) > 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; 
 }

Répondre aux questions suivantes :

  • Faire le projet et constater le fonctionnement
  • si la ligne
     uint16_t hh_mmSonnerie = 0x0123, hh_mmCourante=0;
    
    est changée en
     uint16_t hh_mmSonnerie = 0x0645, hh_mmCourante=0;
    
    , 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

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.