bonjour à tous, abordons la programmation pratique des micro-contrôleurs pic.



ces petits composants sont très simples et abordables.

avec un minimum de compétences en électronique et en assembleur, il est possible à moindre frais de programmer des PICs.

la liaison ICSP (in circuit serial programming) est là pour ça.

cette liaison est constituée de 5 signaux, VDD, VSS, VPP, PGC et PGD.
VDD fait 5volts par rapport à VSS (qui est en fait GND).
VPP fait entre 5 et 13 volts, selon que le pic supporte ou non la programmation haute tension (13v).

PGC et PGD sont la liaison serie qui permet au pic et au PC de communiquer.

C pour clock (horloge), D pour data (données).

le principe est de communiquer par une interface reconnue, et deja supportée par les divers logiciels de programmation de microcontroleurs, comme icprog ou winpic, ou autre...

le choix se porte sur jdm programmer.

ce circuit necessite peu de composants, et fonctionne, mais bon, il faut des transistors, tout ça, c'est long à souder, et ça prend de la place. impossible à faire tenir dans un dé à coudre.

et là, magie, sur internet, il y a une version ameliorée du jdm programmer, nommée RCD, et utilisant vraiment très peu de composants.
trois fois rien.



j'utilise celui là, il fonctionne à merveille.

il existe une version encore plus simple, sans condensateur ni diode, car il utilise les diodes internes aux pics... 4 résistances, une par tension, sauf gnd en direct... mais cette solution ne me plait guerre, j'ai pas confiance, et comment permettre le contrôle de vpp et vcc avec cette méthode?

donc, solution RCD, oublier le montage JDM original qui est trop couteux et difficile à câbler.

il faut tester la liaison, arriver à programmer le pic de sorte qu'il fonctionne avec un code trouvé sur internet.

ça marche, la led clignote.

il reste donc à désassembler le programme pour obtenir les instructions, c'est sur cette base qu'il va falloir générer les opcodes qu'il faut, si le fichier compilé donne le même résultat que le fichier d'origine, on à tout bon.

et ça donne ça:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
 
format binary as 'pic'
;PIC 14bits instruction set
;
;ADDWF   f, d    Add W and f                     1       00 0111 dfff ffff  C,DC,Z
;ANDWF   f, d    AND W with f                    1       00 0101 dfff ffff  Z
;CLRF    f       Clear f                         1       00 0001 1fff ffff  Z
;CLRW    -       Clear W                         1       00 0001 0xxx xxxx  Z
;COMF    f, d    Complement f                    1       00 1001 dfff ffff  Z
;DECF    f, d    Decrement f                     1       00 0011 dfff ffff  Z
;DECFSZ  f, d    Decrement f, Skip if 0          1(2)    00 1011 dfff ffff
;INCF    f, d    Increment f                     1       00 1010 dfff ffff  Z
;INCFSZ  f, d    Increment f, Skip if 0          1(2)    00 1111 dfff ffff
;IORWF   f, d    Inclusive OR W with f           1       00 0100 dfff ffff  Z
;MOVF    f, d    Move f                          1       00 1000 dfff ffff  Z
;MOVWF   f       Move W to f                     1       00 0000 1fff ffff
;NOP     -       No Operation                    1       00 0000 0xx0 0000
;RLF     f, d    Rotate Left f through Carry     1       00 1101 dfff ffff  C
;RRF     f, d    Rotate Right f through Carry    1       00 1100 dfff ffff  C
;SUBWF   f, d    Subtract W from f               1       00 0010 dfff ffff  C,DC,Z
;SWAPF   f, d    Swap nibbles in f               1       00 1110 dfff ffff
;XORWF   f, d    Exclusive OR W with f           1       00 0110 dfff ffff  Z
;
;
;BCF     f, b    Bit Clear f                     1       01 00bb bfff ffff
;BSF     f, b    Bit Set f                       1       01 01bb bfff ffff
;BTFSC   f, b    Bit Test f, Skip if Clear       1 (2)   01 10bb bfff ffff
;BTFSS   f, b    Bit Test f, Skip if Set         1 (2)   01 11bb bfff ffff
;
;
;ADDLW   k       Add literal and W               1       11 111x kkkk kkkk  C,DC,Z
;ANDLW   k       AND literal with W              1       11 1001 kkkk kkkk  Z
;CALL    a       Call subroutine                 2       10 0aaa aaaa aaaa
;CLRWDT  -       Clear Watchdog Timer            1       00 0000 0110 0100  TO,PD
;GOTO    a       Go to address                   2       10 1aaa aaaa aaaa
;IORLW   k       Inclusive OR literal with W     1       11 1000 kkkk kkkk  Z
;MOVLW   k       Move literal to W               1       11 00xx kkkk kkkk
;RETFIE  -       Return from interrupt           2       00 0000 0000 1001
;RETLW   k       Return with literal in W        2       11 01xx kkkk kkkk
;RETURN  -       Return from Subroutine          2       00 0000 0000 1000
;SLEEP   -       Go into Standby mode            1       00 0000 0110 0011  TO,PD
;SUBLW   k       Subtract W from literal         1       11 110x kkkk kkkk  C,DC,Z
;XORLW   k       Exclusive OR literal with W     1       11 1010 kkkk kkkk  Z
; f = register adress, 7 bits
; d = destination, 1=reg, 0=W, 1 bit
; b = bit adress, 3 bits
; k = immediate value, 8 bits
; a = code adress, 11 bits
 
