Discussion Forum

Arrays

Next Thread | Thread List | Previous Thread Start a Thread | Settings

DetailsMessage
Read-Only
Author
Steve Kelly
Posted
3-Feb-2002 15:22 GMT
Toolset
C51
New! Arrays
As a fairly new student in C I am having diffictly with arrays.

I have a string of numbers that I am tring to split up into smaller strings to convert them to integers.

I have made the code as basic as possible but still get the errors.

#include <stdio.h>
#include <stdlib.h>
#include <reg52.h>

xdata char Temperatures1[9];
xdata char Temperatures2[12];
xdata char Temperatures3[9];

void main(void)
{

  char a[36] = "<<123456789012345678901234567890>>";
  int s;

    SCON = 0x52;
    TMOD = 0x20;
    TCON = 0x69;
    TH1  = 0xF5;

    for(s=0; s < 9; s++)
    {
     Temperatures1[s] = a[s+2];
    }

    for(s=0; s < 12; s++)
    {
     Temperatures2[s] = a[s+11];
    }

    for(s=0; s < 9; s++)
    {
     Temperatures3[s] = a[s+23];
    }

    printf("Temperatures1: %s\n", Temperatures1);
    printf("Temperatures2: %s\n", Temperatures2);
    printf("Temperatures3: %s\n", Temperatures3);
}
I'd expect that Temperatures1,2,3 would all be 1234567890. But Temperature1 is the entire string and Temperatures 2,3 are both incorrect as well

When I watch what is happening in the watch window of the simulator I can see the error ocurring but don't know how to fix it.

Any ideas

Cheers

Steve
Read-Only
Author
Scott deWolski
Posted
3-Feb-2002 15:39 GMT
Toolset
None
New! RE: Arrays
Steve,
The problem is you are trying to print null terminated strings but are using character arrays without null termination. Try terminating them;
#include <stdio.h>
#include <stdlib.h>
#include <reg52.h>

xdata char Temperatures1[10];
xdata char Temperatures2[13];
xdata char Temperatures3[10];

void main(void)
{

  char a[36] = "<<123456789012345678901234567890>>";
  int s;

    SCON = 0x52;
    TMOD = 0x20;
    TCON = 0x69;
    TH1  = 0xF5;

    for(s=0; s < 9; s++)
    {
     Temperatures1[s] = a[s+2];
    }
    Temperatures1[s] = 0;

    for(s=0; s < 12; s++)
    {
     Temperatures2[s] = a[s+11];
    }
    Temperatures2[s] = 0;

    for(s=0; s < 9; s++)
    {
     Temperatures3[s] = a[s+23];
    }
    Temperatures3[s] = 0;

    printf("Temperatures1: %s\n", Temperatures1);
    printf("Temperatures2: %s\n", Temperatures2);
    printf("Temperatures3: %s\n", Temperatures3);
}

The 'C' initializer will probably clear the arrays before calling main(), in which case the last character in each array would already be a null, but you should never rely on this.
You could also use memset() to clear all the arrays before using them.
Best luck
Read-Only
Author
Steve Kelly
Posted
3-Feb-2002 17:35 GMT
Toolset
None
New! RE: Arrays
Scott,

Thanks a lot thats worked a treat.

Cheers

Steve
Read-Only
Author
Jon Ward
Posted
4-Feb-2002 17:38 GMT
Toolset
None
New! RE: Arrays
You may want to consider using the library routines to do actually copy the strings.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <reg52.h>

xdata char Temperatures1[10];
xdata char Temperatures2[13];
xdata char Temperatures3[10];

void main(void)
{

  char a[36] = "<<123456789012345678901234567890>>";

    SCON = 0x52;
    TMOD = 0x20;
    TCON = 0x69;
    TH1  = 0xF5;

    strncpy (Temperature1, &a[2], 9);
    Temperatures1[9] = 0;

    strncpy (Temperature2, &a[11], 9);
    Temperatures2[9] = 0;

    strncpy (Temperature3, &a[23], 9);
    Temperatures3[9] = 0;

    printf("Temperatures1: %s\n", Temperatures1);
    printf("Temperatures2: %s\n", Temperatures2);
    printf("Temperatures3: %s\n", Temperatures3);
}

Jon
Read-Only
Author
Andrew Neil
Posted
4-Feb-2002 17:53 GMT
Toolset
None
New! RE: Arrays
"consider using the library routines"

The library routines are written by the compiler vendor, and usually provide the most efficient implementation - certainly better than writing your own 'for' loop!

Also, with C51, certain Library functions can take advantage of the extra DPTR(s)
Read-Only
Author
Mark Odell
Posted
4-Feb-2002 17:40 GMT
Toolset
None
New! RE: Arrays
The 'C' initializer will probably clear the arrays before calling main()

The C language requires this. All static duration variables must be zeroed before main is called.
Read-Only
Author
Jon Ward
Posted
4-Feb-2002 17:46 GMT
Toolset
None
New! RE: Arrays
The 'C' initializer will probably clear the arrays before calling main(), in which case the last character in each array would already be a null, but you should never rely on this.

