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 ---
Bout de code posé là !

Modérateur : Jérémy

ASM: Exemple de division 16 bits sur 18F4525
F6FCO
Avatar de l’utilisateur
Expert
Expert
Messages : 2846
Âge : 99
Enregistré en : décembre 2017
Localisation : Banlieue sud de Klyntar
Contact :

#1 Message par F6FCO » mar. 14 mai 2024 20:22

Exemple de division 16 bits sur 18F4525.

Code : Tout sélectionner

;----------------------------------------------------------------------------------------------
;                                
Division 16bits F6FCO
;                                     12 décembre 2018

;----------------------------------------------------------------------------------------------

    
Errorlevel-302                         Supprime le message "Ensure that bank bits are correct" 

    
list        p=18f4525                processeur utilisé 
    
#include    <p18f4525.inc>            ; Définitions des constantes

;---------------------------------------------------------------------------------------------

 
CONFIG    OSC XT                        Oscillateur ext 4MHz 
 
;CONFIG    OSC HSPLL                        Oscillateur interne 32Mhz 
 CONFIG    IESO 
OFF                        Oscillateur secondaire refusé (ON/OFF)
 
CONFIG PWRT ON                        Délai au démarrage (ON/OFF)
 
CONFIG BOREN OFF                        Reset si chute de tension (ON/OFF)
 
CONFIG BORV 0                        Tension de reset en 1/10ème Volts 
 CONFIG WDT 
OFF                        Mise hors service du watchdog (ON/OFF)
 
CONFIG PBADEN OFF                    PORTB<4:0les broches sont configurées comme E/S numériques lors de la réinitialisation
 CONFIG LPT1OSC 
OFF                    Timer1 configuré pour un fonctionnement plus puissant
 CONFIG MCLRE 
ON                        Mclr 
 CONFIG STVREN 
ON                        Reset sur débordement de pile (ON/OFF)
 
CONFIG LVP OFF                        Programmation basse tension autorisée (ON/OFF)
 
CONFIG XINST OFF                        L'extension du jeu d'instructions et le mode d'adressage indexé sont désactivés(mode hérité)
 CONFIG DEBUG = ON                        ; Debugger hors service
 CONFIG CP0 = OFF                        ; Code protection sur block 0 (ON/OFF)
 CONFIG CP1 = OFF                        ; Code protection sur block 1 (ON/OFF)
 CONFIG CP2 = OFF                        ; Code protection sur block 2 (ON/OFF)
 CONFIG CPB = OFF                        ; Code protection sur bootblock  (ON/OFF)
 CONFIG CPD = OFF                        ; Code protection sur eeprom (ON/OFF)
 CONFIG WRT0 = OFF                        ; Protection écriture block 0 (ON/OFF)
 CONFIG WRT1 = OFF                        ; Protection écriture block 1 (ON/OFF)
 CONFIG WRT2 = OFF                        ; Protection écriture block 2 (ON/OFF)
 CONFIG WRTB = OFF                        ; Protection écriture bootblock (ON/OFF)
 CONFIG WRTC = OFF                        ; Protection écriture configurations (ON/OFF)
 CONFIG WRTD = OFF                        ; Protection écriture zone eeprom (ON/OFF)
 CONFIG EBTR0 = OFF                        ; Protection lecture de table block 0 (ON/OFF)
 CONFIG EBTR1 = OFF                        ; Protection lecture de table block 1 (ON/OFF)
 CONFIG EBTR2 = OFF                        ; Protection lecture de table block 2 (ON/OFF)
 CONFIG EBTRB = OFF                        ; Protection lecture de table bootblock (ON/OFF)
            

;------------------------------ déclaration des variables -------------------------------------

                 CBLOCK    H'
08'
                    ptr_train_RCIF                    ; compteur nb octets reçus dans un train
                    valeur1:2
                    valeur2:2
                    dividende16:2                        ; utilisé par division 16bits
                    diviseur16:2                        ; utilisé par division 16bits
                    reste16:2                            ; utilisé par division 16bits
                    quotient16:2                        ; utilisé par division 16bits
                    W_TEMP
                    STATUS_TEMP
                    BSR_TEMP
                 ENDC
                 
                 CBLOCK H'
100
                ENDC


;--------------------------------- adresse de depart après reset -----------------------------
                ORG     H'
0'
                bra        init      

;--------------------------------------- interruptions ---------------------------------------

                ORG        H'
08'
interrupt       btfss    PIR1,RCIF                ; registre plein ? si oui on saute à réception
                bra        int1                    ; sinon on sort de l'
interrupt                   
reception        
                nop
                movff    RCREG
,POSTINC0            lecture de RCREG  et mise en mem       
                incf    ptr_train_RCIF            
on a reçu qq chose donc on incrémente le compteur de trains
                btfss    RCSTA
,OERR                test d'une erreur d'overrun
                
goto    int1
                
traitement de l'erreur d'overrun
                bcf        RCSTA
,CREN                on efface le bit OERR
                bsf        RCSTA
,CREN                on relance la réception
int1            
traitement des autres interruptions
                retfie
            
         
;----------------------------------- Initialisations -------------------------------------------------
init
                
;ovlw    b'01000000'                oscillateur interne 8Mhzx4=32Mhz
                
;ovlw    OSCTUNE                    
                movlw    
b'11000000'                INTCON (activation des int GIE/GIEH=1PEIE/GIEL=1)
                
movwf    INTCON
                movlw    
b'10000000'                RCON (priorités int activées IPEN=1,)
                
movwf    RCON
                movlw    
b'00100000'                IPR1 (Rx en haute priorité RCIP=1)
                
movwf    IPR1
                movlw    
b'00100000'                PIE1 (int RX activée RCIE=1)
                
movwf    PIE1
                movlw    
