Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Programming Microcontrollers in C, 2-nd edit (Ted Van Sickle, 2001).pdf
Скачиваний:
296
Добавлен:
12.08.2013
Размер:
7.2 Mб
Скачать

352 Chapter 7 Advanced Topics

Numeric Encoding

Data will be entered from a keyboard that is assumed to provide an ASCII character stream. In operation, the first entry will be the telephone number. As this number is received the coding will be converted from ASCII to a modified BCD format. The modification is needed to eliminate trouble with the occurrence of zeros in the number. The conventional BCD encoding for a zero is a 0x0 that is 4 bits wide. If you should have a double zero, the encoded version would be an 8-bit zero or ‘\0’, which is interpreted in C as an end of a character string. That confuses the issue enough that it was decided to encode the digit zero as 0xa. The literal interpretation of this number is the value ten. But, with our BCD encoding, the number ten will never occur, so it is safe to use this value for the value zero.

/* The ascii data in the constant array s[] con tains a number. These data are converted to a modified BCD form and stored in the array array[]. The number zero is stored as 0xa. The series is terminated with a null character followed by an enter character. */

#include <ctype>

int numbdup(char * const s, unsigned *array, int len)

{

char *pq,*sp; int i;

sp=s; /* use local pointer */

pq=(char *)array; /* convert pointer to character */ for(i=0;i<len;i++) /* empty the array */

pq[i]=0;

i=0;

while(*sp!=’\0'&&*sp!=’\n’) /* read until termination char*/

{

*pq=0;

if(isdigit(*sp)) /* convert the inputs two at atime*/

Numeric Encoding 353

{

if(*sp==’0') /* handle a zero input */ *sp=’0'+0xa;

*pq|=(*sp-’0')<<4 ;

}

else

pq|=0xf0; /* non digit, mark it */ if(isdigit(*(sp+1))) /* the next input */

{

if(*sp==’0') /* treat a zero */ *sp=’0'+0xa;

*pq|=(*(sp+1)-’0');

}

else

pq|=0xf; /* another non digit */

 

sp+=2; /* Increment the input data

pointer, */

pq++;

/* the output data pointer,

*/

i++;

/* and the data count */

 

}

return i; /* length of the array */

}

Listing 7-1: Numeric Encoding Routine

All of the storage arrays in the EEPROM are of the type un­ signed int. Here the storage of both numeric data and alpha data requires that every bit of every storage location be used so that unsigned is the norm. In the coding routines, the data are passed in as characters and the destination arrays are unsigned. Therefore, to aid the local bookkeeping, the destination array pointer is immediately assigned to a type char * and this pointer will be used to store the encoded data.

The following program provides a simple test for the numeric coding. This program has a serious problem though. All computers configure memory in either a big endian or a little endian order. In the big endian order, the most significant byte, 8 bits, of a 16-bit address is given the smaller address and the least significant byte goes to the larger address. The little endian order is just the reverse.

354 Chapter 7 Advanced Topics

Here the least significant byte of data is assigned to the smaller ad­ dress and the most significant byte goes to the larger address. Almost all Motorola chips use big endian, and almost all Intel chips use little endian. There can be some confusion when developing code to run on one style of data storage on a machine with the opposite. This problem is seen in the following program.

#include <stdio.h>

main()

{

unsigned array[25]; int i;

numbdup(“123456789098765”,array,25);

for(i=0;i<8;i++)

printf(“%x”,array[i]);

putchar(‘\n’);

}

Listing 7-2: Numeric Encode Test

If this program is compiled with a PC (Intel-based) compiler, the result will not appear to be correct. However, if the program is com­ piled on an HC12, or 68HC16, or 683XX, or 68HC11, or 68HC05 compiler, it will seem to work correctly. In fact, both results are cor­ rect, only the numeric representation in memory is different.

Numeric Decoding

Once the numeric data are encoded and stored, they must be de­ coded to be used by other parts of the program. The decode routine is called putbcd(). This function is shown below.

void putbcd(char *s,char *number)

{

int c,i=0; char *sa; sa=s;

while(*sa!=’\0')

{

Numeric Decoding 355

if(isdigit(c=(*sa>>4)+’0'))

number[i++]=c; else if(c==’0'+0xa)

number[i++]=’0';

if(isdigit(c=(*sa&0xf)+’0'))

number[i++]=c; else if(c==’0'+0xa)

number[i++]=’0';

sa++;

}

number[i++]=’\n’;

number[i++]=0;

}

Listing 7-3: Numeric Decoding Routine

In this function the output data is called number[] and the in­ put is s[]. The encoded data in s[] is converted one BCD 4-bit field at a time to ASCII characters. In the event that a character re­ ceived has a value ‘0’+0xa, it is then a character zero or ‘0’. Each byte is converted from two 4-bit BCD values to two ASCII charac­ ters that represent the proper digits.

The test program for this routine is a combination of the encode test routine with one to decode the encoded data. As one would ex­ pect, when both the encode and the decode routine are used together, the result is correct. This observation is true on either the Intel or the Motorola style chip. The endian-ness of the chip is immaterial when the entire encode/decode operation is completed.

#include <stdio.h> #define ARRAY_SIZE 100

int decode(unsigned M[],char *s);

int encode(char *a,unsigned *array,int length);

main()

{

char a[ARRAY_SIZE] ; int c,i=0;

unsigned array[ARRAY_SIZE]; char s[ARRAY_SIZE];