Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur l'Assembleur !

Modérateur : mazertoc

Mise en oeuvre d'un TDSX315/6
JJE
Passioné
Passioné
Messages : 399
Âge : 83
Enregistré en : novembre 2017
Localisation : Picardie

#1 Message par JJE » sam. 23 mars 2019 18:32

Bonjour à tous,
Petit complément à mon post auquel j'ai apporté quelques modifications ce matin (ajout du schéma et photo de la réalisation mise en oeuvre)
Dans ce post, je parle et j'utilisé un fichier .inc gérant un afficheur 7 segments TDS. En voici le code qui mérite peut-être quelques petites explication données après :

Code : Tout sélectionner

; Module TDS

    ifndef  _TDS
        
#DEFINE _TDS
        
    include     
"../../callx/callx.inc"
    
    
#DEFINE TDS_ANODECOMMUNE 0
    #DEFINE TDS_CATHODECOMMUNE 1
    
    
#DEFINE TDS_CODESEGMENTS    1
    #DEFINE TDS_CODECHIFFRES    2
    
    
TDS_Init    macro    TDS_Type
, Port, sa,sb,sc,sd,se,sf,sg,sdp
; Renseigner le programme 
;   du type d'afficheur utilisé
;   du port utilisé
;   des pins où sont comnnectées les pins du TDS pour chaque segment
    if  TDS_Type == TDS_ANODECOMMUNE
        #DEFINE ANODECOMMUNE
    else
        if TDS_Type == TDS_CATHODECOMMUNE
            #DEFINE CATHODECOMMUNE
        else
            messg   " "
            error   "Premier paramètre incorrect dans TDS_Init
            messg   " "
        endif
    endif               
        
    #DEFINE     TDS_Port    Port
    
;******************************************************************
; Constantes utiles à l'
utilisation d'un afficheur 7 TDS_segments
;******************************************************************

; brochage
    #DEFINE        TDS_segmenta    sa  ;0x01    ; 0x1
    #DEFINE        TDS_segmentb    sb  ;0x02    ; 0x2
    #DEFINE        TDS_segmentc    sc  ;0x04    ; 0x4
    #DEFINE        TDS_segmentd    sd  ;0x08    ; 0x80
    #DEFINE        TDS_segmente    se  ;0x10    ; 0x40
    #DEFINE        TDS_segmentf    sf  ;0x20    ; 0x20
    #DEFINE        TDS_segmentg    sg  ;0x40    ; 0x10
    #DEFINE        TDS_segmentDP    sdp ;0x80    ; 0x8

;******************************************************************
; commandes des 7 TDS_segments
    ifdef    ANODECOMMUNE
TDS_Segmenta    EQU    TDS_segmenta^0xff
TDS_Segmentb    EQU    TDS_segmentb^0xff
TDS_Segmentc    EQU    TDS_segmentc^0xff
TDS_Segmentd    EQU    TDS_segmentd^0xff
TDS_Segmente    EQU    TDS_segmente^0xff
TDS_Segmentf    EQU    TDS_segmentf^0xff
TDS_Segmentg    EQU    TDS_segmentg^0xff
TDS_SegmentDP    EQU    TDS_segmentDP^0xff
; pour améliorer la mise en page du listing
TDS_Segmentsab    EQU    TDS_Segmenta & TDS_Segmentb
TDS_Segmentsac    EQU    TDS_Segmenta & TDS_Segmentc
TDS_Segmentsbc    EQU    TDS_Segmentb & TDS_Segmentc
TDS_Segmentsef    EQU    TDS_Segmente & TDS_Segmentf
TDS_Segmentsabc    EQU    TDS_Segmenta & TDS_Segmentb & TDS_Segmentc
TDS_Segmentsefg    EQU    TDS_Segmente & TDS_Segmentf & TDS_Segmentg
    else
TDS_Segmenta    EQU    TDS_segmenta
TDS_Segmentb    EQU    TDS_segmentb
TDS_Segmentc    EQU    TDS_segmentc
TDS_Segmentd    EQU    TDS_segmentd
TDS_Segmente    EQU    TDS_segmente
TDS_Segmentf    EQU    TDS_segmentf
TDS_Segmentg    EQU    TDS_segmentg
TDS_SegmentDP    EQU    TDS_segmentDP
; pour améliorer la mise en page du listing
TDS_Segmentsab    EQU    TDS_Segmenta + TDS_Segmentb
TDS_Segmentsac    EQU    TDS_Segmenta + TDS_Segmentc
TDS_Segmentsbc    EQU    TDS_Segmentb + TDS_Segmentc
TDS_Segmentsef    EQU    TDS_Segmente + TDS_Segmentf
TDS_Segmentsabc    EQU    TDS_Segmenta + TDS_Segmentb + TDS_Segmentc
TDS_Segmentsefg    EQU    TDS_Segmente + TDS_Segmentf + TDS_Segmentg
    endif
    ifdef    ANODECOMMUNE
