Voir la version complète : Buffer circulaire
Voila j'ai réalisé un buffer circulaire dans lequel des données provenant d'un hyperterminal, via un port série. Ceci fonctionne parfaitement.
Mon probleme est de pouvoir réaliser des test sur les caractères reçus.
Par exemple, si je reçoit "p1234567891234567" je dois réaliser une programmation d'une étiquette (non détaillée ici). Je regarde si j'ai reçu le caractère "p", puis j'attends les 16 prochains caractères.
A savoir que mon buffer, s'appelle buff[32].
Tout se passe bien quand les 17 caractères se situe avant la fin du buffer. En effet si par exemple j'ai ceci dans buff:
buff[30]=p
buff[31]=1
buff[0]=2
buff[1]=3
.
.
.
.
buff[14]=7
(buffer ciculaire)
Dans ce cas je ne sais pas comment pouvoir tester les caractères reçus.
Je possède un pointeur "b" qui s'incremente suivant le nbr de caractère reçu..
Si quelqu'un peux m'aider..
Merci
Petit détails je programme un pic 18f252 en langage c avec Mplab ICD2.
Je ne vois pas trop où tu as un problème.
Il suffit de gérer la lecture comme l'écriture.
A savoir test apres chaque lecture du pointeur correspondant et remise à 0 si il vaut 33.
voici le bout de prgramme d'écriture:
void high_isr0 (void) // interruption sur reception usart
{
bu1[b]=RCREG; // stockage des caractères recus dans bu1[]
b++;
if(b==33)
{
b=0;
}
b1=1; // b1=1 mode reception
}
Comment ferais tu pour pouvoir réaliser la lecture avec les test?
Je réfléchirais ;-). Bon ok elle est facile....
Plus sérieusement. Voci comment je ferais :
int index_lect; //initialisé à 0 en début de prog dans le main
int lect(int size)
{
for(i=0; i<=size; i++)
{
if (bu1[index_lect] == 'x')
//traitement
else if....
//traitement 2
index_lect ++;
if (index_lect == 33)
index_lect = 0;
}
}
size représentant le nombre d'octets à lire. C'est une solution parmi tant d'autres qui devrait marcher (boiter?).
Attention, il faut encore réfléchir à comment gérer le compteur size.
Un conseil, commence par mettre sur le papier avec des "mots" ce que tu veux faire.
Un soft ca commence par une spécification, une définition de protocole quand on parle d'échange de données. Ensuite on fait la conception, le codage et enfin la validation.
Il me semble que tu veux aller trop vite. Essaie de relire le post #31 et les suivants de Vincent++ sur la précédente discussion. Ce sont des bases qu'il faut arriver à assimiler. Cela fait gagner beaucoup de temps ensuite.
ok merci beaucoup et bonne soirée..
Mon protocole est deja définit, et en ce qui concerne la taille du message, je ne vois pas comment y traité. En effet j'ai essayé avec deux pointeurs où je réaliser la différence des 2. Mais la donnée reçu est traitée caractère par caractère, donc la différence entre les deux pointeurs est toujours égale à 1.
Mon unique probleme est de réussir a réaliser un test des caractères que je reçoit qui se placent a la fin et au début de mon buffer..
J'ai essayé beaucoup de méthode mais aucune ne marche et je commence à ne plus avoir d'idée..
C'est très rudimentaire, peut-être pas adpaté mais il me semble que ca devrait fonctionner :
// hypotheses de départ : on recoit les données par 16 systematiquement.
// Les timing permettent de lire l'ensemble de la trame entre deux receptions
// cette dernière remarque implique que size n'est pas incrémenté
// (interruption jamais activée) pendant la lecture
char buffer[32]
int index_write;
int index_read;
int size;
void high_isr0 (void) // interruption sur reception usart
{
buffer[index_write]=RCREG; // stockage des caractères recus dans bu1[]
index_write++;
size ++;
if(index_write==33)
index_write=0;
if (size==33)
size=0;
}
int lect(int size)
{
if ( (size != 0) && (size < 16))
{
for(i=0; i<size; i++)
{
//exemple de traitement à adapter
if (buffer[index_read] == 'x')
//traitement x
else if (buffer[index_read] == 'y')
// traitement y
else if (buffer[index_read] == 'z')
{
index_read ++;
i++;
if(index_read == 33)
index_read = 0;
if(buffer[index_read] == 'a')
//traitement
}
index_read ++;
if (index_read == 33)
index_read = 0;
}
size = 0;
return 0;
}
else
{
return -1;
}
}
int main(void)
{
index_write = 0;
index_read = 0;
size = 0;
while(1)
{
if (size == 16)
{
if (lect(size) != 0)
print("Reception NOK");
else
print("Reception OK");
}
}
return 0;
}
Voici le bout de rpog que j'ai réalisé:
void lect1(void)
{
while (b!=y)
{
if((b-y)>0)
{
for(i=y;i<b;i++)
{
temp[i]=bu1[i];
}
}
else
{
nb=b-y+32;
for(i=y;i<33;i++) temp[i]=bu1[i];
nbrestant=nb-(32-y);
for(i=0;i=nbrestant;i++) temp[i]=bu1[i];
}
y++;
if(y==33)
{
y=0;
}
}
}
void high_isr0 (void) // interruption sur reception usart
{
bu1[b]=RCREG;
b++;
if(b==33)
{
b=0;
}
}
void main(void)
{
if(b1==1)
{
lect1();
for(i=0;i<y;i++)
{
if(temp[i]=='p'||temp[i]=='P')
{
if(temp[i+16]!=0)
{
...........
.............
}
}
}
}
}
Voila; j'ai donc deux buffer circulaire, en faite bu1 est recopié dans temp. J'ai aussi 2 pointeurs, b pour le remplissage et y pour la lecture. Les 2 buffers sont bien des buffers circulaires, le seul probleme c'est que quand j'attends les 16 caractères apres la lettre "p", si ceux ci se situent a la fin et au début du buffer cela ne marche pas.
En effet, si par exemple la lettre "p" se trouve a la case 28 (bu1[32] et temp[32]), lorsque je réalise "if(temp[i+16]!=0)" , le pic ne comprends pas car pour lui temp[i+16]=temp[28+16] soit temp[44], or moi je veux que cela soit temp[8]..
Je sais pas si j'ai été clair mais voici le gros probleme que je rencontre..
Merci.
J'ai bien compris ton problème. C'est donc que tu as un souci d'algo. Il faut faire autrement.
Si tu veux passer par une copie de bu1[] dans temp[], il te suffit de copier bu[28] à bu[11] dans temp[0] à temp[15]. C'est juste une gestion d'indices. Et dans ce cas ta fonction de traitement avec temp[i+16] sera toujours bonne.
J'ai deja essayé de le faire mais je ne sait pas comment y faire..dsl ************ Pas de SMS , veuillez corrigez votre texte *** ******************** Pas de SMS , veuillez corrigez votre texte *** ******** je suis débutant en programmation..
Merci pour ton aide
J'ai deja essayé de le faire mais je ne sait pas comment y faire..désolé mais je suis débutant en programmation..
Merci pour ton aide
Ya pas de mal. On en passe tous par là.
Je ferais ca :
//si y pointe sur le prochain caractere à lire : 30
//On a recu 16 octets => b pointe sur le prochain caractère à ecrire : 14
//Rque : le dernier caractere à lire est bien 13
// a la fin de la lecture y vaut 14
void lect1(void)
{
int size=0;
if (b<y)
{
size = 32-y; //size = 2
size += b; //size = 2 + 14 = 16
}
else
size = b-y;
for(i=0;i<size;i++) // Pour i de 0 à 15 : 16 octets
{
temp[i]=bu1[y];
y++;
if(y==32)
y=0;
}
}
Je veux pas que tu le prenne mal, mais j'ai essayé ton bout de rpog et ça ne marche pas.. quand je tape une premiere fois "p111...1111", ça m'écrit dans temp[] juste un "1" à temp[0], puis si je renvoi "p111...11" ( cas ou le buffer bu1 revient à 0), ça me réecrit tous les caractères que j'ai dans bu1[] dans temp[]..
Merci beaucoup de m'aider ..
C'est fort possible.
Ma fonction copie x octets correspondant entre l'ecart b-y de bu1 dans temp.
Si au moment ou elle est appelée y=0 et b=1 elle ne copiera que 1 octet. Si la deuxième fois que tu l'appelles y=1 b=0, ca copie les 31 autres octets.
Bienvenue dans le monde du débogage...
Quelques conseils avant que je me déconnecte sachant que tu as déjà fais la moitie du travail :
1 - développe la fonction de traitement et valide la SEULE en déclarant en dur ton tableau temp.
2 - développe ta fonction de copie (celle que j'ai donnée adaptée?) et valide la SEULE avec deux tableaux codées en dur et des indices que tu fixes toi "à la main".
3 - développe ta fonction de réception et valide la SEULE en vérifiant que ton tableau bu1 est bien rempli et les indices bien mis à jour.
4 - tes trois fonctions sont validées. Tu sais ce qu'elles font exactement. Réunies les dans un même programme et fais les "ajustements" nécessaires au bon fonctionnement de l'ensemble.
Pour moi ton souci viens du main : tu n'appelles pas la fonction de lecture au bon moment.
le probleme , quand j'envoi plusieurs caractères, ils sont traitées un par un, c'est à dire que l'écart en b et y n'est jamais supérieur à 1, donc il n'est pas possible de calculer la taille du message reçu.
Deplus j'ai l'impression, que par exemple quand b passe de 31 à 0 et que y est à 31 (donc b-y<0), on ne rentre jamais dans la conditon (if(b-y<0)) ...
Le buffer bu1[] fonctionne parfaitement , mon probleme est dans le recopiage de bu1 dans temp à partir de temp[0]..
Voici mon prog:
void lect1(void)
{
if (b!=y)
{
if(b>y)
{
for(i=y,j=0;i<b;i++,j++)
{
temp[j]=bu1[i];
}
}
else
{
for(i=y,j=0;i<33;i++,j++) temp[j]=bu1[i];
for(i=0,j;i=b;i++,j++) temp[i]=bu1[j];
}
}
}
void high_isr0 (void) // interruption sur reception usart
{
bu1[b]=RCREG;
b++;
if(b==33)
{
b=0;
}
b1=1;
}
main void(main)
{
if(b1==1)
{
for(i=y;i<b;i++)
{
if(bu1[i]==112||bu1[i]==80)
{
if(bu1[i+16]!=0)
{
lect1(); for(i=0;i<y;i++) temp[i]=0;
b1=0;
}
}
}
}
Voila le probleme est que je ne sais pas ou placer l'incrementation du pointeur de lecture (y).
void lect1(void)
{
if (b!=y)
{
if(b>y)
{
for(i=y,j=0;i<b;i++,j++)
{
temp[j]=bu1[i];
y++
}
}
else
{
for(i=y,j=0;i<33;i++,j++)
{
temp[j]=bu1[i];
y++;
}
y=0
for(i=0,j;i=b;i++,j++)
{
temp[i]=bu1[j];
y++;
}
}
}
}
Le plus simple c'est de gérer des buffers circulaires avec des modulo.... Ou encore des puissances de 2, comme ca, pas de test, un simple incrément.... sans précaution....
Sinon, tu peux aussi utiliser des listes chainées...
mais bon, un truc du genre :
char buffer[32];
char v;
while (TaCondition)
{
v = ++buffer%32;
Traite(v);
}
A plus
ok merci , je suis pas sur que c'est bien adapté a ce que je recherche . Merci quand meme..
Si quelqu'un a d'autres idées n'hésité pas..
Pour Beldin:
[code]
void lect1(void)
{
if(ecriture-lecture>0)
{
for(i=lecture,j=0;i<ecriture;i++,j++)
{
temp[j]=bu1[i];
lecture++;
}
}
else
{
nb=ecriture-lecture+32;
for(i=lecture,j=0;i<33;i++,j++) temp[j]=bu1[i];
nbrestant=nb-32-lecture;
for(i=0,j;i=nbrestant;i++,j++) temp[i]=bu1[j];
}
}
}
void high_isr0 (void) // interruption sur reception usart
{
bu1[ecriture]=RCREG;
ecriture++;
if(ecriture==33)
{
ecriture=0;
}
carac_recu=1;
}
void main(void)
{
while(carac_recu==1)
{
for(i=lecture;i<ecriture;i++)
{
if(bu1[i]=='p' || bu1[i]=='P')
{
if(bu1[i+16]!=0)
{
lect1();
carac_recu=0;
}
}
}
}
}
[\code]
Mes deux pointerus (b et y) ont étaient rapellés ecriture(b) et lecture(y).
Pourtant ca colle exactement avec ce que tu veux faire .... Lire des données stockées dans un buffer circulaire sans te préoccuper de la fin/début du buffer...
char wbuf[SIZE];
char rbuff[SIZE];
readbuff(char Offset)
{
int i = Offset;
int j = 0;
for (i = Offset; i< Offset + TAILLE_TRAME; i++)
{rbuffer[j] = wbuff[i];
++i%SIZE;
++j%SIZE;
}
}
Ca copier le contenu de ton buffer w (ecrit par l'hyperterm) dnas un buffer de traitement. Il faut fournir l'offset du buffer W ou tu as ton caractere 'p' de debut de trame... les 2 buffers se vident et se remplissent de facon circulaire... sans que tu te préoccupes des bornes...
A plus
Mali :
nbrestant=nb-32-lecture;
for(i=0,j;i=nbrestant;i++,j++) temp[i]=bu1[j];
Tu réécrases temp[0].
il faut au moins faire
for (i=0;i<nbrestant;i++,j++) temp[j] = bu1[i];
Le soft ce n'est pas du "bidouillage jusqu'a ce que ca marche". Il faut reflechir un peu avant de faire les choses.
Le probleme c'est que j'ai réfléchis, mais la je suis bloqué et je ne trouve plus d'autre solution pour me débloquer.
Si quelqu'un a des idées qui pourraient m'aider, n'hésité pas ..
Merci et bonne journée.
Je relance ce post histoire de voir si des personnes peuvent m'aider...
Hello,
Je vous relance pour savoir si quelqu'n connait un astuce ou une adresse qui pourrait me décoincer..
Merci et bonne journée.
Heuuuu, je pige pas trop la... Tu as toutes les infos, ou se situe ton problème?
A mon avis, c'est la bonne adresse.... Tu veux faire un buffer circulaire, le plus simple, c'est d'utiliser les incrément avec un modulo... Le modulo, tu peux le faire avec un masque, ou un opérateur % en C.
A plus
Vincent++
16/05/2006, 17h50
Je pense qu'il faut revoir ton algorithme et ne pas essayer de rafistoler le programme existant.
A+
Vincent
ok merci, je vais reprendre mon algorithme et je vous tiendrez au courant si il fonctione..