Précédent   Forum du club des développeurs et IT Pro > Environnements de développement > Autres EDI > MPLAB
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 29/05/2009, 10h02   #1
Haox85
Invité de passage
 
Inscription : mai 2009
Messages : 7
Détails du profil
Informations forums :
Inscription : mai 2009
Messages : 7
Points : 0
Points : 0
Par défaut [PIC 18F2525][Débutant] Problème d'interruption

J'ai un petit pb dans mon projet. Avant tout je tiens à dire que je suis débutant en programmation (ça fait 1 mois que j'y touche) donc soyez indulgent svp. Tout ce qui suit, a été fait en partie grâce au cours de Bigonoff (je n'ai pas tout lu non plus) que je remercie...

Je traduit en mot ce que j'ai programmé :

J'ai demandé à mon PIC de faire 8 conversions analogique/digitale et d'en faire la moyenne. Cette moyenne je veux l'afficher sur deux 7 segments. Pour l'afficher j'ai programmé un TIMER qui toutes les 20 ms renvoie à l'adresse 0x08 de l'interruption. L'interruption consiste donc à afficher la valeur tens et ones sur les deux 7 segments de façon alternative. Donc toutes les 20 ms les cadrans des dixaines et des unités s'allumeront successivement pour afficher les valeurs stockées dans ones et tens. Seulement pendant une simulation, quand je fais "watch" dans MPLAB, Le PORTB, le PORTA et TABLAT restent à 0 ce qui veut dire que mon interruption ne se met pas en route et je ne comprends pas pourquoi...

Pouvez vous m'aider?

Voilà mon code:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
LIST      p=18F2525            
 #include <p18F2525.inc>            
 
 CONFIG  OSC  = INTIO67
 CONFIG FCMEN =  OFF
 CONFIG IESO  =  OFF
 CONFIG PWRT  = OFF
 CONFIG BOREN = OFF
 CONFIG WDT  = OFF
 CONFIG MCLRE = OFF
 CONFIG LPT1OSC = OFF
 CONFIG PBADEN = OFF
 CONFIG DEBUG = ON
 
;*********************************************************************
;                                Masques             *
;                                     *
;*********************************************************************
 
MASK_ADCON0   EQU  B'00000000'  ; la conversion analogique n'est pas autorisÈe
MASK_ADCON1   EQU  B'00001110'  ; Le voltage de rÈfÈrence pour la conversion Ètant comme VSS et VDD
MASK_ADCON2   EQU  B'10001100'  ; dÈfinie la justification par la droite ou gauche
 
MASK_TRISA   EQU  B'00000011'  ; les pins 2 et 3 sont configurÈes comme des entrÈes  
           ; et 4,5,6,7,9 et 10 comme des sorties
MASK_TRISB   EQU  B'00000000'  ; Toutes les pins PORTB sont configurÈes comme des sorties  
 
MASK_TRISC   EQU  B'01000000'  ; Toutes les pins PORTC sont configurÈes en sortie sauf RC6 qui sera utilisÈ
           ; pour l'USART
 
MASK_T0CONOFF  EQU  B'00000111'  ; le timer n'est pas enclenchÈ
MASK_T0CONON  EQU  B'10000111'  ; le timer est enclenchÈ
 
 
MASK_INTCONOFF  EQU  B'00000000'  ; interdire les interruptions
MASK_INTCONON  EQU  B'10100000'  ; autorise uniquement l'interruption du timer 0
MASK_TIMER0ON  EQU  B'10000111'  ; lancer le timer
 
   
;*********************************************************************
;                            DEFINITION                           *
;*********************************************************************
 
#DEFINE bouton  PORTA,2   ; Bouton permettant de mettre sous tension
 
#DEFINE a   PORTB,0   ; Afficheur de la barre a
#DEFINE b   PORTB,1   ; Afficheur de la barre b
#DEFINE c   PORTB,2   ; Afficheur de la barre c
#DEFINE d   PORTB,3   ; Afficheur de la barre d
#DEFINE e   PORTB,4   ; Afficheur de la barre e
#DEFINE f   PORTB,5   ; Afficheur de la barre f
#DEFINE g   PORTB,6   ; Afficheur de la barre g
#DEFINE dp   PORTB,7   ; Afficheur de la barre dp
 
#DEFINE Ones  PORTC,0   ; Allume le 7 segments des unitÈs
#DEFINE Tens  PORTC,1   ; allume le 7 segments des dixaines
 
;*********************************************************************
;                            TABLE 7 segments         *
;Cette table permet le stockage d'informations concernant l'affichage*
; des 7 segments. Elle contient les adresses qui permettent d'affiher*
;tel ou tel chiffre. Les adresses suivantes sont attribuÈes    *
;respectivement ‡ 0,1,2,3,4,5,6,7,8,9,10        *
;*********************************************************************
tabl_segment EQU  0x0001000
 
 org  tabl_segment
 
 db  0x3F,0x06,0x5B,0X4F
 db  0x26,0x6D,0x7D,0x07
 db  0x7F,0x6F,0x00
 
;*********************************************************************
;                          VARIABLES                       *
;*********************************************************************
 
 CBLOCK  0x000
  cmptac  : 1    ; Temps nÈcessaire ‡ la charge du convertisseur pour l'
         ; acquisition
  cmptac50 : 1        
  cmptmoy  : 1    ; compteur permettant d'avoir 8 Èchantillons et d'en faire  
         ; la moyenne
  accumL  : 1          
  accumH  : 1
 
  moyenneL : 1    ; 8 premiers octets de la moyenne
  moyenneH : 1    ; 8 derniers octets de la moyenne
 
  ones  : 1    ; variables des unitÈs pour 7-segments
  tens  : 1    ; variables des dixaines pour 7-segments
  casel  : 1    ; permet de sÈlectionner quel cadran allumer
   
  ENDC
 
 org  0x000
 bra  init  
 
;*********************************************************************
;                            INTERRUPTION                          *
;*********************************************************************
 
   ;     AFFICHAGE      ;
   ; Cette interruption sert ‡ afficher toutes   ;
   ; les 20ms sur les cadrans 7 segments les     ;
   ; donnÈes stockÈes dans les registres ones    ;
   ; et tens           ;
   ;**********************************************
 
 org  0x008
 
 
 movlw MASK_INTCONOFF
 movwf INTCON,0
 
AFFICHAGE
 
 movlw  UPPER(tabl_segment)  ; charger bits 16 ‡ 21 de líadresse
 movwf  TBLPTRU     ; dans pointeur UPPER
 movlw  HIGH(tabl_segment)   ; charger bits 8 ‡ 15 de líadresse
 movwf  TBLPTRH     ; dans pointeur HIGH
 movlw  LOW(tabl_segment)   ; charger bits 0 ‡ 7 de líadresse
 movwf  TBLPTRL     ; dans pointeur LOW
 
 BCF  PORTC,0     ; On configure RC0 et RC1 en sortie
 BCF  PORTC,1
 
 movlw 0x01     ; on met 1 dans w
 movwf casel     ; on charge 1 dans casel
 
 cpfseq casel,0     ; comparer casel ‡ w, et sauter s'ils sont Ègaux
 
 bra  AFITENS     ; si diffÈrent alors on va afficher les dixaines
 
 movf ones,w,0    ; mettre le nombre d'unitÈ dans w
 addwf TBLPTRL,1,0    ; ajouter ones dans le pointeur de la table L
 
 tblrd *      ; lire la table ‡ l'adresse du pointeur
 
 movf TABLAT,w    ; mettre le rÈsultat de la table dans w
 movwf PORTB     ; envoyer la valeur de la table vers l'afficheur 7 segments
 
 BSF  PORTC,0,0    ; allumer uniquement le cadran des unitÈs
 
 BRA  NVCASEL     ; aller ‡ NVCASEL de faÁon ‡ sÈlectionner un nouveau cadran
 
AFITENS
 
 movlw 0x02     ; charger 2 dans w
 cpfseq casel,0     ; comparer si casel est Ègal ‡ deux
         ; si oui alors sauter l'instruction suivante
 bra  NVCASEL     ; sinon aller ‡ NVCASEL
 
 movf tens,w,0    ; charger les tens dans w
 addwf TBLPTRL,1,0    ; Ajouter les tens dans le pointeur de la table
 
 tblrd *      ; lire la table  
 
 movf TABLAT,w    ; charger la valeur de la table pointer dans w
 movwf PORTB     ; envoyer la valeur vers l'afficheur
 
 BSF  PORTC,1,0    ; allumer uniquement le cadran des dixaines
 
NVCASEL
 
 RLNCF casel,1,0    ; faire une rotation de bit vers la gauche
 movlw 0x02     ; si casel > 2 alors le remettre ‡ 1
 cpfsgt casel,0     ; si = ‡ 2 alors retourner pour afficher les dixaines
 bra  AFITENS
 
 bcf  INTCON,TMR0IF   ; enlever le flag de l'interruption
 
 movlw 0x63     ; charger w pour le timer low
 movwf TMR0L     ; charger le registre low du timer
 movlw 0xFF     ; charger w pour le timer high
 movwf TMR0H     ; charger le registre high du timer
 
 movlw MASK_INTCONON   ; Autoriser les interruptions
 movwf INTCON,0
 
 retfie FAST
 
;*********************************************************************
;                             INITIALISATION                         *
;*********************************************************************
init
 movlw MASK_ADCON1    ; ANO = entrÈe analogique. Vref = Vss et Vdd
 movwf ADCON1
 
 movlw MASK_ADCON0    ; AN0 sÈlectionnÈe, pas de conversion en cours
 movwf ADCON0
 
 movlw MASK_ADCON2    ; Justification par la droite, Acquisition time = 2Tad
 movwf ADCON2
 
 movlw MASK_TRISA    ; Configurer Pin 2 et 3 comme des entrÈes
 movwf TRISA          
 
 clrf PORTB
 movlw MASK_TRISB    ; Configurer toutes les pins PORTB comme des sorties
 movwf TRISB
 
 clrf PORTC
 movlw MASK_TRISC    ; configurer les pins 11,12,13,14,15,16,18 en sortie et 17 en entrÈe
 movwf TRISC
 
 movlw MASK_TIMER0ON   ; Lancer le timer0
 movwf T0CON,0    
 movlw 0x63     ; l'interruption aura lieu toutes les 20msec
 movwf TMR0L
 
 movlw 0xFF
 movwf TMR0H
 
 movlw MASK_INTCONON   ; autoriser les interruptions du timer
 movwf INTCON,0
 
 
 ;ATTENTION JE NE COMPRENDS PAS CE QU'A FAIT A-S
 
 
 
;*********************************************************************
;                         PROGRAMME PRINCIPALE                       *
;*********************************************************************
 
MAIN
 
 ;movlw MASK_TIMER0ON   ; Lancer le timer0
 ;movwf T0CON,0    
 ;movlw 0x63     ; l'interruption aura lieu toutes les 20msec
 ;movwf TMR0L
 
 ;movlw 0xFF
 ;movwf TMR0H
 
 ;movlw MASK_INTCONON   ; autoriser les interruptions du timer
 ;movwf INTCON,0
 
CONVERSION
 
 clrf accumL          
 clrf accumH     ; rÈinitialiser accum ‡ 0
 
 movlw MASK_INTCONOFF   ; Interdire les interruptions
 movwf INTCON,0
 bsf  ADCON0,ADON    ; autoriser la conversion analogique
 
 movlw 0xFA     ; charger le registre W ‡ 250  
 movwf cmptac     ; charger la variable cmpt1 pour obtenir un Èchantillon toutes les 25ms
 
 movlw 0x8      ; charger le w ‡ 8 pour obtenir 8 Èchantillons
 movwf cmptmoy     ; charger cmptmoy ‡ 8
 
 
 
BOUCLE
         ; toutes les 50ms prendre un Èchantillon
 movlw 0x02     ; charger 2 dans w
 movwf cmptac50            
 
BOUCLE50MS  
 
 decfsz cmptac     ; dÈcrÈmenter cmptac
 
 bra  BOUCLE50MS    ; =/ 0 boucle1
 
 bsf  ADCON0,GO_DONE   ; lancer la conversion analogique/digitale
 
 decfsz cmptac50
 bra  BOUCLE50MS
 
BOUCLECONV
 
 btfsc ADCON0,GO/DONE   ; tester si = 0 alors conversion finie
         ; une fois la conversion finie, le rÈsultat  
         ; vient se mettre dans deux registres : ADRESL et ADRESH  
 bra  BOUCLECONV    ; =/0 donc boucle2
 
 movlw 0x01     ; simuler une acquisition
 movwf ADRESL
 
 movlw 0x00     ; simuler une acquisition
 movwf ADRESH
 
;           STOCKER LES ECHANTILLONS POUR FAIRE LA MOYENNE
;*********************************************************************
 
 movf ADRESL,w    ; charger la conversion ADRESL dans registre w
 addwf accumL     ; additionner la prÈcÈdente conversion avec la valeur de add8v0  
 
 movf ADRESH,w    ; charger la conversion ADRESH dans registre w
 addwfc accumH     ; additionner  la prÈcÈdente conversion avec la valeur de add8v1
 
 
;             retour ‡ la prise d'Èchantillons
;*********************************************************************
 
BOUCLEMOY
 decfsz cmptmoy     ; dÈcrÈmenter le registre cmptmoy de 1  
 bra  BOUCLE     ; si =/ 0 alors retour ‡ BOUCLE 1
 
 
 
;              calculer la moyenne
;**********************************************************************
 
 
MOYENNE
 
 RRCF accumH     ; divise RRNCF et RRCF par 2
 RRNCF accumL        
 RRCF accumH     ; Divise encore par 2  
 RRNCF accumL
 RRCF accumH     ; divise encore par 2 donc finalement on a par 8
 RRNCF accumL
 
 
 
;                            CHIFFRES                            
;*********************************************************************
CHIFFRE
 
 clrf ones     ; Effacer "ones" et "tens"
 clrf tens
 
DIXAINE  
 
 movlw 0xA      ; Charger 10 dans w pour savoir
         ; combien de dixaine il y a dans notre moyenne
 subwf accumL,1,0    ; pour se faire, on soustrait 10 ‡ accumL et on laisse
         ; le rÈsultat dans accumL jusqu'‡ obtenir un nÈgatif
 movlw 0x0
 subwfb accumH,1,0    ; sousraire le Report de soustraction si il y en a
 
 bn  NEGATIF     ; si le rÈsultat < 0 alors N du reg status vaut 1
         ; Donc on va direct ‡ NEGATIF. Si > 0
 incf tens     ; alors on incrÈmente de 1 la variable tens
 
 BZ  FIN_CHIFFRE    ; si le rÈsultat = 0 alors plus de reste donc terminÈ
 
 bra  DIXAINE     ; Si le rÈsultat est possitif alors on recommence.
 
NEGATIF
 
 movlw 0xA      ; on rajoute les 10 dans accumL pour retrouver un chiffre positif
 addwf accumL,1,0    ; et les passer dans la variable ones
 
UNITE
 
 movff accumL,ones
 
FIN_CHIFFRE
 
 
 bra  MAIN
 END
Haox85 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/05/2009, 10h39   #2
Leonhart
Membre confirmé
 
Avatar de Leonhart
 
Inscription : mai 2009
Messages : 262
Détails du profil
Informations personnelles :
Âge : 25

Informations forums :
Inscription : mai 2009
Messages : 262
Points : 298
Points : 298
Simple remarque à titre informative : "Pourquoi utiliser MPLAB et son language complexe (mais puissant certes) alors qu'on peut utiliser PICC (Compilateur CCS) et tout faire dans un C des plus basique ?"

Le tout sachant qu'il suffit d'un export via MPLAB pour reprendre le .HEX et le balancer dans le PIC via ICD2 ...



Pour ton problème, as-tu activer les registres du PIC indiquant que les Entrées/sorties qui t'intéressent sont des intérruptions ou des convertisseur A-N ? Si tu ne l'as pas fait, elles sont par défaut considérés comme des I/O standard.

De plus, il faut un timer de minimum 50ms entre chaque convertion pour laisser le temps au multiplexeur de passer d'une ligne à l'autre (car le PIC n'a en réalité qu'un seul convertisseur).
Leonhart est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/05/2009, 10h53   #3
Haox85
Invité de passage
 
Inscription : mai 2009
Messages : 7
Détails du profil
Informations forums :
Inscription : mai 2009
Messages : 7
Points : 0
Points : 0
Mon interruption est une interruption du timer0
Je fais juste un décompte du timer0 de 20ms, une fois le timer dépassé, l'interruption se met en route. Donc aucune incidence des pins sur l'interruption. J'ai néanmoins configuré mes pins de la façon dont je le souhaitais.

Pour ce qui est des 50 ms entre chaque conversion c'est exactement ce que j'ai laissé. mon PIC doit faire 1 conversion toutes les 50 ms et huit fois de suite ce qui donne 400ms de conversion.

Donc ces 400ms seront entrecoupées toutes les 20 ms de l'interruption affichage.

Mais... Mon interruption ne fonctionne toujours pas.... :'(

Je ne trouve pas ce que j'ai mal fait
Haox85 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/05/2009, 11h02   #4
Leonhart
Membre confirmé
 
Avatar de Leonhart
 
Inscription : mai 2009
Messages : 262
Détails du profil
Informations personnelles :
Âge : 25

Informations forums :
Inscription : mai 2009
Messages : 262
Points : 298
Points : 298
Question bete mais, es-tu sur de tes branchements ?
Un problème sur l'Oscilloscope et tout ton programme déconne.
Mais je vais partir du principe que tu as déja transformé ta carte en guirlande de Led clignotante

Sinon, à combien est cadencé ton PIC, ton Timer0 ?
Es-tu sur qu'il tick quand tu le souhaite vraiment ?
Leonhart est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/05/2009, 11h36   #5
Haox85
Invité de passage
 
Inscription : mai 2009
Messages : 7
Détails du profil
Informations forums :
Inscription : mai 2009
Messages : 7
Points : 0
Points : 0
Je n'ai fait aucun branchement encore ce n'est que de la simulation.
Donc pour le moment je me fiche de la cadence du PIC et du timer0

Je veux juste que mes registres se chargent en simulation...

Une fois que mes registres se chargeront, je me préoccuperai de la cadence.

Mais vraiment je sèche...
Haox85 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/05/2009, 13h14   #6
Leonhart
Membre confirmé
 
Avatar de Leonhart
 
Inscription : mai 2009
Messages : 262
Détails du profil
Informations personnelles :
Âge : 25

Informations forums :
Inscription : mai 2009
Messages : 262
Points : 298
Points : 298
Citation:
Envoyé par Haox85 Voir le message
Je n'ai fait aucun branchement encore ce n'est que de la simulation.
Quel logiciel de simulation utilises-tu ?
Je sais que la suite Proteus as du mal avec la simulation et que les résultats ainsi obtenus peuvent etre faux ou absents.

Si, tu simules avec MPLAB, as-tu spécifié la bonne cadence (HS, XT, etc...) ou le bon PIC à utiliser ? Ensuite utilise le débugger pour faire du pas à pas dans ton programme, tu veras quelles instructions ne marchent pas !

PS : si tu veut, tente d'écrire le programme en C via le log PICC. Tu gagneras énormement de temps ET ça sera plus facilement débuggable !
Leonhart est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/05/2009, 13h41   #7
Haox85
Invité de passage
 
Inscription : mai 2009
Messages : 7
Détails du profil
Informations forums :
Inscription : mai 2009
Messages : 7
Points : 0
Points : 0
Oui j'ai spéficié le bon PIC...

En fait j'utilise le Debugger, mais dans mon appli, l'interruption ne se met pas en route

Tout tourne en boucle normalement, sauf qu'aucune interruption n'arrive donc le PORT B et C reste à 0. De ce fait aucun affichage n'est possible...
Haox85 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/05/2009, 10h12   #8
Haox85
Invité de passage
 
Inscription : mai 2009
Messages : 7
Détails du profil
Informations forums :
Inscription : mai 2009
Messages : 7
Points : 0
Points : 0
PB résolu, le délai du timer0 était tellement grand que mon interruption ne se déroulait pas... le simulateur n'était pas assez rapide...

Merci de votre aide

PS: Si quelqu'un sait comment faire varier une fréquence en fonction de la tension analysée dans le but de faire varier la fréquence d'un haut parleur, je ne dis pas non
Haox85 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 20h58.


 
 
 
 
Partenaires

Hébergement Web