We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi All,
I am using DS89C450 MCU and writing my C code using uVision 4 compiler. In my DS89, I had a SRAM of 1kB and I would like to declare a 500 variable of unsigned char therefore I use
unsigned char xdata IR[500];
When I compiler with uVision 4, it show no error and therefore I burn the Hex code into my MCU. However, when I write and then read the IR[500], it give incorrect value
I therefore proceed to use debugger to troubleshoot my code and everything works fine in the debugger. My code does not have any problem.
Therefore I suspect uVision 4 had assign the IR[500] to non SRAM location and therefore the value is actually not written and read.
I would like to know how can I make sure uVision4 assign the SRAM location correctly and is there any setting I need to set before compiling?
Pls help. Thanks a lot
Two things - what settings have you made in your project file where you inform the tools what memory you have?
Another thing - I don't work with your processor, but some of them requires specific configuration bits to be set to activate that XDATA memory since they may support multiple different mappings.
But one question - if you need an array of 500 elements, why do you then create an array with 501 elements?
And another thing - avoid using all-upper-case variable names. All upper-case is normally reserved for preprocessor symbols, to make a developer aware that a symbol as seen in the source code may represent something completely different for the actual compiler.
He didn't.
Note that uVision is not the compiler - see this diagram: http://www.keil.com/c51/devproc.asp
"when I write and then read the IR[500]"
What do you mean by that?
Remember that 'C' array indexes are zero based, so an array of 500 elements has indexes 0..499
"everything works fine in the debugger"
Do you mean the Simulator?
That conclusion is premature. Just because code works in one (rather unrealistic) environment, doesn't mean the code "does not have any problem". It's just as likely that the environment just didn't trigger the problem.
Why suspect when you can check? The linker tells you exactly where it put everything. All you have to do is look in the map file. That's what you got it for.
That said, I'll second Per's suggestion: most likely you forgot to tell the tools that you're going to be using the internal XRAM of your controller. Oh, and "telling the tools" would typically include a change to the startup code.
Actually, there are 2 things here:
1. Telling the tools - via dialogue settings & options;
2. Correctly configuring the controller itself at runtime - eg, in the startup code.
Hi All Expert, Thanks for your comment. Will go and check how to enable the internal SRAM of my MCU and how to set the uVision4 to compile to the correct address. But Some things still puzzled me and I hope you all can enlighten me.
From the memory map of my DS89C450 (I cant attached the jpg here so I will just spell out), it show something like this
00 - FF (128 bytes SFR)
0000 - 1FFF (8kB x 8 Flash Memory Program)
2000 - 3FFF (8kB x 8 Flash Memory Program)
0000 - 03FF (1kB x 8 SRAM, Data OR program memory address from 400 - 7FF)
4000 - FFFF (External Program Memory)
0000 - 03FF - FFFF (External Data memory, 0000 - 03FF non-usable if internal SRAM is activiated)
My question is 1) Why there is an overlap of program memory and data memory from 0000 to FFFF? 2) Does it means that we have 2 x FFFF of memory inside the MCU? 3) Where does the 00 to FF SFR saved as the address is also overlap?
Thanks alot
These are fundamental artefacts of the 8051 architecture.
You need to study the so-called "bible" for the 8051 - links here: www.8052.com/.../120112 - in particular, look st the various distinct memory address spaces.
See also: http://www.keil.com/support/man/docs/c51/c51_le_memareas.htm
The 8051 is a very long-established and widely-used architecture - there is loads of information available online; eg, http://www.8052.com/tutorial http://www.keil.com/books/8051books.asp
Hi All Expert,
Thanks alot. I figure out that I need to set the PMR.1 to use the SRAM. As for the uVision, I already set to use internal RAM and now it works.
A question is that I had 1kB of internal SRAM. Can I declare 2 x 500 bytes of buffer?
e.g.
unsigned char xdata data[499], data1[499];
I run the compiler and it doesnt give any error but when I run the MCU again the result is abnormal again.
Don't you think it confusing with a symbol named "data" directly after the "xdata" keyword? You haven't considered that Keil might have more reserved keywords? http://www.keil.com/support/man/docs/c51/c51_le_intdatamem.htm
And [499] would mean 0..498, i.e. 499 entries. My original comment about 501 entries was because I, for some reason, must have been tired and read wrong. I thought you had written [501] - maybe I happened to have the mouse cursor above the last zero.
But if you want 500 entries, you have to specifically write [500] in the declaration and then you access the elements as [0] .. [499].
I figure out that I need to set the PMR.1 to use the SRAM. not irrelevant where you do it, it must be done in startup.a51, since the compiler initialize the memory BEFORE it reaches main()
Erik
Hi Erik,
I dont understand what you mean by startup.a51? I set my bit in the main loop. Do you mean it will not work this way?
Where should I set the bit then? The register is not bit assessable. So I have to read the whole register and write to only bit 0.
But if you set the bit in main() - don't you then wonder how come global variables magically gets their initial values before you reach main()?
The processor performs quite a lot of work before the execution reaches main(), and some of that work requires that the memory used for storing your global variables is already accessible.
http://www.keil.com/support/man/docs/c51/c51_ap_customfiles.htm
And, again: http://www.keil.com/books/8051books.asp
some people, I shall not mention who, had made this huge '51 project and asked me for help.
Early on I realized that main() started something like this
void main(void) { indexer =0; offset = 0; temp = 0; ...... ...... ......
When I asked "why" the reply was "this compiler (Keil) does not initialize variables". well guess what