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 : mazertoc
Goto , call pile sur pic 16f
bonjour,
basic ou C c'est pareil pour moi je ne connais pas lol
j'ai normalement enlevé touts les goto imbriqué dans les call a moin que j'en ai oublié normalement il n'y en a plus mais sa bug encore je vais peut etre utiliser le watchdog mais sa ne va pas me trouver d'ou viens le probleme...
j'ai essayer de mettre des commentaires sur le code pour que se soit plus facile a regarder pour vous soyez indulgent lol merci
pour le code le voici :
basic ou C c'est pareil pour moi je ne connais pas lol
j'ai normalement enlevé touts les goto imbriqué dans les call a moin que j'en ai oublié normalement il n'y en a plus mais sa bug encore je vais peut etre utiliser le watchdog mais sa ne va pas me trouver d'ou viens le probleme...
j'ai essayer de mettre des commentaires sur le code pour que se soit plus facile a regarder pour vous soyez indulgent lol merci
pour le code le voici :
Code : Tout sélectionner
start
movlw D'1'
movwf adra
movlw 0X70
movwf calcul
goto lecture
sendata
decf scdd,f ; preparation des données avant d'envoyer au ds1307
swapf scdd,w
movwf secondes
decf scdu,w
addwf secondes,f
decf mind,f
swapf mind,w
movwf minutes
decf minu,w
addwf minutes,f
call I2C_start
movlw B'11010000' ;adresse
call I2C_write
call I2C_ack_slave_to_master
movlw 0x00 ;registre secondes
call I2C_write
call I2C_ack_slave_to_master
movlw D'0' ; on remet les secondes a 0
call I2C_write
call I2C_ack_slave_to_master
movf secondes,w ;valeur des MINUTES
call I2C_write
call I2C_ack_slave_to_master
movf minutes,w ;valeur des HEURES
call I2C_write
call I2C_ack_slave_to_master
call I2C_stop
goto lecture
fonction
bcf flag1,1 ; on s'en fou
movf adra,w ; numeros du digit a regler
movwf PORTA ; allume le digit a regler
movf calcul,w ; adresse du debut de la zone variable scd,scdd,minu,mind
movwf FSR
movf INDF,w ; valeur de la variable selectionnée
call readee ; lecture de la table pour le code a envoyé au digit
movwf PORTB ; on envoie sur le portb la valeur du digit
testbp
movlw D'220'
movwf d3
bouc121
movlw D'120'
movwf d2
bouc111
movlw D'120'
movwf d1
bouc101
btfss PORTC,0 ; test bp
goto bp1b
btfss PORTC,1
goto bp2b
btfss PORTC,2
goto bp3b
decfsz d1
goto bouc101
decfsz d2
goto bouc111
decfsz d3
goto bouc121
bcf flag1,7
movlw D'1' ; on remet le numeros du digit a regler a 1 pour la prochaine fois
movwf adra
movlw 0X70 ; pareil pour l'adresse de la variable contenant la valeur du premier digit
movwf calcul
goto sendata ; pas de bp appuyé depuis 5 secondes donc on envoie les données de reglages et on repasse a l'affichage
bp1b ; bp moins
call tempo2
call tempo2
call tempo2
call tempo2
movf calcul,w ; adresse de la variable contenant la valeur du digit a regler
movwf FSR
decfsz INDF,f ; si valeur du digit a 0 on remet la valeur a 10 (decalage de 1 donc on affiche 9)
goto fonction ; pas a 0 on envoie
movf calcul,w
movwf FSR
movlw D'10' ; sinon on remet a 10 ( 10-1 9
movwf INDF
goto fonction
bp2b ; bp reglage
call tempo2
call tempo2
call tempo2
call tempo2
incf calcul,f ; on passe au digit suivant
movlw 0X74
subwf calcul, W
btfss STATUS, Z ; test si debordement 4 digits
goto bp2bs
movlw 0X70 ; debordement donc on remet a 0
movwf calcul
goto bp2bs
bp2bs
rlf adra,f ; affiche le digit suivant
btfss adra,4 ; test debordement digit
goto fonction
movlw D'1'
movwf adra
bcf flag1,7
goto sendata
bp3b ; bp plus
call tempo2
call tempo2
call tempo2
call tempo2
movf calcul,w ; adresse de la variable contenant la valeur du digit a regler
movwf FSR
incf INDF,f
movf calcul,w
movwf FSR
movlw D'11'
subwf INDF,w
btfss STATUS, Z ; test debordement chiffre dans le digit
goto fonction ; pas de debordement
movf calcul,w
movwf FSR
movlw D'1' ; debordement du chiffre arrivé a 9 donc on repasse a 1 ( 1-1 0
movwf INDF
call readee
goto fonction
lecture
call I2C_start
movlw B'11010000' ;adresse
call I2C_write
call I2C_ack_slave_to_master
movlw 0x01 ;registre minutes
call I2C_write
call I2C_ack_slave_to_master
call I2C_repeated_start
movlw B'11010001' ;adresse en lecture
call I2C_write
call I2C_ack_slave_to_master
call I2C_read
movwf secondes ; valeur des MINUTES
call I2C_ack_master_to_slave
call I2C_read
movwf minutes ; valeur des HEURES
call I2C_ack_master_to_slave
call I2C_read
movwf heures
call I2C_noack
call I2C_stop
prepa
movlw B'00001111' ; masque
andwf secondes,w
movwf scdu ; on masque les dizaines
incf scdu,f ; incremente de 1 pour le decmptage apres
movlw B'11110000' ; masque
andwf secondes,w
movwf scdd ; on masque les unitées
swapf scdd,f
incf scdd,f ; incremente de 1 pour le decmptage apres
movlw B'00001111'
andwf minutes,w
movwf minu ; on masque les dizaines
incf minu,f
movlw B'11110000'
andwf minutes,w
movwf mind ; on masque les unitées
swapf mind,f
incf mind,f
affichage
btfsc flag1,7 ; test si on appuie sur le bouton reglage
goto fonction
bcf PORTA,3 ; eteint le digit 4
bsf PORTA,0 ; allume le digit 1
movf scdu,w
call readee
movwf PORTB
call tempo
movf scdd,w
call readee
bcf PORTA,0
bsf PORTA,1
movwf PORTB
call tempo
movf minu,w
call readee
bcf PORTA,1
bsf PORTA,2
movwf PORTB
call tempo
movf mind,w
call readee
bcf PORTA,2
bsf PORTA,3
movwf PORTB
call tempo
goto lecture
END ; directive fin de programme
Goto , call pile sur pic 16f
Goto , call pile sur pic 16f
Bonjour,
J'ai pas tout compris, mais tu gagnerais à structurer un peu pour éviter tous ces gotos.
Un programme principal du genre :
C'est quoi flag1 ?
J'ai pas tout compris, mais tu gagnerais à structurer un peu pour éviter tous ces gotos.
Un programme principal du genre :
Code : Tout sélectionner
init
boucle
call lecture
call affichage
call fonction
btfsc STATUS,C
call senddata
goto boucle
C'est quoi flag1 ?
Goto , call pile sur pic 16f
Oui satinas je sais c’est un peu le basar il faudrait que j’y arrive a strucurer mais seulement .... j’y arrive pas lol
Flag1 je ne me sert que du bit 7 . En fait dans la routine d’interruption timer0 je met bsf. Flag1,7 comme sa dans le prog principale des que je detecte le bit 7 a 1 sa veut dire qui faut que je rentre dans le mode reglage
Flag1 je ne me sert que du bit 7 . En fait dans la routine d’interruption timer0 je met bsf. Flag1,7 comme sa dans le prog principale des que je detecte le bit 7 a 1 sa veut dire qui faut que je rentre dans le mode reglage
Goto , call pile sur pic 16f
Goto , call pile sur pic 16f
Goto , call pile sur pic 16f
Goto , call pile sur pic 16f
Code : Tout sélectionner
;*****************************************************************************
; Ce fichier est la base de départ pour une programmation avec *
; le PIC 16F876. Il contient les informations de base pour *
; démarrer. *
; *
;*****************************************************************************
; *
; NOM: *
; Date: *
; Version: *
; Circuit: *
; Auteur: *
; *
;*****************************************************************************
; *
; Fichier requis: P16F876.inc *
; *
; *
; *
;*****************************************************************************
; *
; Notes:
; alimentation 5VDC
; portA
; A0 : digit 1
; A1 : digit 2
; A2 : digit 3
; A3 : digit 4
; portB
; B0 a B7 pour les 7 segments et le point
; portC
; C0 : bp moins
; C1 : bp reglage
; C2 : bp plus *
; *
; *
; *
; *
;*****************************************************************************
LIST p=16F876 ; Définition de processeur
#include <p16F876.inc> ; fichier include
#include <table.inc>
radix dec ; on travaille en décimal par défaut
__CONFIG _CP_OFF & _DEBUG_OFF & _WRT_ENABLE_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC
;*****************************************************************************
; ASSIGNATIONS SYSTEME *
;*****************************************************************************
; REGISTRE OPTION_REG (configuration)
; -----------------------------------
OPTIONVAL EQU B'00000111'
; RBPU b7 : 1= Résistance rappel +5V hors service
; INTEDG b6 : 1= Interrupt sur flanc montant de RB0
; 0= Interrupt sur flanc descend. de RB0
; TOCS b5 : 1= source clock = transition sur RA4
; 0= horloge interne
; TOSE b4 : 1= Sélection flanc montant RA4(si B5=1)
; 0= Sélection flanc descendant RA4
; PSA b3 : 1= Assignation prédiviseur sur Watchdog
; 0= Assignation prédiviseur sur Tmr0
; PS2/PS0 b2/b0 valeur du prédiviseur
; 000 = 1/1 (watchdog) ou 1/2 (tmr0)
; 001 = 1/2 1/4
; 010 = 1/4 1/8
; 011 = 1/8 1/16
; 100 = 1/16 1/32
; 101 = 1/32 1/64
; 110 = 1/64 1/128
; 111 = 1/128 1/256
; REGISTRE INTCON (contrôle interruptions standard)
; -------------------------------------------------
INTCONVAL EQU B'10100000'
; GIE b7 : masque autorisation générale interrupt
; ne pas mettre ce bit à 1 ici
; sera mis en temps utile
; PEIE b6 : masque autorisation générale périphériques
; T0IE b5 : masque interruption tmr0
; INTE b4 : masque interuption RB0/Int
; RBIE b3 : masque interruption RB4/RB7
; T0IF b2 : flag tmr0
; INTF b1 : flag RB0/Int
; RBIF b0 : flag interruption RB4/RB7
; REGISTRE PIE1 (contrôle interruptions périphériques)
; ----------------------------------------------------
PIE1VAL EQU B'00000000'
; PSPIE b7 : Toujours 0 sur PIC 16F786
; ADIE b6 : masque interrupt convertisseur A/D
; RCIE b5 : masque interrupt réception USART
; TXIE b4 : masque interrupt transmission USART
; SSPIE b3 : masque interrupt port série synchrone
; CCP1IE b2 : masque interrupt CCP1
; TMR2IE b1 : masque interrupt TMR2 = PR2
; TMR1IE b0 : masque interrupt débordement tmr1
; REGISTRE PIE2 (contrôle interruptions particulières)
; ----------------------------------------------------
PIE2VAL EQU B'00000000'
; UNUSED b7 : inutilisé, laisser à 0
; RESERVED b6 : réservé, laisser à 0
; UNUSED b5 : inutilisé, laisser à 0
; EEIE b4 : masque interrupt écriture EEPROM
; BCLIE b3 : masque interrupt collision bus
; UNUSED b2 : inutilisé, laisser à 0
; UNUSED b1 : inutilisé, laisser à 0
; CCP2IE b0 : masque interrupt CCP2
; REGISTRE ADCON1 (ANALOGIQUE/DIGITAL)
; ------------------------------------
ADCON1VAL EQU B'00000110' ; PORTA en mode digital
; DIRECTION DES PORTS I/O
; -----------------------
DIRPORTA EQU B'00000000' ; Direction PORTA (1=entrée)
DIRPORTB EQU B'00000000' ; Direction PORTB
DIRPORTC EQU B'01111111' ; Direction PORTC
;*****************************************************************************
; ASSIGNATIONS PROGRAMME *
;*****************************************************************************
; exemple
; -------
MASQUE EQU H'00FF'
;*****************************************************************************
; DEFINE *
;*****************************************************************************
; exemple
; -------
#DEFINE LED1 PORTB,1 ; LED de sortie 1
;*****************************************************************************
; MACRO *
;*****************************************************************************
; Changement de banques
; ----------------------
BANK0 macro ; passer en banque0
bcf STATUS,RP0
bcf STATUS,RP1
endm
BANK1 macro ; passer en banque1
bsf STATUS,RP0
bcf STATUS,RP1
endm
BANK2 macro ; passer en banque2
bcf STATUS,RP0
bsf STATUS,RP1
endm
BANK3 macro ; passer en banque3
bsf STATUS,RP0
bsf STATUS,RP1
endm
; Sauts inter-pages
; -----------------
GOTOX macro ADRESSE ; saut inter-page
local BIT4 = (ADRESSE & 0x1000) ; voir bit 12
local BIT3 = (ADRESSE & 0x0800) ; voir bit 11
local ICI ; adresse courante
ICI
local PICI = (ICI+2 & 0x1800) ; page du saut
IF BIT3 ; si page 1 ou 3
bsf PCLATH , 3 ; b3 de PCLATH = 1
ELSE ; sinon
bcf PCLATH , 3 ; b3 de PCLATH = 0
ENDIF
IF BIT4 ; si page 2 ou 3
bsf PCLATH , 4 ; b4 de PCLATH = 1
ELSE ; sinon
bcf PCLATH , 4 ; b4 de PCLATH = 0
ENDIF
goto (ADRESSE & 0x7FF | PICI) ; adresse simulée
endm
PCLAX macro ADRESSE ; positionne PCLATH pour
; les sauts sans le saut
local BIT4 = (ADRESSE & 0x1000) ; voir bit 12
local BIT3 = (ADRESSE & 0x0800) ; voir bit 11
IF BIT3 ; si page 1 ou 3
bsf PCLATH , 3 ; b3 de PCLATH = 1
ELSE ; sinon
bcf PCLATH , 3 ; b3 de PCLATH = 0
ENDIF
IF BIT4 ; si page 2 ou 3
bsf PCLATH , 4 ; b4 de PCLATH = 1
ELSE ; sinon
bcf PCLATH , 4 ; b4 de PCLATH = 0
ENDIF
endm
GOTSX macro ADRESSE ; saut inter-page sans
; sélection de PCLATH
local ICI ; adresse courante
local PICI = (ICI & 0x1800) ; page du saut
ICI
goto (ADRESSE & 0x7FF | PICI) ; adresse simulée
endm
; Sous-routines inter-pages
; -------------------------
CALLX macro ADRESSE ; call inter-page
local BIT4 = (ADRESSE & 0x1000) ; voir bit 12
local BIT3 = (ADRESSE & 0x0800) ; voir bit 11
local ICI ; adresse courante
ICI
local PICI = (ICI+2 & 0x1800) ; page du saut
IF BIT3 ; si page 1 ou 3
bsf PCLATH , 3 ; b3 de PCLATH = 1
ELSE ; sinon
bcf PCLATH , 3 ; b3 de PCLATH = 0
ENDIF
IF BIT4 ; si page 2 ou 3
bsf PCLATH , 4 ; b4 de PCLATH = 1
ELSE ; sinon
bcf PCLATH , 4 ; b4 de PCLATH = 0
ENDIF
call (ADRESSE & 0x7FF | PICI) ; adresse simulée
local BIT4 = ((ICI+5) & 0x1000) ; voir bit 12
local BIT3 = ((ICI+5) & 0x0800) ; voir bit 11
IF BIT3 ; si page 1 ou 3
bsf PCLATH , 3 ; b3 de PCLATH = 1
ELSE ; sinon
bcf PCLATH , 3 ; b3 de PCLATH = 0
ENDIF
IF BIT4 ; si page 2 ou 3
bsf PCLATH , 4 ; b4 de PCLATH = 1
ELSE ; sinon
bcf PCLATH , 4 ; b4 de PCLATH = 0
ENDIF
endm
CALLSX macro ADRESSE ; sous-routine inter-page sans
; sélection de PCLATH
local ICI ; adresse courante
local PICI = (ICI & 0x1800) ; page du saut
ICI
call (ADRESSE & 0x7FF | PICI) ; adresse simulée
endm
; opérations en mémoire eeprom
; -----------------------------
REEPROM macro ; lire eeprom(adresse & résultat en w)
clrwdt ; reset watchdog
bcf STATUS,RP0 ; passer en banque2
bsf STATUS,RP1
movwf EEADR ; pointer sur adresse eeprom
bsf STATUS,RP0 ; passer en banque3
bcf EECON1,EEPGD ; pointer sur eeprom
bsf EECON1,RD ; ordre de lecture
bcf STATUS,RP0 ; passer en banque2
movf EEDATA,w ; charger valeur lue
bcf STATUS,RP1 ; passer en banque0
endm
WEEPROM macro addwrite ; la donnée se trouve dans W
LOCAL loop
bcf STATUS,RP0 ; passer en banque2
bsf STATUS,RP1
movwf EEDATA ; placer data dans registre
movlw addwrite ; charger adresse d'écriture
movwf EEADR ; placer dans registre
bsf STATUS,RP0 ; passer en banque3
bcf EECON1 , EEPGD ; pointer sur mémoire data
bsf EECON1 , WREN ; autoriser accès écriture
bcf INTCON , GIE ; interdire interruptions
movlw 0x55 ; charger 0x55
movwf EECON2 ; envoyer commande
movlw 0xAA ; charger 0xAA
movwf EECON2 ; envoyer commande
bsf EECON1 , WR ; lancer cycle d'écriture
bsf INTCON , GIE ; réautoriser interruptions
loop
clrwdt ; effacer watchdog
btfsc EECON1 , WR ; tester si écriture terminée
goto loop ; non, attendre
bcf EECON1 , WREN ; verrouiller prochaine écriture
bcf STATUS , RP0 ; passer en banque0
bcf STATUS , RP1
endm
;*****************************************************************************
; VARIABLES BANQUE 0 *
;*****************************************************************************
; Zone de 80 bytes
; ----------------
CBLOCK 0x20 ; Début de la zone (0x20 à 0x6F)
;Exemples
;--------
test :1 ; Zone de 1 byte
cmpt1 : 1
cmpt2 : 1
cmpt3 : 1
d1 : 1
d2 : 1
d3 : 1
table : 10 ; zone de 10 bytes
ENDC ; Fin de la zone
var1 EQU H'006E' ; adresse imposée
;*****************************************************************************
; VARIABLES ZONE COMMUNE *
;*****************************************************************************
; Zone de 16 bytes
; ----------------
CBLOCK 0x70 ; Début de la zone (0x70 à 0x7F)
scdu : 1
scdd : 1
minu : 1
mind : 1
w_temp : 1 ; Sauvegarde registre W
status_temp : 1 ; sauvegarde registre STATUS
FSR_temp : 1 ; sauvegarde FSR (si indirect en interrupt)
PCLATH_temp : 1 ; sauvegarde PCLATH (si prog>2K)
calcul : 1
flag1 : 1
adra : 1
secondes : 1
minutes : 1
heures : 1
ENDC
;*****************************************************************************
; VARIABLES BANQUE 1 *
;*****************************************************************************
; Zone de 80 bytes
; ----------------
CBLOCK 0xA0 ; Début de la zone (0xA0 à 0xEF)
ENDC ; Fin de la zone
;*****************************************************************************
; VARIABLES BANQUE 2 *
;*****************************************************************************
; Zone de 96 bytes
; ----------------
CBLOCK 0x110 ; Début de la zone (0x110 à 0x16F)
ENDC ; Fin de la zone
;*****************************************************************************
; VARIABLES BANQUE 3 *
;*****************************************************************************
; Zone de 96 bytes
; ----------------
CBLOCK 0x190 ; Début de la zone (0x190 à 0x1EF)
ENDC ; Fin de la zone
;*****************************************************************************
; DEMARRAGE SUR RESET *
;*****************************************************************************
org 0x000 ; Adresse de départ après reset
goto init ; Initialiser
; ////////////////////////////////////////////////////////////////////////////
; I N T E R R U P T I O N S
; ////////////////////////////////////////////////////////////////////////////
;*****************************************************************************
; ROUTINE INTERRUPTION *
;*****************************************************************************
;-----------------------------------------------------------------------------
; Si on n'utilise pas l'adressage indirect dans les interrupts, on se passera
; de sauvegarder FSR
; Si le programme ne fait pas plus de 2K, on se passera de la gestion de
; PCLATH
;-----------------------------------------------------------------------------
;sauvegarder registres
;---------------------
org 0x004 ; adresse d'interruption
movwf w_temp ; sauver registre W
swapf STATUS,w ; swap status avec résultat dans w
movwf status_temp ; sauver status swappé
movf FSR , w ; charger FSR
movwf FSR_temp ; sauvegarder FSR
movf PCLATH , w ; charger PCLATH
movwf PCLATH_temp ; le sauver
clrf PCLATH ; on est en page 0
BANK0 ; passer en banque0
; switch vers différentes interrupts
; inverser ordre pour modifier priorités
; mais attention alors au test PEIE
; effacer les inutiles
;----------------------------------------
; Interruption TMR0
; -----------------
btfsc INTCON,T0IE ; tester si interrupt timer autorisée
btfss INTCON,T0IF ; oui, tester si interrupt timer en cours
goto intsw1 ; non test suivant
call inttmr0 ; oui, traiter interrupt tmr0
bcf INTCON,T0IF ; effacer flag interrupt tmr0
goto restorereg ; et fin d'interruption
; SUPPRIMER CETTE LIGNE POUR
; TRAITER PLUSIEURS INTERRUPT
; EN 1 SEULE FOIS
; Interruption RB0/INT
; --------------------
intsw1
btfsc INTCON,INTE ; tester si interrupt RB0 autorisée
btfss INTCON,INTF ; oui, tester si interrupt RB0 en cours
goto intsw2 ; non sauter au test suivant
call intrb0 ; oui, traiter interrupt RB0
bcf INTCON,INTF ; effacer flag interupt RB0
goto restorereg ; et fin d'interruption
; SUPPRIMER CETTE LIGNE POUR
; TRAITER PLUSIEURS INTERRUPT
; EN 1 SEULE FOIS
; interruption RB4/RB7
; --------------------
intsw2
btfsc INTCON,RBIE ; tester si interrupt RB4/7 autorisée
btfss INTCON,RBIF ; oui, tester si interrupt RB4/7 en cours
goto intsw3 ; non sauter
call intrb4 ; oui, traiter interrupt RB4/7
bcf INTCON,RBIF ; effacer flag interupt RB4/7
goto restorereg ; et fin d'interrupt
; détection interruptions périphériques
; le test peut être supprimé si une seule
; interrupt est traitée à la fois
; --------------------------------------
intsw3
btfss INTCON,PEIE ; tester interruption périphérique autorisée
goto restorereg ; non, fin d'interruption
; Interruption convertisseur A/D
; ------------------------------
bsf STATUS,RP0 ; sélectionner banque1
btfss PIE1,ADIE ; tester si interrupt autorisée
goto intsw4 ; non sauter
bcf STATUS,RP0 ; oui, sélectionner banque0
btfss PIR1,ADIF ; tester si interrupt en cours
goto intsw4 ; non sauter
call intad ; oui, traiter interrupt
bcf PIR1,ADIF ; effacer flag interupt
goto restorereg ; et fin d'interrupt
; Interruption réception USART
; ----------------------------
intsw4
bsf STATUS,RP0 ; sélectionner banque1
btfss PIE1,RCIE ; tester si interrupt autorisée
goto intsw5 ; non sauter
bcf STATUS,RP0 ; oui, sélectionner banque0
btfss PIR1,RCIF ; oui, tester si interrupt en cours
goto intsw5 ; non sauter
call intrc ; oui, traiter interrupt
; LE FLAG NE DOIT PAS ETRE REMIS A 0
; C'EST LA LECTURE DE RCREG QUI LE PROVOQUE
goto restorereg ; et fin d'interrupt
; Interruption transmission USART
; -------------------------------
intsw5
bsf STATUS,RP0 ; sélectionner banque1
btfss PIE1,TXIE ; tester si interrupt autorisée
goto intsw6 ; non sauter
bcf STATUS,RP0 ; oui, sélectionner banque0
btfss PIR1,TXIF ; oui, tester si interrupt en cours
goto intsw6 ; non sauter
call inttx ; oui, traiter interrupt
; LE FLAG NE DOIT PAS ETRE REMIS A 0
; C'EST L'ECRITURE DE TXREG QUI LE PROVOQUE
goto restorereg ; et fin d'interrupt
; Interruption SSP
; ----------------
intsw6
bsf STATUS,RP0 ; sélectionner banque1
btfss PIE1,SSPIE ; tester si interrupt autorisée
goto intsw7 ; non sauter
bcf STATUS,RP0 ; oui, sélectionner banque0
btfss PIR1,SSPIF ; oui, tester si interrupt en cours
goto intsw7 ; non sauter
call intssp ; oui, traiter interrupt
bcf PIR1,SSPIF ; effacer flag interupt
goto restorereg ; et fin d'interrupt
; Interruption CCP1
; -----------------
intsw7
bsf STATUS,RP0 ; sélectionner banque1
btfss PIE1,CCP1IE ; tester si interrupt autorisée
goto intsw8 ; non sauter
bcf STATUS,RP0 ; oui, sélectionner banque0
btfss PIR1,CCP1IF ; oui, tester si interrupt en cours
goto intsw8 ; non sauter
call intccp1 ; oui, traiter interrupt
bcf PIR1,CCP1IF ; effacer flag interupt
goto restorereg ; et fin d'interrupt
; Interruption TMR2
; -----------------
intsw8
bsf STATUS,RP0 ; sélectionner banque1
btfss PIE1,TMR2IE ; tester si interrupt autorisée
goto intsw9 ; non sauter
bcf STATUS,RP0 ; oui, sélectionner banque0
btfss PIR1,TMR2IF ; oui, tester si interrupt en cours
goto intsw9 ; non sauter
call inttmr2 ; oui, traiter interrupt
bcf PIR1,TMR2IF ; effacer flag interupt
goto restorereg ; et fin d'interrupt
; Interruption TMR1
; -----------------
intsw9
bsf STATUS,RP0 ; sélectionner banque1
btfss PIE1,TMR1IE ; tester si interrupt autorisée
goto intswA ; non sauter
bcf STATUS,RP0 ; oui, sélectionner banque0
btfss PIR1,TMR1IF ; oui, tester si interrupt en cours
goto intswA ; non sauter
call inttmr1 ; oui, traiter interrupt
bcf PIR1,TMR1IF ; effacer flag interupt
goto restorereg ; et fin d'interrupt
; Interruption EEPROM
; -------------------
intswA
bsf STATUS,RP0 ; sélectionner banque1
btfss PIE2,EEIE ; tester si interrupt autorisée
goto intswB ; non sauter
bcf STATUS,RP0 ; oui, sélectionner banque0
btfss PIR2,EEIF ; oui, tester si interrupt en cours
goto intswB ; non sauter
call inteprom ; oui, traiter interrupt
bcf PIR2,EEIF ; effacer flag interupt
goto restorereg ; et fin d'interrupt
; Interruption COLLISION
; ----------------------
intswB
bsf STATUS,RP0 ; sélectionner banque1
btfss PIE2,BCLIE ; tester si interrupt autorisée
goto intswC ; non sauter
bcf STATUS,RP0 ; oui, sélectionner banque0
btfss PIR2,BCLIF ; oui, tester si interrupt en cours
goto intswC ; non sauter
call intbc ; oui, traiter interrupt
bcf PIR2,BCLIF ; effacer flag interupt
goto restorereg ; et fin d'interrupt
; interruption CCP2
; -----------------
intswC
bcf STATUS,RP0 ; oui, sélectionner banque0
call intccp2 ; traiter interrupt
bcf PIR2,CCP2IF ; effacer flag interupt
;restaurer registres
;-------------------
restorereg
movf PCLATH_temp , w ; recharger ancien PCLATH
movwf PCLATH ; le restaurer
movf FSR_temp , w ; charger FSR sauvé
movwf FSR ; restaurer FSR
swapf status_temp,w ; swap ancien status, résultat dans w
movwf STATUS ; restaurer status
swapf w_temp,f ; Inversion L et H de l'ancien W
; sans modifier Z
swapf w_temp,w ; Réinversion de L et H dans W
; W restauré sans modifier status
retfie ; return from interrupt
;*****************************************************************************
; INTERRUPTION TIMER 0 *
;*****************************************************************************
inttmr0
btfss PORTC,1
call bp2
return
bp2
call tempo2
call tempo2
call tempo2
call tempo2
clrf PORTA
btfsc flag1,7
return
bsf flag1,7
return
; fin d'interruption timer
; peut être remplacé par
; retlw pour retour code d'erreur
;*****************************************************************************
; INTERRUPTION RB0/INT *
;*****************************************************************************
intrb0
return ; fin d'interruption RB0/INT
; peut être remplacé par
; retlw pour retour code d'erreur
;*****************************************************************************
; INTERRUPTION RB4/RB7 *
;*****************************************************************************
intrb4
movf PORTB,w ; indispensable pour pouvoir resetter RBIF
return ; fin d'interruption RB4/RB7
; peut être remplacé par
; retlw pour retour code d'erreur
;*****************************************************************************
; INTERRUPTION CONVERTISSEUR A/D *
;*****************************************************************************
intad
return ; fin d'interruption
; peut être remplacé par
; retlw pour retour code d'erreur
;*****************************************************************************
; INTERRUPTION RECEPTION USART *
;*****************************************************************************
intrc
return ; fin d'interruption
; peut être remplacé par
; retlw pour retour code d'erreur
;*****************************************************************************
; INTERRUPTION TRANSMISSION USART *
;*****************************************************************************
inttx
return ; fin d'interruption
; peut être remplacé par
; retlw pour retour code d'erreur
;*****************************************************************************
; INTERRUPTION SSP *
;*****************************************************************************
intssp
return ; fin d'interruption
; peut être remplacé par
; retlw pour retour code d'erreur
;*****************************************************************************
; INTERRUPTION CCP1 *
;*****************************************************************************
intccp1
return ; fin d'interruption
; peut être remplacé par
; retlw pour retour code d'erreur
;*****************************************************************************
; INTERRUPTION TIMER 2 *
;*****************************************************************************
inttmr2
return ; fin d'interruption
; peut être remplacé par
; retlw pour retour code d'erreur
;*****************************************************************************
; INTERRUPTION TIMER 1 *
;*****************************************************************************
inttmr1
return ; fin d'interruption
; peut être remplacé par
; retlw pour retour code d'erreur
;*****************************************************************************
; INTERRUPTION EEPROM *
;*****************************************************************************
inteprom
return ; fin d'interruption
; peut être remplacé par
; retlw pour retour code d'erreur
;*****************************************************************************
; INTERRUPTION COLLISION *
;*****************************************************************************
intbc
return ; fin d'interruption
; peut être remplacé par
; retlw pour retour code d'erreur
;*****************************************************************************
; INTERRUPTION CCP2 *
;*****************************************************************************
intccp2
return ; fin d'interruption
; peut être remplacé par
; retlw pour retour code d'erreur
;*****************************************************************************
; ROUTINE i2c *
;*****************************************************************************
;START
I2C_start
call I2C_idle ; on attend que le bus I2C soit libre
bsf STATUS , RP0 ; passage en banque 1
bcf STATUS , RP1 ; passage en banque 1
bsf SSPCON2 , SEN ; SEN = 1 (lancement d'une opération Start)
bcf STATUS , RP0 ; passage en banque 0
bcf STATUS , RP1 ; passage en banque 0
return
;IDLE (bus libre ?)
I2C_idle
bsf STATUS , RP0 ; passage en banque 1
bcf STATUS , RP1 ; passage en banque 1
I2C_idle0
btfsc SSPCON2 , ACKEN
goto I2C_idle0 ; le bit ACKEN n'est pas nul
btfsc SSPCON2 , RCEN
goto I2C_idle0 ; le bit RCEN n'est pas nul
btfsc SSPCON2 , PEN
goto I2C_idle0 ; le bit PEN n'est pas nul
btfsc SSPCON2 , RSEN
goto I2C_idle0 ; le bit RSEN n'est pas nul
btfsc SSPCON2 , SEN
goto I2C_idle0 ; le bit SEN n'est pas nul
btfsc SSPSTAT , R_W
goto I2C_idle0 ; le bit R_W n'est pas nul
bcf STATUS , RP0 ; passage en banque 0
bcf STATUS , RP1 ; passage en banque 0
return
;WRITE (movlw xxxx ; I2C_write)
I2C_write
call I2C_idle ; on attend que le bus I2C soit prêt
movwf SSPBUF
return
;accusé de reception slave vers master
I2C_ack_slave_to_master
call I2C_idle ; on attend que le bus I2C soit prêt
bsf STATUS , RP0 ; passage en banque 1
bcf STATUS , RP1 ; passage en banque 1
I2C_ACK_slave_to_master0
btfsc SSPCON2 , ACKSTAT
goto I2C_ACK_slave_to_master0 ; on attend la réception du bit ACK
bcf STATUS , RP0 ; passage en banque 0
bcf STATUS , RP1 ; passage en banque 0
return
;repeated start
I2C_repeated_start
call I2C_idle ; on attend que le bus I2C soit prêt
bsf STATUS , RP0 ; passage en banque 1
bcf STATUS , RP1 ; passage en banque 1
bsf SSPCON2 , RSEN ; RSEN = 1 (lancement d'une opération Repeated Start)
bcf STATUS , RP0 ; passage en banque 0
bcf STATUS , RP1 ; passage en banque 0
return
;lecture (call i2c_read ; movwf variable )
I2C_read
call I2C_idle ; on attend que le bus I2C soit prêt
bsf STATUS , RP0 ; passage en banque 1
bcf STATUS , RP1 ; passage en banque 1
bsf SSPCON2 , RCEN ; on lance la réception
I2C_read0
btfsc SSPCON2 , RCEN
goto I2C_read0 ; on attend la fin de la réception
bcf STATUS , RP0 ; passage en banque 0
bcf STATUS , RP1 ; passage en banque 0
movf SSPBUF , W
return
;accusé de reception du maitre vers esclave
I2C_ack_master_to_slave
call I2C_idle ; on attend que le bus I2C soit prêt
bsf STATUS , RP0 ; passage en banque 1
bcf STATUS , RP1 ; passage en banque 1
bcf SSPCON2 , ACKDT ; ACKDT = 0
bsf SSPCON2 , ACKEN ; ACKEN = 1 (lancement d'une opération Acknowledge)
bcf STATUS , RP0 ; passage en banque 0
bcf STATUS , RP1 ; passage en banque 0
return
;non accusé de reception
I2C_noack
call I2C_idle ; on attend que le bus I2C soit prêt
bsf STATUS , RP0 ; passage en banque 1
bcf STATUS , RP1 ; passage en banque 1
bsf SSPCON2 , ACKDT ; ACKDT = 1
bsf SSPCON2 , ACKEN ; ACKEN = 1 (lancement d'une opération Not Acknowledge)
bcf STATUS , RP0 ; passage en banque 0
bcf STATUS , RP1 ; passage en banque 0
return
;pour stopper l'esclave
I2C_stop
call I2C_idle ; on attend que le bus I2C soit prêt
bsf STATUS , RP0 ; passage en banque 1
bcf STATUS , RP1 ; passage en banque 1
bsf SSPCON2 , PEN ; PEN = 1 (lancement d'une opération Stop)
bcf STATUS , RP0 ; passage en banque 0
bcf STATUS , RP1 ; passage en banque 0
return
; ////////////////////////////////////////////////////////////////////////////
; P R O G R A M M E
; ////////////////////////////////////////////////////////////////////////////
readee
bcf STATUS,RP0 ; passer en banque2
bsf STATUS,RP1
movwf EEADR ; pointer sur adresse eeprom
bsf STATUS,RP0 ; passer en banque3
bcf EECON1,EEPGD ; pointer sur eeprom
bsf EECON1,RD ; ordre de lecture
bcf STATUS,RP0 ; passer en banque2
movf EEDATA,w ; charger valeur lue
bcf STATUS,RP1 ; passer en banque0
return
tempo5 ;49999997 cycles
movlw D'200'
movwf d3
bouc12
movlw D'210'
movwf d2
bouc11
movlw D'5'
movwf d1
bouc10
decfsz d1
goto bouc10
decfsz d2
goto bouc11
decfsz d3
goto bouc12
return
tempo
movlw 3 ; pour 2 boucles
movwf cmpt3 ; initialiser compteur3
boucle3
clrf cmpt2 ; effacer compteur2
boucle2
clrf cmpt1 ; effacer compteur1
decfsz cmpt2,f ; si 0, décrémenter compteur 2
goto boucle2 ; si cmpt2 pas 0, recommencer boucle1
decfsz cmpt3,f ; si 0, décrémenter compteur 3
goto boucle3 ; si cmpt3 pas 0, recommencer boucle2
return
tempo2
movlw 255 ; pour 2 boucles
movwf cmpt3 ; initialiser compteur3
boucle3w
clrf cmpt2 ; effacer compteur2
boucle2w
clrf cmpt1 ; effacer compteur1
decfsz cmpt2,f ; si 0, décrémenter compteur 2
goto boucle2w ; si cmpt2 pas 0, recommencer boucle1
decfsz cmpt3,f ; si 0, décrémenter compteur 3
goto boucle3w ; si cmpt3 pas 0, recommencer boucle2
return
;*****************************************************************************
; INITIALISATIONS *
;*****************************************************************************
init
; initialisation PORTS (banque 0 et 1)
; ------------------------------------
BANK0 ; sélectionner banque0
clrf PORTA ; Sorties PORTA à 0
clrf PORTB ; sorties PORTB à 0
clrf PORTC ; sorties PORTC à 0
bsf STATUS,RP0 ; passer en banque1
movlw ADCON1VAL ; PORTA en mode digital/analogique
movwf ADCON1 ; écriture dans contrôle A/D
movlw DIRPORTA ; Direction PORTA
movwf TRISA ; écriture dans registre direction
movlw DIRPORTB ; Direction PORTB
movwf TRISB ; écriture dans registre direction
movlw DIRPORTC ; Direction PORTC
movwf TRISC ; écriture dans registre direction
bsf TRISC , 3 ; broche RC3/SCK/SCL configurée en entrée
bsf TRISC , 4 ; broche RC4/SDI/SDA configurée en entrée
; initialisation 100 kHz standart
bsf SSPSTAT , SMP ; SMP = 1 : fréquence de l'horloge du bus I2C = 100 kHz
bcf SSPSTAT , CKE ; CKE = 0 : Disable SMBus specific inputs
movlw 0x31
movwf SSPADD ; (SSPADD) = (FOSC / (4*f SCL)) - 1 = 0x31
BANK0
movlw B'00101000'
movwf SSPCON
BANK1
; Registre d'options (banque 1)
; -----------------------------
movlw OPTIONVAL ; charger masque
movwf OPTION_REG ; initialiser registre option
; registres interruptions (banque 1)
; ----------------------------------
movlw INTCONVAL ; charger valeur registre interruption
movwf INTCON ; initialiser interruptions
movlw PIE1VAL ; Initialiser registre
movwf PIE1 ; interruptions périphériques 1
movlw PIE2VAL ; initialiser registre
movwf PIE2 ; interruptions périphériques 2
; Effacer RAM banque 0
; ---------------------
bcf STATUS,RP0 ; sélectionner banque 0
movlw 0x20 ; initialisation pointeur
movwf FSR ; d'adressage indirect
init1
clrf INDF ; effacer ram
incf FSR,f ; pointer sur suivant
btfss FSR,7 ; tester si fin zone atteinte (>7F)
goto init1 ; non, boucler
; autoriser interruptions (banque 0)
; ----------------------------------
clrf PIR1 ; effacer flags 1
clrf PIR2 ; effacer flags 2
bsf INTCON,GIE ; valider interruptions
goto start ; programme principal
;*****************************************************************************
; PROGRAMME PRINCIPAL *
;*****************************************************************************
start
movlw D'1'
movwf adra
movlw 0X70
movwf calcul
goto lecture
sendata
decf scdd,f ; preparation des données avant d'envoyer au ds1307
swapf scdd,w
movwf secondes
decf scdu,w
addwf secondes,f
decf mind,f
swapf mind,w
movwf minutes
decf minu,w
addwf minutes,f
call I2C_start
movlw B'11010000' ;adresse
call I2C_write
call I2C_ack_slave_to_master
movlw 0x00 ;registre secondes
call I2C_write
call I2C_ack_slave_to_master
movlw D'0' ; on remet les secondes a 0
call I2C_write
call I2C_ack_slave_to_master
movf secondes,w ;valeur des MINUTES
call I2C_write
call I2C_ack_slave_to_master
movf minutes,w ;valeur des HEURES
call I2C_write
call I2C_ack_slave_to_master
call I2C_stop
goto lecture
fonction
bcf flag1,1 ; on s'en fou
movf adra,w ; numeros du digit a regler
movwf PORTA ; allume le digit a regler
movf calcul,w ; adresse du debut de la zone variable scd,scdd,minu,mind
movwf FSR
movf INDF,w ; valeur de la variable selectionnée
call readee ; lecture de la table pour le code a envoyé au digit
movwf PORTB ; on envoie sur le portb la valeur du digit
testbp
movlw D'220'
movwf d3
bouc121
movlw D'120'
movwf d2
bouc111
movlw D'120'
movwf d1
bouc101
btfss PORTC,0 ; test bp
goto bp1b
btfss PORTC,1
goto bp2b
btfss PORTC,2
goto bp3b
decfsz d1
goto bouc101
decfsz d2
goto bouc111
decfsz d3
goto bouc121
bcf flag1,7
movlw D'1' ; on remet le numeros du digit a regler a 1 pour la prochaine fois
movwf adra
movlw 0X70 ; pareil pour l'adresse de la variable contenant la valeur du premier digit
movwf calcul
goto sendata ; pas de bp appuyé depuis 5 secondes donc on envoie les données de reglages et on repasse a l'affichage
bp1b ; bp moins
call tempo2
call tempo2
call tempo2
call tempo2
movf calcul,w ; adresse de la variable contenant la valeur du digit a regler
movwf FSR
decfsz INDF,f ; si valeur du digit a 0 on remet la valeur a 10 (decalage de 1 donc on affiche 9)
goto fonction ; pas a 0 on envoie
movf calcul,w
movwf FSR
movlw D'10' ; sinon on remet a 10 ( 10-1 9
movwf INDF
goto fonction
bp2b ; bp reglage
call tempo2
call tempo2
call tempo2
call tempo2
incf calcul,f ; on passe au digit suivant
movlw 0X74
subwf calcul, W
btfss STATUS, Z ; test si debordement 4 digits
goto bp2bs
movlw 0X70 ; debordement donc on remet a 0
movwf calcul
goto bp2bs
bp2bs
rlf adra,f ; affiche le digit suivant
btfss adra,4 ; test debordement digit
goto fonction
movlw D'1'
movwf adra
bcf flag1,7
goto sendata
bp3b ; bp plus
call tempo2
call tempo2
call tempo2
call tempo2
movf calcul,w ; adresse de la variable contenant la valeur du digit a regler
movwf FSR
incf INDF,f
movf calcul,w
movwf FSR
movlw D'11'
subwf INDF,w
btfss STATUS, Z ; test debordement chiffre dans le digit
goto fonction ; pas de debordement
movf calcul,w
movwf FSR
movlw D'1' ; debordement du chiffre arrivé a 9 donc on repasse a 1 ( 1-1 0
movwf INDF
call readee
goto fonction
lecture
call I2C_start
movlw B'11010000' ;adresse
call I2C_write
call I2C_ack_slave_to_master
movlw 0x01 ;registre minutes
call I2C_write
call I2C_ack_slave_to_master
call I2C_repeated_start
movlw B'11010001' ;adresse en lecture
call I2C_write
call I2C_ack_slave_to_master
call I2C_read
movwf secondes ; valeur des MINUTES
call I2C_ack_master_to_slave
call I2C_read
movwf minutes ; valeur des HEURES
call I2C_ack_master_to_slave
call I2C_read
movwf heures
call I2C_noack
call I2C_stop
prepa
movlw B'00001111' ; masque
andwf secondes,w
movwf scdu ; on masque les dizaines
incf scdu,f ; incremente de 1 pour le decmptage apres
movlw B'11110000' ; masque
andwf secondes,w
movwf scdd ; on masque les unitées
swapf scdd,f
incf scdd,f ; incremente de 1 pour le decmptage apres
movlw B'00001111'
andwf minutes,w
movwf minu ; on masque les dizaines
incf minu,f
movlw B'11110000'
andwf minutes,w
movwf mind ; on masque les unitées
swapf mind,f
incf mind,f
affichage
btfsc flag1,7 ; test si on appuie sur le bouton reglage
goto fonction
bcf PORTA,3 ; eteint le digit 4
bsf PORTA,0 ; allume le digit 1
movf scdu,w
call readee
movwf PORTB
call tempo
movf scdd,w
call readee
bcf PORTA,0
bsf PORTA,1
movwf PORTB
call tempo
movf minu,w
call readee
bcf PORTA,1
bsf PORTA,2
movwf PORTB
call tempo
movf mind,w
call readee
bcf PORTA,2
bsf PORTA,3
movwf PORTB
call tempo
goto lecture
END ; directive fin de programme
Goto , call pile sur pic 16f
Goto , call pile sur pic 16f
Je vois pas l'intérêt de l'interruption, à moins quelle fasse partie de l'apprentissage.
Tu peux très bien détecter l'appui du bouton de réglage dans la boucle du programme.
Y a des spécialistes des 16F ici on va voir, j'en ai pas trop l'habitude.
Pour faire avancer les choses, ça fait quoi quand ça bugge, plus d'affichage ?
Et si tu as le schéma sous la main, ça peut intéresser
Tu peux très bien détecter l'appui du bouton de réglage dans la boucle du programme.
Y a des spécialistes des 16F ici on va voir, j'en ai pas trop l'habitude.
Pour faire avancer les choses, ça fait quoi quand ça bugge, plus d'affichage ?
Et si tu as le schéma sous la main, ça peut intéresser
Retourner vers « Langage ASM »
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 123 invités