Topic : bit(s) not allowed as automatic variables

Forum : 8051

Original Post
Post Information Post
July 4, 2007 - 12:29am
Guest

Hello,
I'm trying to build a project which display things on LCD, but I get this error.

ERROR C205 IN LINE 86 OF recepteurrf.c : BIT(s) not allowed as automatic variables

I'm using a XEVA-DEMO kit with 8051 uC on it.
Can anyone help me ?
Thanks

Replies
Post Information Post
+1
0
-1
July 4, 2007 - 3:30pm
Guest

You can declare variables with the bit keyword:

bit my_soft_flag;

However, you cannot use this syntax for local variables within a reentrant functions (it would be very hard to address bits in the internal stack).

Francis

+1
0
-1
July 4, 2007 - 7:55pm
Guest

well this is the code

/*****************************************************************************/
/* Programme de l'interruption int1 */
/*****************************************************************************/
void int1(void) interrupt 2 {
// doit contenir le message, la date ou le nombre à afficher
int val[33];

bit oldbit;
static bit newbit;
static int compteur; // pour indexer les caractères de la trame
static int cont10; // pour compter jusqu'à 10, marquer la fin d'une séquence de 10 bits
static int type_trame; // pour mémoriser le type de trame reçue
static int etat; // pour mémoriser l'état du récepteur
//un récepteur est toujours dans un des états suivant
// aff_heures, aff_graphe, aff_texte

// sépare le préambule du de la donnée ou la commande dans la trame
static int JK;

/* Décodage NRZI -> NRZ */
oldbit = newbit;
newbit = RXD;
NRZ = NRZ << 1;
NRZ = NRZ + (newbit ^ oldbit);

if ((NRZ & 0x001F) == 0x0011) { // détection du JK
compteur = 0; // Init compteur
cont10 = 0;
JK = 1; // JK okay
}

if (JK==1){
cont10++; // on incrémente le compteur modulo 10

if (cont10==9) { // on a reçu les 10 bits
compteur++; // on incrémente le compteur de caractères
cont10 = 0; // mise à zéro du compteur mmodulo 10

switch(compteur) {
case 1: // cas réception du type de trame
type_trame = dec_5b4b();
break;

case 2:
// on teste si la trame est une commande
if (type_trame==com) {
etat = dec_5b4b(); // mémorise la commande reçue
JK = 0;
}
else {
if (etat==aff_graphe) {
val[0] = dec_5b4b();
aff_g();
JK = 0;
}
else
val[0] = dec_5b4b();
}
break;

case 8:
val[6]=dec_5b4b();
// on détecte si on veut afficher l'heure
if (etat==aff_heures) {
aff_h();
JK = 0;
}
break;

case 33:
val[31] = dec_5b4b();
aff_t();
JK = 0;
break;

default:
val[compteur-2] = dec_5b4b();
break;
}
}
}
}

comments are in french but I guess you understand.

+1
0
-1
July 10, 2007 - 6:28pm
Guest

Make 'oldbit' static like 'newbit' and it should work.

You have declared oldbit as an automatic bit variable in an interrupt procedure. That is not possible. You can either use an automatic byte-addressable variable or a static bit-addressed variable. This is a restriction on the special non-standard 'bit' type.

Interrupt procedures are of necessity of the reentrant type, in that they create all dynamic variables on the stack.

Bit variables are provided to make use of a region of special bit-addressable hardware memory locations specific to the 8051 series, which are not in the same place as the stack.

So bit variables cannot be created on the stack and so must be static, or at least pseudo-static.

(Pseudo-static is the default way dynamic variables in non-reentrant procedures are created. They are really static memory locations shared between procedures that the linker can determine will not be called at the same time. So to the programmer they look like automatic variables. True reentrant procedures share variables with *themselves*, interupt procedures share with *everyone*, so neither can use this mechanism.)

Tim

+1
0
-1
July 11, 2007 - 10:39am
Guest

Hi
Note your int [33] array is quite big for the stack (if you are in AUTO mode).
Moreover, for interrupt handler, it is better to specify a register bank (in order to avoid the long sequence of push/pop). The general principle is to associate qa register bank for a "priority level" (0/1).
Francis