Cours:TP printempsM4209 TP 6c Corr : Différence entre versions
m |
m |
||
Ligne 1 : | Ligne 1 : | ||
+ | <accesscontrol>Acces:Prof</accesscontrol> | ||
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]. |
Version du 20 mars 2018 à 13:47
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.
Puisqu'il s'agit d'un processeur, nous donnons trois fichiers de correction :
- fichier microcontroleur.vhd
- fichier lcd16x2_ctrl_demo.vhd
- un fichier d'exemple d'utilisation en C
Fichier microcontroleur.vhd
----------------------------------------------------------------------------------
-- 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;
Fichier "lcd16x2_ctrl_demo.vhd"
-------------------------------------------------------------------------------
-- 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;
Fichier d'exemple en C
#include "avr/io.h"
#undef F_CPU
#define F_CPU 16000000UL
#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) {
(*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;
}