Précédent   Forum du club des développeurs et IT Pro > Autres langages > Assembleur > Autres architectures
Autres architectures Toutes les autres architectures (PIC, MIPS, ARM, 68K, Z80...) et leurs outils
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 02/08/2012, 18h04   #1
Phiiinou
Invité de passage
 
Femme
Étudiant
Inscription : août 2012
Messages : 5
Détails du profil
Informations personnelles :
Sexe : Femme
Localisation : France

Informations professionnelles :
Activité : Étudiant
Secteur : High Tech - Électronique et micro-électronique

Informations forums :
Inscription : août 2012
Messages : 5
Points : 1
Points : 1
Par défaut [PIC12F508] Chien de garde en assembleur

Bonjour,

Avant tout, desolee pour les accents manquants, je suis sur qwerty.
J'espere que ca ne rendra pas la lecture trop penible.

Mon projet est un chien de garde a implementer en assembleur.
Le microcontroleur est un PIC12F508, horloge 4MHz (cycles de 1us).
1 seul timer (TMR0). Pas de registre dedie aux interruptions.
Le seul projet que j'aie fait sur PIC utilisait un 18f que je programmais en C.
J'ai donc quelques questions relatives au code en assembleur. J'utilise MPLAB v8.86.

Voila l'idee:
Un dispositif maitre envoie un creneau "classique" (rapport cyclique 1/2) de periode 1 min pour signaler qu'il est en bonne sante. Le chien de garde doit detecter un arret du creneau (qui peut rester a l'etat haut ou bas), generer sur la ligne d'alimentation une coupure d'environ 150 ms puis la remettre a 1 et attendre 5 min avant une nouvelle interrogation (pour laisser le temps au dispositif maitre de rebooter).

(Pour info, mais ce n'est pas l'objet du post car ca ne pose pas de souci, un flag doit egalement etre mis a 1 avant de demarrer la procedure de coupure d'alim. Ce flag doit etre remis a zero durant les 5 min suite a un changement de bit sur un port d'entree mais une interrogation toutes les minutes est suffisante, cette partie ne me pose pas de difficulte).

Pour le polling sur le creneau du dispositif maitre, j'ai pense a lire la valeur a un instant t, attendre 31 sec, lire a nouveau la valeur et faire un XOR (ou exclusif) entre les 2. Si le XOR vaut 1, tout va bien et je reboucle pour interroger a nouveau. Si le XOR vaut zero, cela signifie que le creneau est arrete, et dans ce cas je lance la procedure de reboot. J'utilise le zero flag du registre STATUS pour le test.

1) Mon code (je n'ai pas encore ecrit les tempos) compile. D'apres la methode evoquee ci-dessus, ya-t-il un risque de mauvais fonctionnement in situ?

2) De nombreuses tempos sont necessaires dans le programme, la plupart sont multiples d'1 sec, je compte donc ecrire une tempo 1 sec en utilisant le timer0 et faire des call dans le programme principal. Dois-je ecrire le sous programme "Tempo 1s" apres le END ? Sinon, comment proceder?

3) Si quelqu'un possede deja un code pour une tempo 1 sec avec des cycles de 1us, je suis preneuse je pense que le prescaler est a zero par defaut.

Merci d'avance pour vos conseils (toute suggestion est la bienvenue) et eventuelles explications!
Phiiinou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/08/2012, 13h23   #2
Obsidian
Modérateur
 
Avatar de Obsidian
 
Homme
Chercheur d'emploi
Inscription : septembre 2007
Messages : 4 612
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 36
Localisation : France, Essonne (Île de France)

Informations professionnelles :
Activité : Chercheur d'emploi
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : septembre 2007
Messages : 4 612
Points : 11 082
Points : 11 082
Hello,

Citation:
Envoyé par Phiiinou Voir le message
Pour le polling sur le creneau du dispositif maitre, j'ai pense a lire la valeur a un instant t, attendre 31 sec, lire a nouveau la valeur
Non, tu ne peux pas procéder ainsi puisque si l'état change entretemps, tu ne pourras pas le détecter. Tu es alors obligée de te fier au fait que l'émetteur va t'envoyer un signal parfaitement carré et que le nouvel état sera maintenu jusqu'à ce que tu daignes le lire.

