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

De troyesGEII
Aller à : navigation, rechercher
m
m
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.

Version du 22 novembre 2019 à 16:04

Il s’agit d’une page protégée.

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 : TinyReveilLCDStart.zip

Devoir surveillé de Novembre 2019

Vous allez partir de la correction qui est donnée en ressource juste au dessus.

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) { 
   // 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; 
 }

Répondre aux questions suivantes :

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

 
if (PINA & 0x04) {
  if (hh_mmSonnerie == hh_mmCourante) 
    PORTA = 1;
} else 
  PORTA=0;

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.