REG=1
W=0
 
INDF    equ 00h
TMR0    equ 01h
PCL     equ 02h
STATUS  equ 03h
rp0     equ 5
c       equ 0
dc      equ 1
z       equ 2
FSR     equ 04h
GPIO    equ 05h
PORTA   equ GPIO
PORTB   equ 06h
EEDATA  equ 08h
EEADR   equ 09h
PCLATH  equ 0ah
INTCON  equ 0bh
PIR1    equ 0ch
TMR1L   equ 0eh
TMR1H   equ 0fh
T1CON   equ 10h
CMCON   equ 19h
ADRESH  equ 1eh
ADCON0  equ 1fh
al      equ 20h
ah      equ 21h
bl      equ 22h
bh      equ 23h
cl      equ 24h
ch      equ 25h
dl      equ 26h
dh      equ 27h
r1      equ 28h
r2      equ 29h
r3      equ 2Ah
r4      equ 2Bh
r5      equ 2Ch
r6      equ 2Dh
r7      equ 2Eh
r8      equ 2Fh
 
 
INDF1   equ 80h
OPTION  equ 81h
PCL     equ 82h
STATUS  equ 83h
FSR     equ 84h
TRISIO  equ 85h
input   equ 1
output  equ 0
PCLATH  equ 8ah
INTCON  equ 8bh
PIE1    equ 8ch
PCON    equ 8eh
OSCCAL  equ 90h
WPU     equ 95h
IOC     equ 96h
VRCON   equ 99h
EEDATA  equ 9ah
EEADR   equ 9bh
EECON1  equ 9ch
EECON21 equ 9dh
ADRESL  equ 9eh
ANSEL   equ 9fh
 
;used to reverse bytes
macro dw value          {db (((value and 3f00h ) shr 8) and 0ffh),(value and 0ffh)}
;used to align code
macro calign n          {align n*2}
;register operation
macro addwf f,d         {dw 0700h or (f and 7fh) or ((d and 1 )shl 7)}
macro andwf f,d         {dw 0500h or (f and 7fh) or ((d and 1 )shl 7)}
macro clrf f            {dw 0180h or (f and 7fh)}
macro clrw              {dw 0100h}
macro comf f,d          {dw 0900h or (f and 7fh) or ((d and 1 )shl 7)}
macro decf f,d          {dw 0300h or (f and 7fh) or ((d and 1 )shl 7)}
macro decfsz f,d        {dw 0b00h or (f and 7fh) or ((d and 1 )shl 7)}
macro incf f,d          {dw 0a00h or (f and 7fh) or ((d and 1 )shl 7)}
macro incfsz f,d        {dw 0f00h or (f and 7fh) or ((d and 1 )shl 7)}
macro iorwf f,d         {dw 0400h or (f and 7fh) or ((d and 1 )shl 7)}
macro movf f,d          {dw 0800h or (f and 7fh) or ((d and 1 )shl 7)}
macro movwf f           {dw 0080h or (f and 7fh)}
macro nop               {dw 0000h} ;20h, 40h, 60h
macro rlf f,d           {dw 0d00h or (f and 7fh) or ((d and 1 )shl 7)}
macro rrf f,d           {dw 0c00h or (f and 7fh) or ((d and 1 )shl 7)}
macro subwf f,d         {dw 0200h or (f and 7fh) or ((d and 1 )shl 7)}
macro swapf f,d         {dw 0e00h or (f and 7fh) or ((d and 1 )shl 7)}
macro xorwf f,d         {dw 0600h or (f and 7fh) or ((d and 1 )shl 7)}
;bit operations
macro bcf f,b           {dw 1000h or (f and 7fh) or ((b and 7 )shl 7)}
macro bsf f,b           {dw 1400h or (f and 7fh) or ((b and 7 )shl 7)}
macro btfsc f,b         {dw 1800h or (f and 7fh) or ((b and 7 )shl 7)}
macro btfss f,b         {dw 1c00h or (f and 7fh) or ((b and 7 )shl 7)}
;literal operation
macro addlw k           {dw 3e00h or (k and 0ffh)}
macro andlw k           {dw 3900h or (k and 0ffh)}
macro call a            {dw 2000h or ((a/2) and 7ffh)}
macro clrwdt            {dw 0064h}
macro goto a            {dw 2800h or ((a/2) and 7FFh)}
macro iorlw k           {dw 3800h or (k and 0ffh)}
macro movlw k           {dw 3000h or (k and 0ffh)}
macro retfie            {dw 0009h}
macro retlw k           {dw 3400h or (k and 0ffh)}
macro return            {dw 0008h}
macro sleep             {dw 0063h}
macro sublw k           {dw 3c00h or (k and 0ffh)}
macro xorlw k           {dw 3a00h or (k and 0ffh)}
macro null              {dw 3fffh}
;undocumented:::
macro option            {dw 0062h}
macro tris r            {dw 0060h or (r and 7)} ;r={1,5,6,7}
 