TDS_chiffre0    EQU    TDS_Segmentsab & TDS_Segmentc & TDS_Segmentd & TDS_Segmentsef
TDS_chiffre1    EQU    TDS_Segmentb & TDS_Segmentc
TDS_chiffre2    EQU    TDS_Segmentsab & TDS_Segmentd & TDS_Segmente & TDS_Segmentg
TDS_chiffre3    EQU    TDS_Segmentsab & TDS_Segmentc & TDS_Segmentd & TDS_Segmentg
TDS_chiffre4    EQU    TDS_Segmentb & TDS_Segmentc & TDS_Segmentf & TDS_Segmentg
TDS_chiffre5    EQU    TDS_Segmentsac & TDS_Segmentd & TDS_Segmentf & TDS_Segmentg
TDS_chiffre6    EQU    TDS_Segmenta & TDS_Segmentc & TDS_Segmentd & TDS_Segmentsefg
TDS_chiffre7    EQU    TDS_Segmenta & TDS_Segmentb & TDS_Segmentc
TDS_chiffre8    EQU    TDS_Segmentsabc & TDS_Segmentd & TDS_Segmentsefg
TDS_chiffre9    EQU    TDS_Segmentsab & TDS_Segmentc & TDS_Segmentf & TDS_Segmentg
TDS_chiffreA    EQU    TDS_Segmentsab & TDS_Segmentc & TDS_Segmentsefg
TDS_chiffreB    EQU    TDS_Segmentc & TDS_Segmentd & TDS_Segmentsefg
TDS_chiffreC    EQU    TDS_Segmenta & TDS_Segmentd & TDS_Segmente & TDS_Segmentf
TDS_chiffreD    EQU    TDS_Segmentsbc & TDS_Segmentd & TDS_Segmente & TDS_Segmentg
TDS_chiffreE    EQU    TDS_Segmenta & TDS_Segmentd & TDS_Segmentsef & TDS_Segmentg
TDS_chiffreF    EQU    TDS_Segmenta & TDS_Segmentsefg
TDS_chiffreVide    EQU 0xff
    else
TDS_chiffre0    EQU    TDS_Segmentsab + TDS_Segmentc + TDS_Segmentd + TDS_Segmentsef
TDS_chiffre1    EQU    TDS_Segmentb + TDS_Segmentc
TDS_chiffre2    EQU    TDS_Segmentsab + TDS_Segmentd + TDS_Segmente + TDS_Segmentg
TDS_chiffre3    EQU    TDS_Segmentsab + TDS_Segmentc + TDS_Segmentd + TDS_Segmentg
TDS_chiffre4    EQU    TDS_Segmentb + TDS_Segmentc + TDS_Segmentf + TDS_Segmentg
TDS_chiffre5    EQU    TDS_Segmentsac + TDS_Segmentd + TDS_Segmentf + TDS_Segmentg
TDS_chiffre6    EQU    TDS_Segmenta + TDS_Segmentc + TDS_Segmentd + TDS_Segmentsefg
TDS_chiffre7    EQU    TDS_Segmenta + TDS_Segmentb + TDS_Segmentc
TDS_chiffre8    EQU    TDS_Segmentsabc + TDS_Segmentd + TDS_Segmentsefg
TDS_chiffre9    EQU    TDS_Segmentsab + TDS_Segmentc + TDS_Segmentf + TDS_Segmentg
TDS_chiffreA    EQU    TDS_Segmentsab + TDS_Segmentc + TDS_Segmentsefg
TDS_chiffreB    EQU    TDS_Segmentc + TDS_Segmentd + TDS_Segmente + TDS_Segmentsefg
TDS_chiffreC    EQU    TDS_Segmenta + TDS_Segmentd + TDS_Segmente + TDS_Segmentf
TDS_chiffreD    EQU    TDS_Segmentsbc + TDS_Segmentd + TDS_Segmente + TDS_Segmentg
TDS_chiffreE    EQU    TDS_Segmenta + TDS_Segmentd + TDS_Segmentsef + TDS_Segmentg
TDS_chiffreF    EQU    TDS_Segmenta + TDS_Segmente + TDS_Segmentf + TDS_Segmentg
TDS_chiffreVide    EQU 0x00
    endif
    endm
    
