- •1 Introduction to C
- •1.1 Some Simple Programs
- •1.2 Names
- •1.3 Types and Type Declarations
- •1.4 Storage Classes, Linkage, and Scope
- •1.5 Character Constants
- •1.6 Arrays
- •1.7 Other types
- •1.8 Operators and Expressions
- •1.9 Increment and Decrement Operators
- •1.10 Precedence and Associativity
- •1.11 Program Flow and Control
- •1.12 Functions
- •1.13 Recursion
- •1.14 Summary
- •2 Advanced C Topics
- •2.1 Pointers
- •2.2 Multidimensional Arrays
- •2.3 Structures
- •2.4 More Structures
- •2.5 Input and Output
- •2.6 Memory Management
- •2.7 Miscellaneous Functions
- •2.8 Summary
- •3 What Are Microcontrollers?
- •3.1 Microcontroller Memory
- •3.3 Programming Microcontrollers
- •3.4 Coding Tips for Microcontrollers
- •4.1 Microcontroller Memory
- •4.2 Timers
- •4.4 Pulse Width Modulator System
- •4.5 Other Program Items
- •4.6 Summary
- •5.1 Header File
- •5.2 Sorting Programs
- •5.3 Data Compression
- •5.4 Timer Operations
- •5.5 Summary
- •6 Large Microcontrollers
- •6.3 A Pulse Width Modulation Program
- •6.4 Cosmic MC68HC16 Compiler
- •6.6 Digital Signal Processor Operations
- •6.7 Other MC68HC16 Considerations
- •7.1 Numeric Encoding
- •7.2 Numeric Decoding
- •7.3 Coding the alpha data
- •7.4 The Monitor Program
- •7.5 The SAVEIT() Routine
- •7.6 The printout() and the printafter() Functions
- •7.7 Reset
- •7.9 Putting It All Together
- •7.10 Summary
- •8 MCORE, a RISC Machine
- •8.1 Delay Routine
- •8.2 Delays Revisited
- •8.4 Handling Interrupts
- •8.5 A Clock Program
- •8.6 Keyboard
- •8.7 Integrating Keyboard and Clock
- •8.8 Adding a Display
- •8.9 Summary
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];