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
Maître
Maître
Messages : 3028
Âge : 100
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:0> les 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=1, PEIE/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=1, et mode asynchrone haute vitesse BRGH=1)
                
movwf    TXSTA
                movlw    
b'10010000'                ; RCSTA (Utilisation du port série activée SPEN=1, Réception USART activée CREN=1)
                
movwf    RCSTA
                movlw    d
'25'                    ; 9600bauds avec sync=O, brgh=1, brg16=0, xtal=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         *
;         
dividende16, diviseur16, quotient16    et reste16                *
;                                                                    *
; 
Placer le poids fort de la valeur à diviser dans dividende16, le  *
; 
le poids faible dans dividende16+1                                *
; 
Placer le poids fort du diviseur dans diviseur16, le 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 valeur2, valeur2+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 6 invités