;******************************************************************
;                   Affichage d'
un chiffre hexa
;******************************************************************

TDS_AfficheV    macro   V
; affiche le chiffre hexa passé dans la variable V
    BANKSEL V
    movf    V
, w
    CALLX    TDS_AfficheWREG
    endm

TDS_AfficheL    macro   V
; affiche le chiffre hexa passé dans le litéral V
    movlw     V
    CALLX    TDS_AfficheWREG
    endm
        
;******************************************************************
;
                   Affichage d'un segment
;******************************************************************

; affiche le segment dont le n° est passé dans la variable V
TDS_AfficheSegmentV macro   V
    BANKSEL   V
    movf      V, w
    CALLX    TDS_AfficheSegmentWREG
    endm

TDS_AfficheSegmentL macro   V
; affiche le segment dont le n° est passé en litéral V
    movlw     V
    CALLX    TDS_AfficheSegmentWREG
    endm
    
TDS_CODE macro  TypeCode
    if  TypeCode >3
        messg   " "
        error   "Paramètre d'
appel de la macro TYPE_CODE incorrect"
        messg   "
 "
     endif
     
TDS_DEBUT_CODE     

;******************************************************************
;                            convertir
;                            ---------
;******************************************************************
    if  (TypeCode & TDS_CODECHIFFRES) != 0
    
TDS_Convertir
; convertir la valeur présente dans W <0 à 15> en la valeur à envoyer
; au HC4094 pour un affichage de ce TDS_chiffre sur le TDS0316
    andlw   0x0f
    addwf    PCL,f
    retlw     TDS_chiffre0
    retlw     TDS_chiffre1
    retlw     TDS_chiffre2
    retlw     TDS_chiffre3
    retlw     TDS_chiffre4
    retlw     TDS_chiffre5
    retlw     TDS_chiffre6
    retlw     TDS_chiffre7
    retlw     TDS_chiffre8
    retlw     TDS_chiffre9
    retlw     TDS_chiffreA
    retlw     TDS_chiffreB
    retlw     TDS_chiffreC
    retlw     TDS_chiffreD
    retlw     TDS_chiffreE
    retlw     TDS_chiffreF
TDS_FinConvertir
    if  TDS_Convertir & 0xff00 != (TDS_FinConvertir-1) & 0xff00
        messg   "
 "
        error   "
La table TDS_Convertir franchit une frontière de bloc"
        messg   "
 "
    endif
TDS_AfficheWREG
; affiche le chiffre hexa donné dans WREG
    call    TDS_Convertir
    goto    TDS_SetTDSSegmentsWREG
    
    endif
    
    if  (TypeCode & TDS_CODESEGMENTS) != 0
TDS_getTDS_Segment
; retourne dans WREG la configuration de bits qu'il faut envoyer
; sur le port TDS_Port pour afficher le segment (et lui seul)
; dont le n° est passé dans WREG
    andlw   0x07
    addwf    PCL,f
    retlw    TDS_Segmenta
    retlw    TDS_Segmentb
    retlw    TDS_Segmentc
    retlw    TDS_Segmentd
    retlw    TDS_Segmente
    retlw    TDS_Segmentf
    retlw    TDS_Segmentg
    retlw    TDS_SegmentDP
TDS_FingetTDS_Segment
    if  TDS_getTDS_Segment & 0xff00 != (TDS_FingetTDS_Segment-1) & 0xff00
        messg   "
 "
        error   "
La table TDS_getTDS_Segment franchit une frontière de bloc"
        messg   "
 "
    endif
TDS_AfficheSegmentWREG
; allume le segment dont le numéro est donné dans WREG
; 0=a, 1=b, ..., 6=g, 7=DP
    call    TDS_getTDS_Segment
    goto    TDS_SetTDSSegmentsWREG
    
    endif
    

TDS_SetTDSSegmentsWREG
; envoie sur TDS_Port la valeur passée dans WREG
    BANKSEL TDS_Port
    movwf   TDS_Port
    return
    
    endm    
    endif


les lignes 3 et 4, classiques, servent à éviter des doubles def