Ce qu'il faut, c'est faire une boucle qui lit l'entrée en permanence et qui n'en sort que lorsque l'entrée varie ou que la fin du laps de temps est atteinte.

Citation:
3) Si quelqu'un possede deja un code pour une tempo 1 sec avec des cycles de 1us, je suis preneuse
Ce n'est pas bien difficile : 1 seconde (s), c'est exactement un million de micro-secondes (µs). Sur un PIC12x508, comme sur la plupart de ses frères et sœurs, une instruction dure exactement un cycle ! Tu n'as donc qu'à compter tes instructions, boucles et sauts compris, et choisir un nombre de tours qui, lorsque tu les cumules, amène au plus proche du million d'instruction exécutées.
Obsidian est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/08/2012, 18h20   #3
Phiiinou
Invité de passage
 
Femme
Étudiant
Inscription : août 2012
Messages : 5
Détails du profil
Informations personnelles :
Sexe : Femme
Localisation : France

Informations professionnelles :
Activité : Étudiant
Secteur : High Tech - Électronique et micro-électronique

Informations forums :
Inscription : août 2012
Messages : 5
Points : 1
Points : 1
Merci pour ta reponse,

J'ai implemente les boucles et teste, elles fonctionnent.

Je crois que vois ce que tu veux dire pour le polling.
Je souhaite justement rester dans la boucle d'interrogation lorsque l'emetteur envoie un creneau de periode une minute, car c'est la situation normale.
L'emetteur dans l'application finale est precis et envoie des 1 et 0 nets.
J'ai reduit le temps d'interrogation a 30 sec.
Penses-tu qu'il y aura tout de meme un probleme?
Voila le bout de code correspondant:

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
;*************polling on Pulse (from CPU)
 
MAIN_LOOP
 
	movf GP2, 0 ; reading CPU pulse, result in working register w
	movwf GP3   ; saving first value in GP3
 
	; TEMPO 30 SEC 
	movlw .60
	movwf dc4
delay4
	call TEMPO_500mS
	decfsz dc4, f
	goto delay4
	; END TEMPO 30 SEC
 
	movf GP3, 0  ; restore first value in working register w
	xorwf GP2, 0  ; w xor GP2, result in working register w
	btfss Z, 0		; testing zero flag (status register).
	goto MAIN_LOOP	 ; zero flag = 0, no problem
 
;************reset
 
	bsf GPIO, 0	 ; FLAG 	
	bcf GPIO, 1	 ; POWER LINE (turns off)
	call TEMPO_500mS    ; time to reset
	bsf GPIO, 1	 ; POWER LINE (reboots)
Mon souci actuel est que je ne peux pas tester mon programme en situation, a cause d'un probleme de calibration.
Le message qui apparait a la connexion du picKit est le suivant :
Code :
"The target has invalid calibration data (6)"
J'ai cherche sur le net, apparemment cela peut etre un pb de configuration OSCCAL. C'est curieux car j'ai utilise une copie du template pic12f508 fourni par microchip qui contient toutes les premieres lignes de config necessaires. Et hier, je n'avais pas de probleme pour charger dans le PIC les programmes de tests des boucles avec des LEDS.
Phiiinou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/08/2012, 19h28   #4
Obsidian
Modérateur
 
Avatar de Obsidian
 
Homme
Chercheur d'emploi
Inscription : septembre 2007
Messages : 4 612
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 36
Localisation : France, Essonne (Île de France)

Informations professionnelles :
Activité : Chercheur d'emploi
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : septembre 2007
Messages : 4 612
Points : 11 082
Points : 11 082
Pour le problème de calibration, il faudrait que je cherche un peu.

Pour les temporisations et le polling, ne te focalises pas sur « CALL TEMPO_500mS ». Essaie plutôt d'écrire ta propre routine de temporisation, à l'intérieur de laquelle tu surveilleras la ligne. Ça te permettra de scruter un changement tous les quatre ou cinq millisecondes pendant la durée de ton choix.