;macro NOP               {dw 0000h} ;20h, 40h, 60h
;macro RETURN            {dw 0008h}
;macro RETFIE            {dw 0009h}
;macro TRIS r            {dw 0060h or (r and 7)} ;r={1,5,6,7}
;macro OPTION            {dw 0062h}
;macro SLEEP             {dw 0063h}
;macro CLRWDT            {dw 0064h}
;macro MOVWF f           {dw 0080h or (f and 07fh)}
;macro CLRW              {dw 0100h}
;macro CLRF f            {dw 0180h or (f and 07fh)}
;macro SUBWF f,d         {dw 0200h or (f and 07fh) or ((d and 1 )shl 7)}
;macro DECF f,d          {dw 0300h or (f and 07fh) or ((d and 1 )shl 7)}
;macro IORWF f,d         {dw 0400h or (f and 07fh) or ((d and 1 )shl 7)}
;macro ANDWF f,d         {dw 0500h or (f and 07fh) or ((d and 1 )shl 7)}
;macro XORWF f,d         {dw 0600h or (f and 07fh) or ((d and 1 )shl 7)}
;macro ADDWF f,d         {dw 0700h or (f and 07fh) or ((d and 1 )shl 7)}
;macro MOVF f,d          {dw 0800h or (f and 07fh) or ((d and 1 )shl 7)}
;macro COMF f,d          {dw 0900h or (f and 07fh) or ((d and 1 )shl 7)}
;macro INCF f,d          {dw 0a00h or (f and 07fh) or ((d and 1 )shl 7)}
;macro DECFSZ f,d        {dw 0b00h or (f and 07fh) or ((d and 1 )shl 7)}
;macro RRF f,d           {dw 0c00h or (f and 07fh) or ((d and 1 )shl 7)}
;macro RLF f,d           {dw 0d00h or (f and 07fh) or ((d and 1 )shl 7)}
;macro SWAPF f,d         {dw 0e00h or (f and 07fh) or ((d and 1 )shl 7)}
;macro INCFSZ f,d        {dw 0f00h or (f and 07fh) or ((d and 1 )shl 7)}
;macro BCF f,b           {dw 1000h or (f and 07fh) or ((b and 7 )shl 7)}
;macro BSF f,b           {dw 1400h or (f and 07fh) or ((b and 7 )shl 7)}
;macro BTFSC f,b         {dw 1800h or (f and 07fh) or ((b and 7 )shl 7)}
;macro BTFSS f,b         {dw 1c00h or (f and 07fh) or ((b and 7 )shl 7)}
;macro CALL a            {dw 2000h or ((a/2) and 7ffh)}
;macro GOTO a            {dw 2800h or ((a/2) and 7FFh)}
;macro MOVLW k           {dw 3000h or (k and 0ffh)}
;macro RETLW k           {dw 3400h or (k and 0ffh)}
;macro IORLW k           {dw 3800h or (k and 0ffh)}
;macro ANDLW k           {dw 3900h or (k and 0ffh)}
;macro XORLW k           {dw 3a00h or (k and 0ffh)}
;macro SUBLW k           {dw 3c00h or (k and 0ffh)}
;macro ADDLW k           {dw 3e00h or (k and 0ffh)}
;macro NULL              {dw 3fffh}
macro osccal o{include 'include/paddosccal.inc'
               retlw o}
