User Tools

Site Tools


start:eti:carte:sources:vcl8254

Vcl8254.pas

UNIT Vcl8254;
{-----------------------------------------------------------------------------
  NOM DE L'UNITE : VCL8254.PAS
  BUT            : Composant VCL 8254 renfermant tout les contrôles du PIT
  AUTEUR         : S.Claus / M.Amarantidis
  DATE           : Février 1997
 
  MODIFIE LE     :
  RAISON         :
 
  REMARQUES      : - Pour la configuration du 8254, la structure du mot de
                     commande qu'il faut écrire à l'adresse de contrôle est la
                     suivante:
 
   0  0  1  1  0  1  1  0    Cnt 0 - Géné    36
   0  1  1  1  0  1  1  0    Cnt 1 - Géné    76
   1  0  1  1  0  1  1  0    Cnt 2 - Géné    B6
 
  D7 D6 D5 D4 D3 D2 D1 D0
   ¦  ¦  ¦  ¦  ¦  ¦  ¦  ¦
   ¦  ¦  ¦  ¦  +--+--+  +-- BCD -> 1 ou Binaire -> 0
   ¦  ¦  ¦  ¦        ¦
   ¦  ¦  ¦  ¦        +----- Mode : 0 = 000   1 = 001   2 = X10
   ¦  ¦  +--+                      3 = X11   4 = 100   5 = 101
   ¦  ¦     ¦
   ¦  ¦     +-------------- Read/Write : 00 Counter Latch Command
   ¦  ¦                                  01 R/W byte de poids faible uniquement
   ¦  ¦                                  10 R/W byte de poids fort uniquement
   ¦  ¦                                  11 R/W byte de poids faible en premier
   +--+                                     puis le byte de poids fort ensuite
      ¦
      +-------------------- Sélection du compteur : 00 = Compteur 0
                                                    01 = Compteur 1
                                                    10 = Compteur 2
                                                    11 = Read Back
 
 -----------------------------------------------------------------------------}
 
 
{=============================================================================}
INTERFACE   {============================================== I N T E R F A C E }
{=============================================================================}
 
 
USES
  WinTypes, WinProcs, Classes, SysUtils;
 
 
CONST
  versionvcl            = '1.00';                            { Version du VCL }
  adressebase           = $308;                     { Adresse de base du 8254 }
  frquartz              = 6000000.0;                    { Fréquence du quartz }
 
TYPE
  TModeCompteur = (mcIndefini, mcGenerateur);            { Etat des compteurs }
 
  TPIT8254 = CLASS(TComponent)
    PRIVATE { Private-déclarations ---------------------------------- PRIVATE }
 
      {-- Divers }
      FVersion         : STRING;
      FAdresseBase8254 : WORD;
      AdresseCtrl,
      AdresseCnt0,
      AdresseCnt1,
      AdresseCnt2      : WORD;
      FCanWrite        : BOOLEAN;
 
      {-- Paramètres généraux }
      FFrequenceQuartz : EXTENDED;
 
      {-- Configuration des compteurs }
      FModeCnt0,
      FModeCnt1,
      FModeCnt2        : TModeCompteur;
 
      {-- Valeur des différents compteurs }
      FCnt0,
      FCnt1,
      FCnt2            : WORD;
 
      {-- Divers }
      PROCEDURE AjusteAdresses;
      PROCEDURE SetAdresseBase(Adresse:WORD);
      PROCEDURE SetCanWrite(WriteEnabled:BOOLEAN);
 
      {-- Configuration des compteurs }
      PROCEDURE SetModeCnt0(Mode:TModeCompteur);
      PROCEDURE SetModeCnt1(Mode:TModeCompteur);
      PROCEDURE SetModeCnt2(Mode:TModeCompteur);
 
      {-- Valeur des différents compteurs }
      PROCEDURE SetCnt0(Valeur: WORD);
      PROCEDURE SetCnt1(Valeur: WORD);
      PROCEDURE SetCnt2(Valeur: WORD);
 
    PUBLIC { Public-déclarations ------------------------------------- PUBLIC }
      CONSTRUCTOR Create(AOwner:TComponent); OVERRIDE;
      DESTRUCTOR Destroy; OVERRIDE;
 
    PUBLISHED { Published declarations ---------------------------- PUBLISHED }
 
      {-- Divers }
      PROPERTY Enabled : BOOLEAN READ FCanWrite WRITE SetCanWrite;
      PROPERTY Adresse : WORD READ FAdresseBase8254 WRITE SetAdresseBase;
      PROPERTY Version : STRING READ FVersion;
      PROPERTY Quartz  : EXTENDED READ FFrequenceQuartz WRITE FFrequenceQuartz;
 
      {-- Configuration des compteurs }
      PROPERTY ModeCompteur0 : TModeCompteur READ FModeCnt0 WRITE SetModeCnt0
                 DEFAULT mcIndefini;
      PROPERTY ModeCompteur1 : TModeCompteur READ FModeCnt1 WRITE SetModeCnt1
                 DEFAULT mcIndefini;
      PROPERTY ModeCompteur2 : TModeCompteur READ FModeCnt2 WRITE SetModeCnt2
                 DEFAULT mcIndefini;
      PROPERTY Compteur0 : WORD READ FCnt0 WRITE SetCnt0 DEFAULT 0;
      PROPERTY Compteur1 : WORD READ FCnt1 WRITE SetCnt1 DEFAULT 0;
      PROPERTY Compteur2 : WORD READ FCnt2 WRITE SetCnt2 DEFAULT 0;
 
  END; {CLASS TPIT8254}
 