Tout changement d'état à l'intérieur de ce laps de temps sera considéré comme de l'activité de la part de la machine surveillée et réinitialisera la boucle. Si, au contraire, tu atteins la fin de la boucle, c'est qu'il ne s'est rien passé durant ce laps et qu'il faut donc relancer la machine.

Il est important de procéder ainsi car il faut absolument mesurer le temps écoulé depuis la dernière activité connue de ta machine.

Si tu te contentes de faire des contrôles à heure fixe en te basant sur le principe que la machine surveillée change d'état à la même fréquence, alors tes deux systèmes vont commencer à se désynchroniser doucement avec le temps, spécialement si la machine surveillée connaît des retards occasionnels. Au bout d'un moment, les contrôles vont coïncider exactement avec les changements d'états, ce qui donnera un comportement indéterminé, et si la machine a un tout petit de retard, ce sera suffisant pour que tu lises deux fois la même valeur et que tu la fasses rebooter de manière injustifiée.
Obsidian est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/08/2012, 20h03   #5
Phiiinou
Invité de passage
 
Femme
Étudiant
Inscription : août 2012
Messages : 5
Détails du profil
Informations personnelles :
Sexe : Femme
Localisation : France

Informations professionnelles :
Activité : Étudiant
Secteur : High Tech - Électronique et micro-électronique

Informations forums :
Inscription : août 2012
Messages : 5
Points : 1
Points : 1
Ok, merci, c'est beaucoup plus clair.
J'ai maintenant integre l'interrogation dans la boucle, et je reinitialise a chaque pulsation detectee.

Pour la calibration, j'ai re verifie tous les parametres de config (reset vector, osc,...), j'ai bien mis la directive CODE 0x00, etc. Sans succes.
Cela peut venir du circuit (j'utilise une demo board "artisanale", qui n'a pas de fonction "master clear" integree pour faire un reset avec les parametres factory)
Phiiinou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/08/2012, 23h46   #6
Phiiinou
Invité de passage
 
Femme
Étudiant
Inscription : août 2012
Messages : 5
Détails du profil
Informations personnelles :
Sexe : Femme
Localisation : France

Informations professionnelles :
Activité : Étudiant
Secteur : High Tech - Électronique et micro-électronique

Informations forums :
Inscription : août 2012
Messages : 5
Points : 1
Points : 1
J'ai change le PIC et je n'ai plus de probleme de calibration.
Compilation ok mais le programme ne fonctionne pas, par contre.
Voila le code complet, au cas ou quelqu'un a le temps d'y jeter un oeil...
Merci d'avance.
KICK DOG = signal creneau en provenance de la machine, periode 1 min.

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
 
 
; Notes:  GP2 = KICK DOG                                           
;            GP4 = WD ENABLE                                          
;            GP1 = PWR ENABLE                                         
;            GP0 = WD FLAG                                            
;            GP5 = WD TRIGGER CLR (to clear the flag)                 
;**********************************************************************
 
    list      p=12F508            ; list directive to define processor
    #include <p12F508.inc>        ; processor specific variable definitions
 
    __CONFIG   _MCLRE_ON & _CP_OFF & _WDT_OFF & _IntRC_OSC
 
; '__CONFIG' directive is used to embed configuration word within .asm file.
; The lables following the directive are located in the respective .inc file. 
; See respective data sheet for additional information on configuration word.
 
;***** VARIABLE DEFINITIONS
TEMP_VAR    UDATA
dc1         RES     1             ; delay loop counter
dc2         RES     1             ; delay loop counter
dc3         RES     1             ; delay loop counter
dc4         RES     1             ; delay loop counter
dc5         RES     1             ; delay loop counter
dc6         RES     1             ; delay loop counter
dc7         RES     1             ; delay loop counter
VAL         RES     1             ; storage
 
;**********************************************************************
RESET_VECTOR    CODE   0x1FF      ; processor reset vector
 
; Internal RC calibration value is placed at location 0x1FF by Microchip
; as a movlw k, where the k is a literal value.
 
MAIN    CODE    0x000
    	movwf   OSCCAL            ; factory cal value 
 
TEMPO_500mS
 
			movlw .244
			movwf dc2
			clrf dc1