b'00100100'                TXSTA (Emission USART activée TXEN=1et mode asynchrone haute vitesse BRGH=1)
                
movwf    TXSTA
                movlw    
b'10010000'                RCSTA (Utilisation du port série activée SPEN=1Réception USART activée CREN=1)
                
movwf    RCSTA
                movlw    d
'25'                    9600bauds avec sync=Obrgh=1brg16=0xtal=4Mhz
                movwf    SPBRG
                bcf        BAUDCON
,BRG16            réglé à 8bits        
                movlw     
B'00000111'                 
                
movwf    TRISB
                movlw     
B'11001100'                
                
movwf    TRISC
                movlw     
B'10000011'                  
                
movwf    TRISD
                movlw     
B'10000011'                 
                
movwf    TRISE
                clrf    PORTB
                clrf    PORTC
                clrf    PORTD
                clrf    PORTE
                
; -----------------   initialisation du PORT A
                clrf    PORTA
                clrf    LATA
                movlw    0xf
                movwf    ADCON1
                movwf    0x07
                movwf    CMCON            
                movlw     0xff                 
                movwf    TRISA
            
                
;############################################################################################################################

main      
            nop
            movlw    0xff
            movwf    dividende16                
poids fort dividende
            movlw    0xff
            movwf    dividende16
+1             poids faible dividende
            movlw    0x03
            movwf    diviseur16                
poids fort diviseur
            movlw    0xd5
            movwf    diviseur16
+1            poids faible dividende                
            call    division16
            nop
            
            
            bra        main
            
                                                                                                            

; ----------------------------------------------------- division 16bits -------------------------------------------------------

;********************************************************************
;                    
Division sur 16bits                              *
;     
Il faut préalablement déclarer les variables sur 16 bits         *
;         
dividende16diviseur16quotient16    et reste16                *
;                                                                    *
Placer le poids fort de la valeur à diviser dans dividende16le  *
le poids faible dans dividende16+1                                *
Placer le poids fort du diviseur dans diviseur16le poids faible    *
dans diviseur16+1                                                    *
Le résultat sera dans quotient16 et quotient16+1                     *   
Le reste sera dans reste16 et reste16+1                            *        
;                                                                    *
Cette division utilise la routine soustraction16                     *    
il faut donc aussi avoir déclaré les variables sur                 *                                            
;                 
16 bits valeur1 et valeur2                                *
;********************************************************************   


division16    quotient=0
            clrf    quotient16
            clrf    quotient16
+1
            
reste=dividende
            movff    dividende16
,reste16
            movff    dividende16
+1,reste16+1
div16_1        
            movf    reste16
,w
            subwf    diviseur16
,w
            
test si poids fort reste>diviseur ?
            
btfss    STATUS,C                    
            bra        div16_3
            
test si poids fort reste=diviseur sinon on sort
div16_4        bz        div16_2
findiv16    
return
div16_2        test si poids faible reste>diviseur
            movff    reste16
+1,WREG
            subwf    diviseur16
+1,w
            btfss    STATUS
,C
            bra        div16_3
            bz        div16_3
            bra        findiv16
div16_3        
reste=dividende-diviseur
            movff    reste16
,valeur1
            movff    reste16
+1,valeur1+1
            movff    diviseur16
,valeur2
            movff    diviseur16
+1,valeur2+1
            call    soustraction16            
résultat dans valeur2valeur2+1
            movff    valeur2
,reste16
            movff    valeur2
+1,reste16+1
            
quotient +1
            movff    quotient16
,valeur1
            movff    quotient16
+1,valeur1+1
            clrf    valeur2
            movlw    1
            movwf    valeur2
+1
            
on additionne valeur1 et valeur2 sur 16bits
            movf    valeur1
+1,W
            addwf    valeur2
+1,f
            
on additionne le carry dans le poids fort
            movf    STATUS
,W
            andlw    0x1
            addwf    valeur2
,f
            movf    valeur1
,W
            addwf    valeur2
,f
            
on charge valeur2 dans quotient
            movff    valeur2
,quotient16
            movff    valeur2
+1,quotient16+1
            bra        div16_1


;********************************************************************
;                   
Soustraction sur 16bits                            *
;     
Il faut préalablement déclarer des variables sur 16 bits         *
;             
valeur1:2 et valeur2:2                                    *
;                                                                    *
Placer le poids fort de la première valeur dans valeur1            *
et le poids faible dans valeur1+1                                    *
Placer le poids fort de la valeur à soustraire dans valeur2        *
et le poids faible dans valeur2+1                                   *   
Appeler la procédure soustraction16 et le résultat de             *
valeur1-valeur2 sur 16bits sera dans les 2 octets de valeur2           *
;********************************************************************   
soustraction16
    
; ------------------------------------- on traite valeur2
            movf    valeur2
,w        inversion du poids fort
            xorlw    0xff
            movwf    valeur2
            movf    valeur2
+1,w        complément à 2 du poids faible
            xorlw    0xff
            addlw    0x01
            movwf    valeur2
+1    
            movf    STATUS
,w        on isole le carry
            andlw    0x01
            addwf    valeur2
,f        et on l'ajoute au poids fort    
            ;----------------------------------- on additionne les deux poids faibles    
            movf    valeur1+1,w
            addwf    valeur2+1,f    
            movf    STATUS,w        ; on isole le carry
            andlw    0x01
            addwf    valeur2,f        ; et on l'
ajoute au poids fort    
            
;--------------------------------- on additionne maintenant les deux poids forts
            movf    valeur1
,w
            addwf    valeur2
,f
            
s'il y a carry il sera perdu car on reste en 16bits
            return
    
              

          END
      



Une porte nand prend 2 bits en entrée... :eek:

Retourner vers « Recueil de mini programmes »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité