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}
start/eti/carte/sources/vcl8254.txt · Last modified: 2016/07/24 01:25 by admin