macro conf c  {include 'include/paddconf.inc'
               dw (c)}
macro eeprom  {include 'include/paddeeprom.inc'}
macro gpout o {movlw o
               movwf GPIO}
macro bank0   {bcf STATUS,rp0}
macro bank1   {bsf STATUS,rp0}
macro clc     {bcf STATUS,c}
macro stc     {bsf STATUS,c}
macro cldc    {bcf STATUS,dc}
macro stdc    {bsf STATUS,dc}
macro clz     {bcf STATUS,z}
macro stz     {bsf STATUS,z}
macro shl r   {clc
               rlf r,REG}
macro shr r   {clc
               rrf r,REG}
macro sar r   {stc
               btfss r,7
               clc
               rrf r,REG}
macro jmp a   {goto a}
macro ret     {return}
macro iret    {retfie}
 
macro loop r,@{decfsz r,REG
               goto @}
macro mov d,s {movf s,W
               movwf d}
macro movb d,s{movlw s
               movwf d}
macro jz a    {btfsc STATUS,z
               jmp a}
macro jnz a   {btfss STATUS,z
               jmp a}
macro je a    {btfsc STATUS,z
               jmp a}
macro jne a   {btfss STATUS,z
               jmp a}
macro jc a    {btfsc STATUS,c
               jmp a}
macro jnc a   {btfss STATUS,c
               jmp a}
macro jl a    {jc a}
macro jnl a   {jc a}
macro jg a    {jnl a}
macro jng a   {jl a}
macro cmp d,s {movf s,W
               subwf d,W}
macro cmpb d,s{movlw s
               subwf d,W}
macro sub d,s {movf s,W
               subwf d,REG}
macro subb d,s{movlw s
               subwf d,REG}
macro add d,s {movf s,W
               addwf d,REG}
macro addb d,s{movlw s
               addwf d,REG}
org 0h
ça s'utilise comme ça

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
 
include 'include/pic14.inc'
start:
        goto @f
        null
        null
        null
@@:
        movlw 0ffh
        movwf 21h
        movlw 0ffh
        movwf 22h
        bcf 21h,0
        call initGP.2
@@:
        movlw 5
        call @f
        bsf 23h,0
        call initGP.1
        movlw 5
        call @f
        bcf 23h,0
        call initGP.1
        goto @b
        goto $
@@:
        movwf 24h
        movf  24h,W
        movwf 25h
        movlw 64h
        movwf 26h
        movlw 0Ah
        goto @f
@@:
        movwf 27h
        movlw 7Fh
        movwf 28h
mainloop:
        movf 26h,W
        movwf 2Ah
.1:
        movf 25h,W
        movwf 29h
.2:
        movlw 17h
.3:
        addwf 28h,W
        btfsc STATUS,c
        goto .3
        decfsz 29h,REG
        goto .2
        decfsz 2Ah,REG
        goto .1
        decfsz 27h,REG
        goto mainloop
        return
initGP:
.1:
        goto @f
@@:
        movf 23h,W
        movwf GPIO ;PORTA
        return
.2:
        goto @f
@@:
        movf 21h,W
        dw 65h  ;TRIS PORTA
        return
ces fichiers includes sont faits pour être compilés par fasm, le fichier generé aura pour extension .pic, un fichier binaire qu'il faudra charger dans icprog, et une fois chargé avec inversion de bits (ou non, selon le réglage de la macro dw), il faut s'assurer des bons réglages de fusibles et paramètres du programmeur, JDM sur port com (1 ou 2), délai I/O entre 1 et 40, contrôle VPP et VCC.

cliquer sur program device (attention au oscal, il faut surtout pas le modifier, sinon, on le perd.)... une barre de défilement apparait, et lorsqu'elle disparait, le pic est programmé.
patienter un peu, le temps que la liaison ICSP s'arrête, et le pic redémarre normalement (environ 10 à 15 secondes, c'est long, quel suspence).

normalement, ça fonctionne.

et je n'en dis pas plus, si ça vous interresse, vous aurez la curiosité de fouiller et de lire les datasheet (en anglais) des composants qui sont de toutes façon indispensables pour bien coder les pics.