Bonjour,

Pour mon projet, j'ai dû créer un buffer circulaire. Il reçoit les données d'un bus CAN et les envoi vers une sortie créneau (il s'agit de programmation microcontrôleur).

J'ai donc créé deux compteurs qui sincrémentent à l'écriture et à la lecture des données.
J'utilise aussi deux modulo qui me donnent l'état de ma mémoire. Le premier donne l'espace utilisé et le second l'espace libre.
Mon programme tourne sans soulevé d'erreur au deboggage.

Par contre, afin de vérifier le bon fonctionnement de mon programme, je m'envoi une trame d'acquittement qui contient les valeurs de mes modulo et de mes compteurs et il apparait que le résultat du calcul modulo n'est pas toujours juste.
(dans des situations aléatoires et non répétables)

Voici le code que j'ai réalisé :
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
 
 
//---------------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 = buffer_full1;	  // Insertion des données que l’on souhaite transmettre.
    CAN2TXDSR1 = buffer_empty1  ;
    CAN2TXDSR2 = write_buffer_wheel1;
    CAN2TXDSR3 = read_buffer_wheel1;
    //CAN2TXDSR7 = 0xFF;
 
  CAN2TFLG = txbuffer;
 
  while ((CAN2TFLG & txbuffer) != txbuffer) {     //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 = 0x03;	  //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 = Buf1;	  // Insertion des données que l’on souhaite transmettre.
    CAN2TXDSR1 = Buf2  ;
    CAN2TXDSR2 = buffer_full1;
    //CAN2TXDSR3 = 0x9C;
    //CAN2TXDSR7 = 0xFF;
 
  CAN2TFLG = txbufferE;
 
  while ((CAN2TFLG & txbufferE) != txbufferE) {     //attendre la fin de la transmissin
  ;
 }
}
 
//------receiveOnCan-----------------------------------------
 
void receiveOnCan (){
 
  unsigned char lenght, index;
 
  DisableInterrupts;   
 
  if (CAN2RFLG & CAN2RFLG_RXF_MASK) {  //message disponible
 
     lenght = ( CAN2RXDLR & 0x0F);     //prend en compte la taille max du message (message = 8 octets max)
 
  for (index = 1 ; index < lenght; index++) {
 
    receive_data [index] = *(&CAN2RXDSR0 + index);  // Transfert du message vers un tampon
  }
 
  Buf1 = write_buffer_wheel1 - read_buffer_wheel1;
  Buf2 =  buffer_lenght+ Buf1;
  buffer_full1 = Buf2 % buffer_lenght;
  TestCan ();
 
  buffer_empty1 = (buffer_lenght-(write_buffer_wheel1 - read_buffer_wheel1)) % buffer_lenght;
  buffer_full2 = (buffer_lenght+(write_buffer_wheel2 - read_buffer_wheel2)) % buffer_lenght;
  buffer_empty2 = (buffer_lenght-(write_buffer_wheel2 - read_buffer_wheel2)) % buffer_lenght;
  buffer_full3 = (buffer_lenght+(write_buffer_wheel3 - read_buffer_wheel3)) % buffer_lenght;
  buffer_empty3 = (buffer_lenght-(write_buffer_wheel3 - read_buffer_wheel3)) % buffer_lenght;
  buffer_full4 = (buffer_lenght+(write_buffer_wheel4 - read_buffer_wheel4)) % buffer_lenght;
  buffer_empty4 = (buffer_lenght-(write_buffer_wheel4 - read_buffer_wheel4)) % buffer_lenght; 
 
 
//ecriture memoire roue 1 et test memoire pleine wheel1 ------------------
 
if (write_buffer_wheel1 != buffer_lenght) {
 
    if (write_buffer_wheel1< buffer_lenght && buffer_full1 != 0)  {           //test de la taille de la memoire
              wheel1 [write_buffer_wheel1]= receive_data[1] + (256*receive_data[0]) ;      //ecriture dans la memoire
              write_buffer_wheel1 ++;                   //incrementation du compteur ecriture
 
 
    } else if (write_buffer_wheel1< buffer_lenght && buffer_full1 == 0) {
 
         PORTB =0b00000001  ; 
         sendOnCanFull ()   ;
 
     }
}else {
             write_buffer_wheel1 = 0;                  //rebouclage de la memoire
              wheel1 [write_buffer_wheel1]= receive_data[1] + (256*receive_data[0]) ; 
 
          } 
 
    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
 
void interrupt 8 TOC0_ISR () {
 
  TFLG1 = TFLG1_C0F_MASK ;    // rabaisse le flag de l'interruption
 
 // buffer_empty1 = buffer_lenght - buffer_full1;
 
 if (buffer_empty1 == buffer_lenght) {
    PORTB =0b00000100  ; 
     sendOnCanEmpty ()   ;  
 
 }
 
  if ( read_buffer_wheel1 < buffer_lenght ){                    //test taille de la memoire
 
     TC0 = TC0 + wheel1[read_buffer_wheel1] ;                //lecture des donnees
     read_buffer_wheel1 ++    ; //incrementation compteur lecture
 
 
      } else{
 
         read_buffer_wheel1 = 0    ;                           //rebouclage memoire   .
         TC0 = TC0 + wheel1[read_buffer_wheel1] ;                //lecture des donnees 
 
     }                                                            
 
}         
#pragma CODE_SEG DEFAULT    
 
////////////////////////////////////////////
#pragma CODE_SEG_NON_BANKED
Le problème c'est que je ne sais pas s'il s'agit d'une erreur de programmation ou si je ne pas correctement mes tests.
(Je me réfere à la trame SendOnCan pour vérifier les calculs)

Merci,