delay1		nop
			decfsz dc1,f
			goto delay1
delay2		nop
			decfsz dc1,f
			goto delay2
			decfsz dc2,f
			goto delay1
 
TEMPO_250mS
 
			movlw .122
			movwf dc2
			clrf dc1
dly1		nop
			decfsz dc1,f
			goto dly1
dly2		nop
			decfsz dc1,f
			goto dly2
			decfsz dc2,f
			goto dly1
 
 
;**************initialization
start  
 
    movlw   b'11101100'       ; GP2 and GP5:INPUTS GP4,GP1 and GP0: OUTPUTS
    tris GPIO              
	bsf GPIO,4 				  ; enables WD
	bsf GPIO,1				  ; POWER 
    bcf GPIO,0				  ; FLAG = 0
 
    ; TEMPO 5 MIN 
	movlw .4
	movwf dc7
delay7
    movlw .119
	movwf dc6
delay6
	call TEMPO_500mS
	decfsz dc6, f
	goto delay6
	decfsz dc7, f
	goto delay7
	; END TEMPO 5 MIN
 
 
;*************polling on Pulse (KICK DOG, from CPU)
 
MAIN_LOOP
 
	movlw .119
	movwf dc4
delay4
	movf GP2, 0				  ; reading KICK DOG, result in working register w			  
	movwf VAL				  ; saving first KICK DOG value in VAL
	call TEMPO_250mS
	movf VAL, 0			      ; restores first KICK DOG value in working register w
	xorwf GP2, 0			  ; w xor GP2, result in working register w
	btfss Z, 0				  ; testing zero flag (status register).
	goto MAIN_LOOP			  ; zero flag = 0 => heartbeat detected
	decfsz dc4, f			  ; zero flag = 1 => nothing happened
	goto delay4
 
;************reset
 
	bsf GPIO, 0			      ; FLAG 	
	bcf GPIO, 1				  ; POWER LINE (turns off)
	call TEMPO_500mS		  ; time to reset
	bsf GPIO, 1				  ; POWER LINE (reboots)
 
;***********polling on Trigger (flag removal authorization)
 
SECOND_LOOP
 
	movlw .4			      ; need to go through the loop 5 times
	movwf dc3
 
delay3 
 
	; TEMPO 1 MIN+POLLING ON TRIGGER  
	movlw .239
	movwf dc5
delay5
	call TEMPO_250mS
	btfss GPIO, 5			  ; testing WD Trigger CLR (0=> FLAG must be removed)
	bcf GPIO, 0				  ; FLAG = 0
	decfsz dc5, f
	goto delay5
	; END TEMPO 1 MIN
 
	decfsz dc3, f			  ; loop over? (dec dc2, skip if zero)
	goto delay3
	goto MAIN_LOOP			  ; repeats polling on pulse (KICK DOG, from CPU)
 
    END
Phiiinou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/08/2012, 01h14   #7
Phiiinou
Invité de passage
 
Femme
Étudiant
Inscription : août 2012
Messages : 5
Détails du profil
Informations personnelles :
Sexe : Femme
Localisation : France

Informations professionnelles :
Activité : Étudiant
Secteur : High Tech - Électronique et micro-électronique

Informations forums :
Inscription : août 2012
Messages : 5
Points : 1
Points : 1
Re,

Aaah, ca y est, ca fonctionne !
Les principaux problemes que j'ai rencontres :

- GP2=timer a la mise sous tension. Etrange configuration par defaut!! Il faut le savoir et reconfigurer ce port en entree/sortie, via le bit 5 du registre OPTION (qui ne figure pas dans le register file map de la datasheet, il fallait chercher dans le detail des registres speciaux).

- oubli de return dans les subroutines et oubli de "goto start" avant.

- operations 8 bits pour finalement tester un resultat sur un seul bit... Et donc confusion en raison des bits indetermines. Resolu avec un "et" entre le mot et un "1" bien place, voir MAIN_LOOP, delay4.


Voila le code, on ne sait jamais, si ca peut aider quelqu'un un jour...

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
    list      p=12F508            ; list directive to define processor
    #include <p12F508.inc>        ; processor specific variable definitions
 
    __CONFIG   _MCLRE_ON & _CP_OFF & _WDT_OFF & _IntRC_OSC
 