Code : Tout sélectionner


    ifndef  _TDS
        
#DEFINE _TDS


la ligne 5 introduit les macros d'appel inter-pages dont j'ai parlé dans le post mentionné plus haut

Code : Tout sélectionner


    include     
"../../callx/callx.inc"


Les lignes 8 et 9 définissent deux constantes permettant de distinguer les deux types de TDS

Code : Tout sélectionner


    
#DEFINE TDS_ANODECOMMUNE 0
    #DEFINE TDS_CATHODECOMMUNE 1


les lignes 11 et 12 définissent deux constantes définissant les besoins de l'utilisateur (voir plus loin)

Code : Tout sélectionner


    
#DEFINE TDS_CODESEGMENTS    1
    #DEFINE TDS_CODECHIFFRES    2


les lignes 15 à 120 précisent au module les contingences matérielles (port utilisé, liaisons entre les broches du pic et les broches du TDS)

Code : Tout sélectionner


TDS_Init    macro    TDS_Type
, Port, sa,sb,sc,sd,se,sf,sg,sdp
; Renseigner le programme 
;   du type d'afficheur utilisé
;   du port utilisé
;   des pins où sont connnectées les pins du TDS pour chaque segment

Cette macro est à invoquer avant tout autre usage de ce module. Par ailleurs, elle définit des constantes facilitant l’usage du TDS. Je crois que les libellés sont assez explicites pour se passer de commentaires.

lignes 122 à 137, les deux macros TDS_AfficheV et TDS_AfficheL affiche un chiffre hexa dont la valeur est passée dans une variable (V) ou en littéral (L)
Ce ne sont que des commodités pour éviter à l'utilisateur les instructions de transfert dans WREG

Code : Tout sélectionner


TDS_AfficheV    macro   V
; affiche le chiffre hexa passé dans la variable V
    BANKSEL V
    movf    V
, w
    CALLX    TDS_AfficheWREG
    endm

TDS_AfficheL    macro   V
; affiche le chiffre hexa passé dans le litéral V
    movlw     V
    CALLX    TDS_AfficheWREG
    endm


lignes 139 à 154, les deux macros TDS_AfficheSegmentV et TDS_AfficheSegmentL affiche un segment dont le numéro est passée dans une variable (V) ou en littéral (L)
Ce ne sont que des commodités pour éviter à l'utilisateur les instructions de transfert dans WREG

Code : Tout sélectionner


TDS_AfficheSegmentV macro   V
; affiche le segment dont le n° est passé dans la variable V
    BANKSEL   V
    movf      V
, w
    CALLX    TDS_AfficheSegmentWREG
    endm

TDS_AfficheSegmentL macro   V
; affiche le segment dont le n° est passé en litéral V
    movlw     V
    CALLX    TDS_AfficheSegmentWREG
    endm


les ligne 156 à la fin définissent une macro introduisant le code du module.

Code : Tout sélectionner


TDS_CODE macro  TypeCode

Ici, j'introduis un petit subterfuge qui dans le cas présent peut apparaître comme un gadget, mais pourrait avoir une utilité dans d'autres situations. J'autorise l'utilisateur à préciser s'il utilisera ce module pour afficher des segments seuls, des chiffres hexa ou les deux. C'est le rôle des deux constantes définies plus haut TDS_CODECHIFFRES et TDS_CODESEGMENTS. On voit ici qie l'invocation d'une macro peut introduire des codes différents.

Les lignes 236 à 240 définissent le sous-programme utilisé par tous les autres points d'entrée qui affiche la combinaison de segments qu'on lui passe en paramètre.

Code : Tout sélectionner


TDS_SetTDSSegmentsWREG
envoie sur TDS_Port la valeur passée dans WREG
    BANKSEL TDS_Port
    movwf   TDS_Port
    
return
 

il peut être utilisé de n'importe quel point du programme dans une séquence du type

Code : Tout sélectionner


    movlw    TDS_Chiffre8
    CALLX    TDS_SetTDSSegmentsWREG


On pourra constater que toutes les précautions sont prises (du moins je pense) pour prévenir l'utilisateur de problèmes de gestion de page au moment de l'assemblage. Ceci est souhaitable dans une telle situation où en utilisant ce fichier, on ne sait pas où l'utilisateur va l'installer dans son code.
Cordialement

JJE

C'est pas parcequ'on n'a rien à dire qu'il faut fermer sa G....e

Retourner vers « Langage ASM »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 51 invités