In C51, the startup code MUST BE configured by the user. The default setting is that DATA memory is cleared (from 0x00-0x7F) but DATA from 0x80-0xFF and XDATA are NOT cleared. You must make a single configuration change to enable that AND you must include the startup code in your project.

Refer to http://www.keil.com/support/docs/1728.htm for a few more details about the startup code.

Jon
Read-Only
Author
Andrew Neil
Posted
5-Feb-2002 00:22 GMT
Toolset
None
New! RE: Arrays
"In C51, the startup code MUST BE configured by the user."

Every time you start uVision, it puts up that annoying splash screen saying, "True Integration"
In my book, if it really was True integration, the startup code configuration would be included in the uVision options forms!

But then I wouldn't have been able to invent the term NEIDE - Not Entirely Integrated Development Environment ;-)


Read-Only
Author
Alex Ruiz
Posted
5-Feb-2002 04:10 GMT
Toolset
None
New! RE: Arrays
"if it really was True integration, the startup code configuration would be included in the uVision options forms!"

The startup code is so "particular" to your chip and target that put all the available features and options into a kind of option form doesn't sound so good ( What are all the possible user's options!?? ). Almost every month there's a new fancy 8051 derivative on market that requires some kind of different startup code. Only trivial tasks could be put in a form ( common stuff to all chips ).

The user is free to modify it whenever required and there will be always something to be changed.

A really true integration would be some stuff like.: Hey, I don't need to program anymore because all my desired code is at form #3300293 :-)

This guy was definitely born to be freely modified for any special or non-special purpose.
Read-Only
Author
Andrew Neil
Posted
5-Feb-2002 10:00 GMT
Toolset
None
New! RE: Arrays
Well, I see your point. I s'pose I should clarify what I was thinking:

In the particular case of 'C' initialisation in STARTUP.A51, many of the standard parameters which have to be manually set are already specified in the uVision options - principally the 'Target', and 'BL51 Locate' tabs:

IDATALEN
XDATASTART
XDATALEN
PDATASTART
PDATALEN
PPAGE

I'm a great believer that things should be defined in one place only - currently these have to be defined in both the uVision forms and the STARTUP.A51 code.
This is obviously asking for trouble as it's oh so easy for them to get out of step...! :-0

And the rest could easily be specified on a uVision form:
IBPSTACK
IBPSTACK
XBPSTACK
XBPSTACK
PBPSTACK
PBPSTACK
PPAGEENABLE

I think that uVision should at least make these definitions available; eg, via SET command-line options.


Of course, you will still need your own target-specific initialisation stuff in addition to Keil's STARTUP.A51.
Read-Only
Author
Jon Ward
Posted
5-Feb-2002 21:09 GMT
Toolset
None
New! RE: Arrays
In the particular case of 'C' initialisation in STARTUP.A51, many of the standard parameters which have to be manually set are already specified in the uVision options - principally the 'Target', and 'BL51 Locate' tabs:

IDATALEN
XDATASTART
XDATALEN
PDATASTART
PDATALEN
PPAGE


But, what if I have 32K of RAM (from 0x0000-0x7FFF) and 32K of battery-backed NVRAM (from 0x8000-0xFFFF) and I want the first 32K cleared to 0 but not the second 32K.

Or, what if I have 32K of SRAM (from 0x0000-0x7FFF), and 8K of EEPROM (from 0xA000-0xBFFF), and 8K of NVRAM (from 0xE000-0xFFFF), and ...

But, I guess you see the point there.

:-)

Jon
Read-Only
Author
Andrew Neil
Posted
6-Feb-2002 09:41 GMT
Toolset
None
New! RE: Arrays
So what is the point of the 'BL51 Locate' tab, and the address-space fields in the 'Target' tab?
Read-Only
Author
Jon Ward
Posted
6-Feb-2002 18:36 GMT
Toolset
None
New! RE: Arrays
So what is the point of the 'BL51 Locate' tab, and the address-space fields in the 'Target' tab?

The point of the locate tab is to specify the addresses and/or order of segments in the different memory areas. For example, you may prefer that segments use DATA or IDATA in a certain order.

The point of the address-space fields in the target tab are to tell the linker what areas of memory it can use for your program code and your variables. Not every program's CODE and XDATA start at 0x0000.

Jon
Read-Only
Author
Mark Odell
Posted
6-Feb-2002 20:20 GMT
Toolset
None
New! RE: Arrays
Can we create our own segments in C51/L51? In GCC and Diab DCC we can create a segment and then tell the compiler to place certain objects in these segments. These segments are unknown to the default C run-time and thus are left alone, e.g. not cleared and not initialized with compile time values.

For example, for NVRAM I'd place all my NVRAM objects in a segment called .nvRam and create in a linker control file. Then, at the definition of my NVRAM objects I'd just indicate that the compiler should put these objects in the .nvRam segment.

Hmm... maybe _at_ would take care of this just fine. Same net affect I guess.

Regards,

- Mark

Next Thread | Thread List | Previous Thread Start a Thread | Settings