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; } }
//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?
This is the file M51.
Do you see an error about the memory ?
BL51 BANKED LINKER/LOCATER V6.11 09/15/2014 20:14:48 PAGE 1 BL51 BANKED LINKER/LOCATER V6.11, INVOKED BY: C:\KEIL\C51\BIN\BL51.EXE Led chenillard.obj TO Led chenillard RAMSIZE (256) INPUT MODULES INCLUDED: Led chenillard.obj (LED_CHENILLARD) LINK MAP OF MODULE: Led chenillard (LED_CHENILLARD) TYPE BASE LENGTH RELOCATION SEGMENT NAME ----------------------------------------------------- * * * * * * * D A T A M E M O R Y * * * * * * * REG 0000H 0008H ABSOLUTE "REG BANK 0" DATA 0008H 0003H UNIT ?DT?LED_CHENILLARD?LED_CHENILLARD * * * * * * * C O D E M E M O R Y * * * * * * * CODE 0000H 00A7H UNIT ?PR?LED_CHENILLARD?LED_CHENILLARD CODE 00A7H 0009H UNIT ?PR?VERIFTI?LED_CHENILLARD CODE 00B0H 0006H UNIT ?PR?VERIFRI?LED_CHENILLARD SYMBOL TABLE OF MODULE: Led chenillard (LED_CHENILLARD) VALUE TYPE NAME ---------------------------------- ------- MODULE LED_CHENILLARD C:0000H SEGMENT ?PR?LED_CHENILLARD?LED_CHENILLARD D:0008H SEGMENT ?DT?LED_CHENILLARD?LED_CHENILLARD C:00B0H SEGMENT ?PR?VERIFRI?LED_CHENILLARD C:00A7H SEGMENT ?PR?VERIFTI?LED_CHENILLARD C:0000H PUBLIC LED_CHENILLARD C:00B0H PUBLIC VERIFRI C:00AAH PUBLIC VERIFTI C:00A5H SYMBOL ?C0001 C:00B0H SYMBOL ?C0004 C:00B3H SYMBOL ?C0005 C:00AAH SYMBOL ?C0007 C:00ADH SYMBOL ?C0008 D:0008H SYMBOL ?LED_CHENILLARD?BYTE B:00D0H.6 SYMBOL AC D:00E0H SYMBOL ACC D:00F0H SYMBOL B D:000AH SYMBOL CENT?042 B:00D0H.7 SYMBOL CY D:0009H SYMBOL DIZ?041 D:0083H SYMBOL DPH D:0082H SYMBOL DPL B:00A0H.0 SYMBOL E B:00A8H.7 SYMBOL EA B:00A8H.4 SYMBOL ES B:00A8H.1 SYMBOL ET0 B:00A8H.3 SYMBOL ET1 B:00A8H.0 SYMBOL EX0 BL51 BANKED LINKER/LOCATER V6.11 09/15/2014 20:14:48 PAGE 2 B:00A8H.2 SYMBOL EX1 B:00D0H.5 SYMBOL F0 D:00B1H SYMBOL IAP D:00A8H SYMBOL IE B:0088H.1 SYMBOL IE0 B:0088H.3 SYMBOL IE1 B:00B0H.2 SYMBOL INT0 B:00B0H.3 SYMBOL INT1 D:00B8H SYMBOL IP B:0088H.0 SYMBOL IT0 B:0088H.2 SYMBOL IT1 C:00A7H SYMBOL L?0010 B:00D0H.2 SYMBOL OV B:00D0H.0 SYMBOL P D:0080H SYMBOL P0 B:0080H.0 SYMBOL P0_0 B:0080H.1 SYMBOL P0_1 B:0080H.2 SYMBOL P0_2 B:0080H.3 SYMBOL P0_3 B:0080H.4 SYMBOL P0_4 B:0080H.5 SYMBOL P0_5 B:0080H.6 SYMBOL P0_6 B:0080H.7 SYMBOL P0_7 D:0090H SYMBOL P1 B:0090H.0 SYMBOL P1_0 B:0090H.1 SYMBOL P1_1 B:0090H.2 SYMBOL P1_2 B:0090H.3 SYMBOL P1_3 B:0090H.4 SYMBOL P1_4 B:0090H.5 SYMBOL P1_5 B:0090H.6 SYMBOL P1_6 B:0090H.7 SYMBOL P1_7 D:00A0H SYMBOL P2 B:00A0H.3 SYMBOL P2_3 B:00A0H.4 SYMBOL P2_4 B:00A0H.5 SYMBOL P2_5 B:00A0H.6 SYMBOL P2_6 B:00A0H.7 SYMBOL P2_7 D:00B0H SYMBOL P3 B:00B0H.0 SYMBOL P3_0 B:00B0H.1 SYMBOL P3_1 B:00B0H.2 SYMBOL P3_2 B:00B0H.3 SYMBOL P3_3 B:00B0H.4 SYMBOL P3_4 B:00B0H.5 SYMBOL P3_5 B:00B0H.6 SYMBOL P3_6 B:00B0H.7 SYMBOL P3_7 D:0087H SYMBOL PCON B:00B8H.4 SYMBOL PS D:00D0H SYMBOL PSW B:00B8H.1 SYMBOL PT0 B:00B8H.3 SYMBOL PT1 B:00B8H.0 SYMBOL PX0 B:00B8H.2 SYMBOL PX1 B:0098H.2 SYMBOL RB8 B:00B0H.7 SYMBOL RD B:0098H.4 SYMBOL REN BL51 BANKED LINKER/LOCATER V6.11 09/15/2014 20:14:48 PAGE 3 B:0098H.0 SYMBOL RI B:00A0H.2 SYMBOL RS B:00D0H.3 SYMBOL RS0 B:00D0H.4 SYMBOL RS1 B:00A0H.1 SYMBOL RW B:00B0H.0 SYMBOL RXD D:0099H SYMBOL SBUF D:0098H SYMBOL SCON B:0098H.7 SYMBOL SM0 B:0098H.6 SYMBOL SM1 B:0098H.5 SYMBOL SM2 D:0081H SYMBOL SP B:00B0H.4 SYMBOL T0 B:00B0H.5 SYMBOL T1 B:0098H.3 SYMBOL TB8 D:0088H SYMBOL TCON B:0088H.5 SYMBOL TF0 B:0088H.7 SYMBOL TF1 D:008CH SYMBOL TH0 D:008DH SYMBOL TH1 B:0098H.1 SYMBOL TI D:008AH SYMBOL TL0 D:008BH SYMBOL TL1 D:0089H SYMBOL TMOD B:0088H.4 SYMBOL TR0 B:0088H.6 SYMBOL TR1 B:00B0H.1 SYMBOL TXD D:0008H SYMBOL UNITE?040 B:00B0H.6 SYMBOL WR C:0000H LINE# 143 C:0002H LINE# 146 C:0004H LINE# 149 C:0006H LINE# 152 C:0008H LINE# 156 C:000BH LINE# 159 ... ... ... ... ... ... ... ... C:00ADH LINE# 397 C:00AFH LINE# 399 ------- ENDMOD LED_CHENILLARD Program Size: data=11.0 xdata=0 code=182 LINK/LOCATE RUN COMPLETE. 0 WARNING(S), 0 ERROR(S)
well now we see that there is more than what you show involved. do a GLOBAL search on unite and fin the other place that play with it
The variable unite is use only at line :
D:0008H SYMBOL UNITE?040
but I note that there is a ?040. Why ?
It's so easy in assembleur why is it so difficult in C ? However, the C language is a high level language.
The problem, I think, is that the variable "unite" is not stock at the good place, and I think that there is, somewhere in Keil, a place to define this, because in assembleur we define this emplacement, for example (MOV 33h, #01Fh), bot not in C, and I don't know how Keil define this automatically.
When we create a software on a PC, windows define automatically the place where variables are stock in the RAM, but maybe with microcontroleur it works diferently.
Are you OK with me ?
I solved part of my problem. Instead of declaring my variables at the begining of the program, I declare it in the fonction.
Before :
#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
And now :
#include <REG51.H> void verifri(); void verifti(); void led_chenillard() { data unsigned char unite; data unsigned char diz; data unsigned char cent; 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'; P2='1'; SBUF=unite; verifti(); SBUF=unite; verifti(); SBUF=unite; verifti(); P1=unite; 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; }
So, with this program the hyperterminal of the PC display "Serial number : 111111".
BUT now if I swap the variables at the time of the statement, it does not work anymore. The PC display "Serial number : çiEEöf.
#include <REG51.H> void verifri(); void verifti(); void led_chenillard() { data unsigned char diz; data unsigned char cent; data unsigned char unite; //unite changed place
Why ????
because whatever writes over, now overwrites 'cent'
you DO have a 'wild' write to the position that is unite/cent FIND IT.
is there somewhere in the rest of your code a write to an absolute address?
Thank you very much for your dedication.
I don't understand "you DO have a 'wild' write to the position that is unite/cent FIND IT."
is there somewhere in the rest of your code a write to an absolute address? :
All of my code is here. As you can see I declare 3 variables at the beginig o "unite, "diz", and "cent", but actually only "unite" is used. When I have solved my problem I can go further, and use the other variable.
My complete code is :
#include <REG51.H> void verifri(); void verifti(); void led_chenillard() { data unsigned char diz; data unsigned char cent; data unsigned char unite; 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'; P2='1'; SBUF=unite; verifti(); SBUF=unite; verifti(); SBUF=unite; verifti(); P1=unite; 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; }
Your complete code???
Where is main()?
Ok, I have changed void led_chenillard() for void main(), but the problem is the same, and in addition I have a new warning :
Warning L1 : unresolved external symbol Symbol : ?C_STARTUP Module : Led chenillard.obj (LED_CHENILLARD)
#include <REG51.H> void verifri(); void verifti(); void main() { data unsigned char diz; data unsigned char cent; data unsigned char unite; 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'; P2='1'; SBUF=unite; verifti(); SBUF=unite; verifti(); SBUF=unite; verifti(); P1=unite; 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; }
Sorry - I've lost track of what the actual problem is!
Warning L1 : unresolved external symbol Symbol : ?C_STARTUP
You're not using the SRC directive (or GUI equivalent) to convert all your 'C' to assembly, are you...?
www.keil.com/.../search.asp
Perhaps it's time to stop and go (back) to basics.
http://www.keil.com/support/man/docs/uv4/uv4_ex_hello.htm
http://www.keil.com/support/man/docs/uv4/uv4_examples.htm
http://www.keil.com/books/
You are probably right. Thanks you for your help.