; '__CONFIG' directive is used to embed configuration word within .asm file.
; The lables following the directive are located in the respective .inc file. 
; See respective data sheet for additional information on configuration word.
 
;***** VARIABLE DEFINITIONS
TEMP_VAR    UDATA
dc1         RES     1             ; delay loop counter
dc2         RES     1             ; delay loop counter
dc3         RES     1             ; delay loop counter
dc4         RES     1             ; delay loop counter
dc5         RES     1             ; delay loop counter
dc6         RES     1             ; delay loop counter
dc7         RES     1             ; delay loop counter
VAL         RES     1            ; storage
 
;**********************************************************************
RESET_VECTOR    CODE   0x1FF      ; processor reset vector
 
; Internal RC calibration value is placed at location 0x1FF by Microchip
; as a movlw k, where the k is a literal value.
 
MAIN    CODE    0x000
    	movwf   OSCCAL            ; factory cal value 
	goto start
 
TEMPO_500mS
 
			movlw .244
			movwf dc2
			clrf dc1
delay1		nop
			decfsz dc1,f
			goto delay1
delay2		nop
			decfsz dc1,f
			goto delay2
			decfsz dc2,f
			goto delay1
			return
 
TEMPO_250mS
 
			movlw .122
			movwf dc2
			clrf dc1
dly1		nop
			decfsz dc1,f
			goto dly1
dly2		nop
			decfsz dc1,f
			goto dly2
			decfsz dc2,f
			goto dly1
			return
 
 
;**************initialization
start  
    movlw 0xdf
	option                    
    movlw   b'11101100'       ; GP2 and GP5:INPUTS GP4,GP1 and GP0: OUTPUTS
    tris GPIO              
	bsf GPIO,4 				  ; enables WD
	bsf GPIO,1				  ; POWER 
    bcf GPIO,0				  ; FLAG = 0
 
    ; TEMPO 5 MIN 
	movlw .1
	movwf dc7
delay7
    movlw .119
	movwf dc6
delay6
	call TEMPO_500mS
	decfsz dc6, f
	goto delay6
	decfsz dc7, f
	goto delay7
	; END TEMPO 5 MIN
 
 
;*************polling on Pulse (KICK DOG, from CPU)
 
MAIN_LOOP
 
	movlw .119
	movwf dc4
delay4
	movf GPIO, 0			  ; reading KICK DOG, result in working register w	
	andlw 0x04		  
	movwf VAL				  ; saving first KICK DOG value in VAL
	call TEMPO_250mS
	andlw 0x04
	xorwf VAL, 0			  ; w xor GP2, result in working register w
	btfss STATUS, 2	   		  ; testing zero flag (status register).
	goto MAIN_LOOP			  ; zero flag = 0 => heartbeat detected
	decfsz dc4, f			  ; zero flag = 1 => nothing happened
	goto delay4
 
;************reset
 
	bsf GPIO, 0			      ; FLAG 	
	bcf GPIO, 1				  ; POWER LINE (turns off)
	call TEMPO_500mS		  ; time to reset
	bsf GPIO, 1				  ; POWER LINE (reboots)
 
;***********polling on Trigger (flag removal authorization)
 
SECOND_LOOP
 
	movlw .4			      ; need to go through the loop 5 times
	movwf dc3
 
delay3 
 
	; TEMPO 1 MIN+POLLING ON TRIGGER  
	movlw .239
	movwf dc5
delay5
	call TEMPO_250mS
	btfss GPIO, 5			  ; testing WD Trigger CLR (0=> FLAG must be removed)
	bcf GPIO, 0				  ; FLAG = 0
	decfsz dc5, f
	goto delay5
	; END TEMPO 1 MIN
 
	decfsz dc3, f			  ; loop over? (dec dc2, skip if zero)
	goto delay3
	goto MAIN_LOOP			  ; repeats polling on pulse (KICK DOG, from CPU)
 
    END
Phiiinou est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 11h54.


 
 
 
 
Partenaires

Hébergement Web