PROCEDURE Register;    { Enregistrement de l'objet dans l'inspecteur d'objets }
 
 
{=============================================================================}
IMPLEMENTATION   {================================= I M P L E M E N A T I O N }
{=============================================================================}
 
 
USES
  Forms, Dialogs;
 
 
CONST
  Poids : ARRAY[0..7] OF WORD = (1, 2, 4, 8, 16, 32, 64, 128);
 
 
TYPE
  bbit = 0..7;                                        { Pour l'accés aux bits }
 
 
{-----------------------------------------------------------------------------}
{ INITIALISATIONS ------------------------------------------- Initialisations }
{-----------------------------------------------------------------------------}
 
 
CONSTRUCTOR TPIT8254.Create;
{ BUT: Initialisation du composant }
BEGIN
  {-- Toujours appeler le constructeur reçu en héritage }
  INHERITED Create(AOwner);
  {-- Version}
  FVersion := versionvcl;
  {-- Interdiction d'écrire sur tous les ports }
  FCanWrite        := FALSE;
  {-- Fréquence du quartz }
  FFrequenceQuartz := frquartz;
  {-- Valeur par défaut des adresses }
  SetAdresseBase(adressebase);
  {-- Valeurs des différents compteurs }
  FCnt0 := 0;
  FCnt1 := 0;
  FCnt2 := 0;
  {-- Tous les compteurs sont dans un état indéfini }
  FModeCnt0 := mcIndefini;
  FModeCnt1 := mcIndefini;
  FModeCnt2 := mcIndefini;
END; {CONSTRUCTOR Create}
 
 
DESTRUCTOR TPIT8254.Destroy;
{ BUT: Tout remettre en ordre quand on a fini }
BEGIN
  { Toujours appeler le destructor hérité }
  INHERITED Destroy;
END; {DESTRUCTOR Destroy}
 
 
{-----------------------------------------------------------------------------}
{ ACCES BAS NIVEAU ----------------------------------------- Accés bas niveau }
{-----------------------------------------------------------------------------}
 
 
FUNCTION InPortB(LePort:WORD):BYTE;
{ BUT: Lecture de l'état d'un port }
VAR
  Valeur : BYTE;
BEGIN
  ASM
    PUSH DX
    MOV  DX, LePort
    IN   AL, DX
    MOV  Valeur, AL
    POP  DX
  END; {ASM}
  InPortB := Valeur;
END; {FUNCTION InPortB}
 
 
PROCEDURE OutPortB(LePort:WORD; Value:BYTE); ASSEMBLER;
{ BUT: Ecriture sur un port }
ASM
  PUSH  DX
  MOV   DX, LePort
  MOV   AL, Value
  OUT   DX, AL
  POP   DX
END; {PROCEDURE OutPortB}
 
 
PROCEDURE SetBitB(VAR B : Byte; bit : bbit);
{ BUT: Mise à 1 d'un bit }
BEGIN
  B := B OR Poids[bit]
END; {PROCEDURE SetBitB}
 
 
PROCEDURE ClearBitB(VAR B : Byte; bit : bbit);
{ BUT: Mise à 0 d'un bit}
BEGIN
  B := B AND NOT Poids[bit];
END; {PROCEDURE ClearBitB}
 
 
{-----------------------------------------------------------------------------}
{ UTILITAIRES --------------------------------------------------- Utilitaires }
{-----------------------------------------------------------------------------}
 
 
PROCEDURE Register;
{ BUT: Ajoute ce composant dans la palette des composants de Delphi}
BEGIN
  RegisterComponents('More...', [TPIT8254]);
END; {PROCEDURE Register}
 
 
{-----------------------------------------------------------------------------}
{ METHODES DU COMPOSANT ------------------------------- Méthodes du composant }
{-----------------------------------------------------------------------------}
 
 
PROCEDURE TPIT8254.SetCanWrite(WriteEnabled:BOOLEAN);
{ BUT: Autorise ou non l'écriture sur les ports }
BEGIN
  FCanWrite := WriteEnabled;
END; {PROCEDURE SetCanWrite}
 
 
PROCEDURE TPIT8254.AjusteAdresses;
{ BUT: Ajuste toutes les adresses du 8254 en fonction de l'adresse de base }
BEGIN
  AdresseCnt0 := FAdresseBase8254 + 0;
  AdresseCnt1 := FAdresseBase8254 + 1;
  AdresseCnt2 := FAdresseBase8254 + 2;
  AdresseCtrl := FAdresseBase8254 + 3;
END; {PROCEDURE AjusteAdresses}
 
 
PROCEDURE TPIT8254.SetAdresseBase(Adresse:WORD);
{ BUT: Configuration de l'adresse de base }
BEGIN
  FAdresseBase8254 := Adresse;
  AjusteAdresses;
END; {PROCEDURE SetAdresseBase}
 
 
{-----------------------------------------------------------------------------}
{ COMPTEUR 0 ----------------------------------------------------- Compteur 0 }
{-----------------------------------------------------------------------------}
 
 
PROCEDURE TPIT8254.SetCnt0(Valeur: WORD);
{ BUT: Change la valeur du compteur 0 }
BEGIN
  IF FCanWrite AND (FModeCnt0 <> mcIndefini) THEN BEGIN
    { On ne change la valeur que si le composant est activé et que le compteur
      a déjà été configuré }
    FCnt0 := Valeur;                                    { MAJ de la propriété }
    CASE FModeCnt0 OF
      mcGenerateur : BEGIN                                   { - GENERATEUR - }
                       IF FCnt0 < 2 THEN FCnt0 := 2;               { ! Limite }
                       OutPortB(AdresseCtrl, $36);            { Choix du mode }
                       OutPortB(AdresseCnt0, Lo(FCnt0));   { Facteur division }
                       OutPortB(AdresseCnt0, Hi(FCnt0));
                     END; {BRANCH OF CASE}
    END; {CASE OF}
  END; {IF}
END; {PROCEDURE SetCnt0}
 
 
PROCEDURE TPIT8254.SetModeCnt0(Mode:TModeCompteur);
{ BUT: Initialisation du mode de fonctionnement du compteur 0 }
VAR
  ValeurControle : BYTE;
BEGIN
  IF FCanWrite AND (Mode <> mcIndefini) THEN BEGIN
    { On ne change le mode de fonctionnement que si le composant est activé
      et qu'on choisi un mode de fonctionnement (logique, non?) }
    FModeCnt0 := Mode;                                  { MAJ de la propriété }
    CASE FModeCnt0 OF
      mcGenerateur : BEGIN                                   { - GENERATEUR - }
                       IF FCnt0 < 2 THEN FCnt0 := 2;               { ! Limite }
                       OutPortB(AdresseCtrl, $36);            { Choix du mode }
                       OutPortB(AdresseCnt0, Lo(FCnt0));   { Facteur division }
                       OutPortB(AdresseCnt0, Hi(FCnt0));
                     END; {BRANCH OF CASE}
    END; {CASE OF}
  END; {IF}
END; {PROCEDURE SetModeCnt0}
 
 
{-----------------------------------------------------------------------------}
{ COMPTEUR 1 ----------------------------------------------------- Compteur 1 }
{-----------------------------------------------------------------------------}
 
 
PROCEDURE TPIT8254.SetCnt1(Valeur: WORD);
{ BUT: Change la valeur du compteur 1 }
BEGIN
  IF FCanWrite AND (FModeCnt1 <> mcIndefini) THEN BEGIN
    { On ne change la valeur que si le composant est activé et que le compteur
      a déjà été configuré }
    FCnt1 := Valeur;                                    { MAJ de la propriété }
    CASE FModeCnt1 OF
      mcGenerateur : BEGIN
                       IF FCnt1 < 2 THEN FCnt1 := 2;               { ! Limite }
                       OutPortB(AdresseCtrl, $76);            { Choix du mode }
                       OutPortB(AdresseCnt0, Lo(FCnt1));   { Facteur division }
                       OutPortB(AdresseCnt0, Hi(FCnt1));
                     END; {BRANCH OF CASE}
    END; {CASE OF}
  END; {IF}
END; {PROCEDURE SetCnt1}
 
 
PROCEDURE TPIT8254.SetModeCnt1(Mode:TModeCompteur);
{ BUT: Initialisation du mode de fonctionnement du compteur 1 }
VAR
  ValeurControle : BYTE;
BEGIN
  IF FCanWrite AND (Mode <> mcIndefini) THEN BEGIN
    { On ne change le mode de fonctionnement que si le composant est activé
      et qu'on choisi un mode de fonctionnement (logique, non?) }
    FModeCnt1 := Mode;                                  { MAJ de la propriété }
    CASE FModeCnt1 OF
      mcGenerateur : BEGIN
                       IF FCnt1 < 2 THEN FCnt1 := 2;               { ! Limite }
                       OutPortB(AdresseCtrl, $76);            { Choix du mode }
                       OutPortB(AdresseCnt1, Lo(FCnt1));   { Facteur division }
                       OutPortB(AdresseCnt1, Hi(FCnt1));
                     END; {BRANCH OF CASE}
    END; {CASE OF}
  END; {IF}
END; {PROCEDURE SetModeCnt1}
 
 
{-----------------------------------------------------------------------------}
{ COMPTEUR 2 ----------------------------------------------------- Compteur 2 }
{-----------------------------------------------------------------------------}
 
 
PROCEDURE TPIT8254.SetCnt2(Valeur: WORD);
{ BUT: Change la valeur du compteur 2 }
BEGIN
  IF FCanWrite AND (FModeCnt2 <> mcIndefini) THEN BEGIN
    { On ne change la valeur que si le composant est activé et que le compteur
      a déjà été configuré }
    FCnt2 := Valeur;                                    { MAJ de la propriété }
    CASE FModeCnt2 OF
      mcGenerateur : BEGIN
                       IF FCnt2 < 2 THEN FCnt2 := 2;               { ! Limite }
                       OutPortB(AdresseCtrl, $B6);            { Choix du mode }
                       OutPortB(AdresseCnt0, Lo(FCnt2));   { Facteur division }
                       OutPortB(AdresseCnt0, Hi(FCnt2));
                     END; {BRANCH OF CASE}
    END; {CASE OF}
  END; {IF}
END; {PROCEDURE SetCnt2}
 
 
PROCEDURE TPIT8254.SetModeCnt2(Mode:TModeCompteur);
{ BUT: Initialisation du mode de fonctionnement du compteur 2 }
VAR
  ValeurControle : BYTE;
BEGIN
  IF FCanWrite AND (Mode <> mcIndefini) THEN BEGIN
    { On ne change le mode de fonctionnement que si le composant est activé
      et qu'on choisi un mode de fonctionnement (logique, non?) }
    FModeCnt2 := Mode;                                  { MAJ de la propriété }
    CASE FModeCnt2 OF
      mcGenerateur : BEGIN
                       IF FCnt2 < 2 THEN FCnt2 := 2;               { ! Limite }
                       OutPortB(AdresseCtrl, $B6);            { Choix du mode }
                       OutPortB(AdresseCnt2, Lo(FCnt2));   { Facteur division }
                       OutPortB(AdresseCnt2, Hi(FCnt2));
                     END; {BRANCH OF CASE}
    END; {CASE OF}
  END; {IF}
END; {PROCEDURE SetModeCnt2}
 
 
{-----------------------------------------------------------------------------}
{ THAT'S ALL -------------------------------------------------------- The end }
{-----------------------------------------------------------------------------}
 
 
INITIALIZATION
END. {UNIT Vcl8254}
This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies
start/eti/carte/sources/vcl8254.txt · Last modified: 2016/07/24 01:25 by admin