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 ---
- 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 ---
Modérateur : Jérémy
ASM: Exemple de division 16 bits sur 18F4525
- F6FCO

Expert- Messages : 2846
- Âge : 99
- Enregistré en : décembre 2017
- Localisation : Banlieue sud de Klyntar
- Contact :
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
Retourner vers « Recueil de mini programmes »
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité
