Bonjour,

J'ai déjà posé des questions concernant la gestion d'un buffer circulaire (notamment pour les déclarations d'alertes) mais il s'avère que j'ai un problème plus en amont.

Je travaille sur un µc MC9S12XDP512.

Je reçois tout d'abord les données par bus CAN ensuite je les stocke dans un buffer intermédiaire avant de les séparer et de les mettre dans un buffer circulaire. C'est valeurs serviront par la suite à créer un signal créneau grâce à une fonction ECT du microcontrôleur.

La trame est composée de 8 octets de données et je cherche à les stocker de manière à avoir 2 octets par buffer circulaire.
En effectuant plusieurs tests je me suis rendu compte que chaque buffer circulaire ne lisait qu'un seul octet et non les deux.

J'ai esayé plusieurs solutions pour au mieux le même résultat.

Ci-dessous le code que j'ai fait, dans le sous programme receiveOnCan vous pourrez voir toutes les solutions que j'ai essayé.

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
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
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
#include <hidef.h>      /* common defines and macros */
#include <mc9s12xdp512.h>     /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12xdp512"
 
 
 
//==============================================================================          #include <hidef.h>      /* common defines and macros */
#include <mc9s12xdp512.h>     /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12xdp512"
 
#define ECT0_VEC 0xEE //vector adress = 2 channel id
#define ECT1_VEC 0xEC //vector adress = 2 channel id
#define ECT2_VEC 0xEA //vector adress = 2 channel id
#define ECT3_VEC 0xE8 //vector adress = 2 channel id
#define CHANGE_PRIORITY(vec_adr, cfdata)
int vec_adr;
int cfdata ;
 
    const  RATE = 10 ;
    volatile unsigned char index, receive_data [8]; //calibration du tampon de manière à ne pas être gené par la lenght du message
    unsigned short buffer [10];   //allocation statique
    volatile unsigned short buffer1 =0 ;
    volatile unsigned short buffer2 =0 ;
    volatile unsigned short wheel1 [200], wheel2 [200], wheel3 [200], wheel4 [200];
    volatile unsigned short write_buffer_wheel1 = 0 ; 
    volatile unsigned short write_buffer_wheel2 = 0 ;
    volatile unsigned short write_buffer_wheel3 = 0 ;
    volatile unsigned short write_buffer_wheel4 = 0 ;  
    volatile unsigned short read_buffer_wheel1 = 0 ;
    volatile unsigned short read_buffer_wheel2 = 0 ;
    volatile unsigned short read_buffer_wheel3 = 0 ;
    volatile unsigned short read_buffer_wheel4 = 0 ;
 
 
    volatile unsigned short buffer_lenght =200 ;   //taille de la memoire
    volatile unsigned short buffer_full1 =0 ;
    volatile unsigned short buffer_full2 =0 ;
    volatile unsigned short buffer_full3 =0 ;
    volatile unsigned short buffer_full4 =0 ;
    volatile unsigned short buffer_empty1 = 0 ;
    volatile unsigned short buffer_empty2 = 0 ;
    volatile unsigned short buffer_empty3 = 0 ;
    volatile unsigned short buffer_empty4 = 0 ;
    short Buf1 = 0;
    unsigned short Buf2 = 0;
 
 
    volatile unsigned short stat_buffer = 100 ;
 
//-----------Initialisation--------------------------------------------
 
void initPort () {
 
  PORTB = 0x00;       // Configuration du port B  entrée/sortie                      
  DDRB = 0x0F;        //gestion des LEDs
  PTT = 0x00;  
  DDRT = 0X0F;
  PTM = 0x10;      //configuration du port M en entrée et sortie (pin 4 est en entrée et le reste en sortie)
  DDRM = 0x10 ;
  }
 
void Delay (){
 
  int i=0 ;
 
  do{
  i++   ;
 } while (i<10000);
}  
 
 
/*-------------------------------------Timer Counter--------------------------------------*/
 
void timer_counter () {
 
 
  TIOS = 0x0F;         //  timer output compare register
  TSCR1 = 0xF0;        //timer system control register
  TSCR2 = 0x00;        //timer system control register 2
  TCTL1 = 0x00;        //timer control register output mode
  TCTL2 = 0x55;
  TIE = 0x0F;          //timer interupt enable
  //TFLG1 = 0x0F;        //main timer interrupt flag
 
}
 
//==============================================================================
//Timer_Init_polling
//==============================================================================
void Timer_Init_Polling(void)
{
  TIOS = 0x0F;   //channels 0 as output compare
  TCTL1 = 0x00;  //channels disconnected from pin logic 
  TCTL2 = 0x55;  //channels connected to pin logic - Toggle OCx output line  
  TIE = 0x00;    //interrupt disable for channel 0 (channel is servicing in main loop through polling)  
 
  TSCR2 = 0x00;  //prescaler 0 timer clk = bus clk / prescaler = 40Mhz / 1 = 40MHz
  TSCR1 = 0xF0;  //enable timer, stop in wait mode, stop in freeze mode, fast flag clear, precision prescaler disable 
}    
 
//==============================================================================
//PLL_Init
//==============================================================================
void PLL_Init(unsigned char synr, unsigned char refdv) 
{    
  PLLCTL = 0b10110001;  // CME=1,PLLON=0,AUTO=1,ACQ=1,FSTWKP=0,PRE=0,PCE=0,SCME=1	  
  CLKSEL = 0B00000011;  // PLLSEL=0,PSTP=0,PLLWAI=0,RTIWAI=1,COPWAI=1  
  SYNR = synr;          // Set the multiplier register 
  REFDV = refdv;        // Set the divider register  
  PLLCTL_PLLON = 1;     // Enable the Phase Lock Loop
  while(!CRGFLG_LOCK);  //wait until PLL clocks are within desired tolerance of target frequency
  CLKSEL_PLLSEL = 1;    //system clocks are derived from PLLCLK 
}
 
 //---------initMSCAN------------------------------------------------------                  
 
void initMSCAN () {     
    int c2=0;           
    int c1=0;      
 
  while (!CAN2CTL1_INITAK) {   // tant que le module ne confirme pas le mode init
 
	c1++; 
  }
 
 
  CAN2CTL1 |= CAN2CTL1_CANE_MASK;      // activation du module CAN (inactif par défaut)
 
  CAN2CTL1 &= (~CAN2CTL1_LISTEN_MASK);    // Désactivation du mode lecture seule
 
 
 // CAN2BTR0 = 0xC0; // Prescaler = 1 et Synchronisation jump width = 2
  CAN2BTR0 = 0xC3;
 
  CAN2BTR1 = 0xA3;    // TSEG1=4tq er TSEG2=3tq (voir calcul doc calcul_bit_rate.pdf v3.1)
		          	      //Bit 7 SAMP = 1 3 échantillon par bit 
 
 
  CAN2IDMR0 = 0xFF;          //accepte tous les messages
  CAN2IDMR1 = 0xFF;
  CAN2IDMR2 = 0xFF;
  CAN2IDMR3 = 0xFF;
  CAN2IDMR4 = 0xFF;
  CAN2IDMR5 = 0xFF;
  CAN2IDMR6 = 0xFF;
  CAN2IDMR7 = 0xFF;
 
  CAN2CTL0 &= (~CAN2CTL0_INITRQ_MASK);    // demande de sortie du mode initialization
 
  while (CAN2CTL1_INITAK) { //test sortie d'init
 
	c2++; 
 
  }
}
 
  //---------------SendOnCan-------------------------------------------------
 
 
void sendOnCan (){
 
  unsigned char txbuffer;
 
 
  while (!CAN2TFLG){        //test tampon de libre
   ;
  }
 
   CAN2TBSEL=CAN2TFLG;             //selection du buffer ayant la plus petite adresse
   txbuffer = CAN2TBSEL;
 
 
    CAN2TXDLR = 0x04 ;	  //Détermine la lenght de la trame de donnée.
    CAN2TXIDR0 = 0xD3;	  //IDE = Détermine l’identificateur du message ID recu 69E
    CAN2TXIDR1 = 0xC0;	  //Bit 3 IDE = 0 format standard Bit 4 RTR = 0 Trame de donnée Bit [5…7] ID = Détermine l’identificateur du message
    CAN2TXDSR0 = 0x80;	  // Insertion des données que l’on souhaite transmettre.
    CAN2TXDSR1 = 0x52  ;
    CAN2TXDSR2 = 0xF4;
    CAN2TXDSR3 = 0x9B;
    //CAN2TXDSR7 = 0xFF;
 
  CAN2TFLG = txbuffer;
 
  while ((CAN2TFLG & txbuffer) != txbuffer) {     //attendre la fin de la transmissin
  ;
  }
 
 
} 
 
//-----------------SendOnCanFull--------------------------------------------------------  
 
void sendOnCanFull (){
 
  unsigned char txbufferF;
 
 
  while (!CAN2TFLG){        //test tampon de libre
   ;
  }
 
   CAN2TBSEL=CAN2TFLG;             //selection du buffer ayant la plus petite adresse
   txbufferF = CAN2TBSEL;
 
 
    CAN2TXDLR = 0x04;	  //Détermine la lenght de la trame de donnée.
    CAN2TXIDR0 = 0x96;	  //IDE = Détermine l’identificateur du message     ID recu 4B7
    CAN2TXIDR1 = 0xE0;	  //Bit 3 IDE = 0 format standard Bit 4 RTR = 0 Trame de donnée Bit [5…7] ID = Détermine l’identificateur du message
    CAN2TXDSR0 = 0x80;	  // Insertion des données que l’on souhaite transmettre.
    CAN2TXDSR1 = 0x58 ;
    CAN2TXDSR2 = buffer_full3;
    CAN2TXDSR3 = buffer_full4;
    //CAN2TXDSR7 = 0xFF;
 
  CAN2TFLG = txbufferF;
 
  while ((CAN2TFLG & txbufferF) != txbufferF) {     //attendre la fin de la transmissin
  ;
  }
}
 
//------------------SendOnCanEmpty-------------------------------------------------------
 
void sendOnCanEmpty (){
 
  unsigned char txbufferE;
 
 
  while (!CAN2TFLG){        //test tampon de libre
   ;
  }
 
   CAN2TBSEL=CAN2TFLG;             //selection du buffer ayant la plus petite adresse
   txbufferE = CAN2TBSEL;
 
    CAN2TXDLR = 0x02;	  //Détermine la lenght de la trame de donnée.
    CAN2TXIDR0 = 0x57;	  //IDE = Détermine l’identificateur du message  ID recu 2BD
    CAN2TXIDR1 = 0xA0;	  //Bit 3 IDE = 0 format standard Bit 4 RTR = 0 Trame de donnée Bit [5…7] ID = Détermine l’identificateur du message
    CAN2TXDSR0 = 0x02;	  // Insertion des données que l’on souhaite transmettre.
    CAN2TXDSR1 = 0x9C  ;
    //CAN2TXDSR2 = 0x02;
    //CAN2TXDSR3 = 0x9C;
    //CAN2TXDSR7 = 0xFF;
 
  CAN2TFLG = txbufferE;
 
  while ((CAN2TFLG & txbufferE) != txbufferE) {     //attendre la fin de la transmissin
  ;
 }
}
 
//------------------TestCan-------------------------------------------------------
 
void TestCan (){
 
  unsigned char txbufferE;
 
 
  while (!CAN2TFLG){        //test tampon de libre
   ;
  }
 
   CAN2TBSEL=CAN2TFLG;             //selection du buffer ayant la plus petite adresse
   txbufferE = CAN2TBSEL;
 
    CAN2TXDLR = 0x02;	  //Détermine la lenght de la trame de donnée.
    CAN2TXIDR0 = 0x29;	  //IDE = Détermine l’identificateur du message  ID recu 2BD
    CAN2TXIDR1 = 0x80;	  //Bit 3 IDE = 0 format standard Bit 4 RTR = 0 Trame de donnée Bit [5…7] ID = Détermine l’identificateur du message
    CAN2TXDSR0 = 0x35;	  // Insertion des données que l’on souhaite transmettre.
    CAN2TXDSR1 = 0xF4  ;
    //CAN2TXDSR2 = buffer_full1;
    //CAN2TXDSR3 = 0x9C;
    //CAN2TXDSR7 = 0xFF;
 
  CAN2TFLG = txbufferE;
 
  while ((CAN2TFLG & txbufferE) != txbufferE) {     //attendre la fin de la transmissin
  ;
 }
}
 
//------receiveOnCan-----------------------------------------
 
void receiveOnCan (){
 
  unsigned char rx_lenght, index;
 
  DisableInterrupts;   
 
  if (CAN2RFLG & CAN2RFLG_RXF_MASK) {  //message disponible
 
     rx_lenght = ( CAN2RXDLR & 0x0F);     //prend en compte la taille max du message (message = 8 octets max)
 
  for (index = 0 ; index < rx_lenght; index++) {
 
 
    receive_data [index] = *(&CAN2RXDSR0 + index);  // Transfert du message vers un tampon
  }
 
 
//ecriture memoire roue 1 et test memoire pleine wheel1 ------------------
 
if (write_buffer_wheel1< buffer_lenght)  {           //test de la taille de la memoire
              wheel1 [write_buffer_wheel1]= receive_data[0]   ;   //ecriture dans la memoire
              wheel1 [write_buffer_wheel1+1]= receive_data[1] ;
              write_buffer_wheel1 ++;                 //incrementation du compteur ecriture
 
    }
  else {
             write_buffer_wheel1 = 0;                  //rebouclage de la memoire
             wheel1 [write_buffer_wheel1]= receive_data[0]   ;   //ecriture dans la memoire
             wheel1 [write_buffer_wheel1+1]= receive_data[1] ;
             }
 
 
    /*
//ecriture memoire roue 1 et test memoire pleine wheel1 ------------------
  
//if (stat_buffer <= 170){
  
    
  if (write_buffer_wheel1< buffer_lenght)  {           //test de la taille de la memoire
              wheel1 [write_buffer_wheel1]= (256*receive_data[1]) + (receive_data[0]) ;      //ecriture dans la memoire
              write_buffer_wheel1 ++;                   //incrementation du compteur ecriture
              stat_buffer  ++;
                         
    
   } else {
             write_buffer_wheel1 = 0;                  //rebouclage de la memoire
              wheel1 [write_buffer_wheel1]= (256*receive_data[1]) + (receive_data[0]) ; 
              stat_buffer  ++;
          }
/*} else {
           sendOnCanFull () ;
          
           
}  */
 
 //ecriture memoire roue 2 et test memoire pleine wheel2 -----------------
 
if (write_buffer_wheel2< buffer_lenght)  {           //test de la taille de la memoire
              wheel2 [write_buffer_wheel2]= (256*receive_data[3]) + (receive_data[2]) ;      //ecriture dans la memoire
              write_buffer_wheel2 ++;                   //incrementation du compteur ecriture
 
 
 } else {
             write_buffer_wheel2 = 0;                  //rebouclage de la memoire
              wheel2 [write_buffer_wheel2]= (256*receive_data[3]) + (receive_data[2]) ;  
          }
 
 //ecriture memoire roue 3 et test memoire pleine wheel3 ----------------
 
if (write_buffer_wheel3< buffer_lenght)  {           //test de la taille de la memoire
              wheel3 [write_buffer_wheel3]= (256*receive_data[5]) + (receive_data[4]) ;      //ecriture dans la memoire
              write_buffer_wheel3 ++;                   //incrementation du compteur ecriture
 
 
 }else {
             write_buffer_wheel3 = 0;                  //rebouclage de la memoire
              wheel3 [write_buffer_wheel3]= (256*receive_data[5]) + (receive_data[4]) ;  
          }
 
 //ecriture memoire roue 4 et test memoire pleine wheel4 ------------------
 
if (write_buffer_wheel4< buffer_lenght)  {           //test de la taille de la memoire
              wheel4 [write_buffer_wheel4]= (256*receive_data[7]) + (receive_data[6]) ;      //ecriture dans la memoire
              write_buffer_wheel4 ++;                   //incrementation du compteur ecriture
 
 
 }else {
             write_buffer_wheel4 = 0;                  //rebouclage de la memoire
              wheel4 [write_buffer_wheel4]= (256*receive_data[7]) + (receive_data[6]) ;  
          }
 
    CAN2RFLG = 0x01;          //flag lors de la reception d'un message
    EnableInterrupts ;  
 
   }
 
  //  sendOnCan();            
   //CAN2RIER = 0x01; // interruption du recepteur après la réception du message
 
}  
 
/*----------------------------------Interrupt------------------------------------------------*/        
#pragma CODE_SEG NON_BANKED   //permet de placer les interruption dans la mémoire en reserve
 
interrupt 8 void TOC0_ISR (void) {
 
 
//if (stat_buffer >= 50) {
 
  if ( read_buffer_wheel1 < buffer_lenght ){                    //test taille de la memoire
 
     TC0 = TCNT+ wheel1[read_buffer_wheel1] ;                //lecture des donnees
     read_buffer_wheel1 ++    ; //incrementation compteur lecture
     stat_buffer -- ;
 
      } else{  
         read_buffer_wheel1 = 0    ;                          //rebouclage memoire   .
         TC0 = TCNT+ wheel1[read_buffer_wheel1] ;                //lecture des donnees 
         stat_buffer -- ;
     }                                                           
/*}else {
 
sendOnCanEmpty ();
}  */
 
}
#pragma CODE_SEG DEFAULT    
 
////////////////////////////////////////////
#pragma CODE_SEG NON_BANKED  
 
interrupt 9 void TOC1_ISR (void)  {   //adresse de la quatrième interruption périodique
 
    if ( read_buffer_wheel2 < buffer_lenght ){                    //test taille de la memoire
 
     TC1 = TCNT + wheel2[read_buffer_wheel2] ;                //lecture des donnees
     read_buffer_wheel2 ++    ; //incrementation compteur lecture
 
      } else{
         read_buffer_wheel2 = 0    ;                           //rebouclage memoire   .
         TC1 = TCNT + wheel2[read_buffer_wheel2] ;                //lecture des donnees 
     }                                                            
} 
 
#pragma CODE_SEG DEFAULT
 
/////////////////////////////////////////////         
#pragma CODE_SEG NON_BANKED
 
interrupt 10 void TOC2_ISR (void)  {   //adresse de la troisième interruption périodique
 
 
   if ( read_buffer_wheel3 < buffer_lenght ){                    //test taille de la memoire
 
     TC2 = TCNT + wheel3[read_buffer_wheel3] ;                //lecture des donnees
     read_buffer_wheel3 ++    ; //incrementation compteur lecture
 
      } else{
         read_buffer_wheel3 = 0    ;                           //rebouclage memoire   .
         TC2 = TCNT + wheel3[read_buffer_wheel3] ;                //lecture des donnees 
     }                                                             
  }
 
#pragma CODE_SEG DEFAULT 
 /////////////////////////////////////////////
#pragma CODE_SEG NON_BANKED  
 
interrupt 11 void TOC3_ISR (void)  {   //adresse de la quatrième interruption périodique
 
  if ( read_buffer_wheel4 < buffer_lenght ){                    //test taille de la memoire
 
     TC3 = TCNT + wheel4[read_buffer_wheel4] ;                //lecture des donnees
     read_buffer_wheel4 ++    ; //incrementation compteur lecture
 
      } else{
         read_buffer_wheel4 = 0    ;                           //rebouclage memoire   .
         TC3 = TCNT + wheel4[read_buffer_wheel4] ;                //lecture des donnees 
     }                                                            
} 
 
#pragma CODE_SEG DEFAULT
 
//==============================================================================
//main
//==============================================================================
 
void main(void) {
 
  initPort();
 
  initMSCAN ();
 
  timer_counter ();
 
  PLL_Init(10 ,1);            //40MHz BUSCLK from 16MHz OSCCLK
 
  // sendOnCan(); 
 
  EnableInterrupts;
 // Timer_Init_Polling();
 
 
    for(;;)                     //endless loop
       {
 
        receiveOnCan();  
 
        while(TFLG1 == 0x00);  //wait for output compare flag
        TC0 = TCNT + wheel1[read_buffer_wheel1] ;     //toggle in pulse interval 
        TC1 = TCNT + wheel2[read_buffer_wheel2] ;
        TC2 = TCNT + wheel3[read_buffer_wheel3] ;
        TC3 = TCNT + wheel4[read_buffer_wheel4] ;   
 
 
       }
}

Merci d'avance,

Je précise aussi que je ne peux pas utiliser les fonctions telles que malloc, realloc, free etc ...