Hello everybody.
I'm french, so sorry for my english.
First, thanks for all gentlemens who will help me.
I follow a formation about programmation microcontroleur 8051's family.
First I have studied the microcontroleur himself, after I have made a lot of programs in assembleur with Keil, and no problem.
After I have learn the langage C, and I have made a lot of program on my computer for the computer, and now I try to made the same previous program that I have created in assembleur but in langage C, always with Keil, and I have a problem.
The problem is that the hyperterminal diplay :
"Serial number : 1’˜ž¤ª"
instead of display "Serial number : 111111".
The problem is when the program call the fonction VERIFTI(), the veriable unite is lost!!!! Why ?????
Do you have an idea?
My microcontroleur is an NXP P89V51RD2BN
Please look at my program:
#include <REG51.H> void VERIFRI()reentrant; void VERIFTI()reentrant; data unsigned char cent; data unsigned char diz; data unsigned char unite; void Led_chenillard() { SM0=0; //UART en mode 1 SM1=1; //UART en mode 1 SM2=0; //Gestion multiprocesseur inactive REN=1; //Reception active TMOD=0x20; //Config Timer 1 en mode 2 et mode temporisateur TH1=255; //56000 Bauds TR1=1; //Active le timer 1 TI=1; SBUF=0x0C; //Efface écran VERIFTI(); //Vérifie si l'envoie au PC est terminé SBUF='S'; VERIFTI(); SBUF='e'; VERIFTI(); SBUF='r'; VERIFTI(); SBUF='i'; VERIFTI(); SBUF='a'; VERIFTI(); SBUF='lk'; VERIFTI(); SBUF=' '; VERIFTI(); SBUF='n'; VERIFTI(); SBUF='u'; VERIFTI(); SBUF='m'; VERIFTI(); SBUF='b'; VERIFTI(); SBUF='e'; VERIFTI(); SBUF='r'; VERIFTI(); SBUF=' '; VERIFTI(); SBUF=':'; VERIFTI(); SBUF=' '; VERIFTI(); unite='1'; SBUF=unite; VERIFTI(); SBUF=unite; VERIFTI(); SBUF=unite; VERIFTI(); SBUF=unite; VERIFTI(); SBUF=unite; VERIFTI(); SBUF=unite; VERIFTI(); FIN: goto FIN; } void VERIFRI()reentrant { DEBUT: if (RI==0) { goto DEBUT; } else { RI=0; } } void VERIFTI()reentrant { DEBUT: if (TI==0) { goto DEBUT; } else { TI=0; } }
what is your oscillator frequency?
Please don't fight the programming language by writing C code as if you were still writing in assembler. Forget about the "goto" keyword until you are already able to write C programs fluently. And even then consider pretending that the language doesn't have any "goto" keyword.
void VERIFRI()reentrant { DEBUT: if (RI==0) { goto DEBUT; } else { RI=0; } }
void VERIFRI() reentrant { while (RI == 0) ; RI = 0; }
Another thing - why do you want VERIFRI() to be reentrant? That's a very costly keyword intended for special needs.
And finally - limit the use of all-capitals symbol names for #define'd symbols, to follow the accepted C language naming conventions.
Ok thanks, I will try your answer.
The frequency of the quartz is 11.0592MHz
My answer isn't a solution to your problem. It's just a solution to trying to the C programming language to write "assembler" code.
High-level languages did get loop and conditional constructs just so that people would not need to use jumps.
First question that comes to my mind is why you need reentrant here. Second question would be: Did you configure reentrant stack in STARTUP.A51?
1) drop reentrant, you do not need it 2) change to 'C' from "assembled C" 3) for a test, comment this out SBUF='S'; VERIFTI();
SBUF='e'; VERIFTI();
SBUF='r'; VERIFTI();
SBUF='i'; VERIFTI(); and post the result
Ok thanks all of you.
You are right, reentrant is not util, and I program C like in assembleur. I took a bad habit. I have remove all "goto". But the problem is still present.
erik, I don't understand change to 'C' from "assembled C". Can you explain ?
So I repeat, on the hyperterminal on my PC the message which is display is :
Serial number : äççiÔö instead of Serial number : 111111
I don't understand. Maybe should I tell the microcontroleur where out where to store the "unite" variable. In assembleur I choose the emplacement in the RAM for example 33h, but normaly with the langage C it's not necessary.
My code now is :
#include <REG51.H> void VERIFRI(); void VERIFTI(); data unsigned char cent; data unsigned char diz; data unsigned char unite; void Led_chenillard() { SM0=0; //UART en mode 1 SM1=1; //UART en mode 1 SM2=0; //Gestion multiprocesseur inactive REN=1; //Reception active TMOD=0x20; //Config Timer 1 en mode 2 et mode temporisateur TH1=255; //56000 Bauds TR1=1; //Active le timer 1 TI=1; SBUF=0x0C; //Efface écran VERIFTI(); //Vérifie si l'envoie au PC est terminé SBUF=0x0C; //Efface écran VERIFTI(); //Vérifie si l'envoie au PC est terminé SBUF='S'; VERIFTI(); SBUF='e'; VERIFTI(); SBUF='r'; VERIFTI(); SBUF='i'; VERIFTI(); SBUF='a'; VERIFTI(); SBUF='l'; VERIFTI(); SBUF=' '; VERIFTI(); SBUF='n'; VERIFTI(); SBUF='u'; VERIFTI(); SBUF='m'; VERIFTI(); SBUF='b'; VERIFTI(); SBUF='e'; VERIFTI(); SBUF='r'; VERIFTI(); SBUF=' '; VERIFTI(); SBUF=':'; VERIFTI(); SBUF=' '; VERIFTI(); unite='1'; SBUF=unite; VERIFTI(); SBUF=unite; VERIFTI(); SBUF=unite; VERIFTI(); SBUF=unite; VERIFTI(); SBUF=unite; VERIFTI(); SBUF=unite; VERIFTI(); while (1); } void VERIFRI() { while (RI==0); RI=0; } void VERIFTI() { while (TI==0); TI=0; }
erik, I don't understand change to 'C' from "assembled C". Can you explain ? e.g. in 'C' function names are not all uppercase
did you try as I suggested to comment out the first part of ser.... for diagnostic purposes, It WILL reveal something whether the serial get right or not
OK for the fonction name.
When I test the code that you submit, the serial get right. The PC display "Seri" on the hyperterminal.
He said COMMENT IT OUT! So you shouldn't get "Seri"
Sorry but I don't understand what you want ?
//SBUF='S'; //VERIFTI();
//SBUF='e'; //VERIFTI();
//SBUF='r'; //VERIFTI();
//SBUF='i'; //VERIFTI();
Ah !!! OK.
So it's the same result. The text "Serial number" is not displayed because it is commented out,
and only thing whish is display, is : äççiÔö instead of 111111.
So - that variable "unite" is stored someplace where it gets constantly overwritten. So the serial code does work but gets bad data to send.
Yes that's what I think. Must configure memory in Keil? Is there a way to configure the memory?