Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
05/08/08 20:20
Modified:
  05/08/08 20:57

Read: times


 
#154592 - You can still do better
Responding to: ???'s previous message
Chris said:
void RS232_Write(unsigned char reg, unsigned char dat0, unsigned char dat1)
{

unsigned char REG_H, REG_L, DAT1_H, DAT1_L, DAT2_H, DAT2_L, CHECKSUM_H,
			  CHECKSUM_L, CHECKSUM_T;

REG_H = Hex2Ascii(reg >> 4);	  // do the Upper Nibble
REG_L = Hex2Ascii(reg & 0x0F);	  // do the Lower Nibble

DAT1_H = Hex2Ascii(dat0 >> 4);	  // do the Upper Nibble
DAT1_L = Hex2Ascii(dat0 & 0x0F);  // do the Lower Nibble

DAT2_H = Hex2Ascii(dat1 >> 4);	  // do the Upper Nibble
DAT2_L = Hex2Ascii(dat1 & 0x0F);  // do the Lower Nibble

CHECKSUM_T = (cam_header + cam_ID_H + cam_ID_L + REG_H + REG_L + DAT1_H + 
			 DAT1_L + DAT2_H + DAT2_L);

CHECKSUM_H = Hex2Ascii(CHECKSUM_T >> 4);	// do the Upper Nibble
CHECKSUM_L = Hex2Ascii(CHECKSUM_T  & 0x0F);	// do the Lower Nibble

//***********************************************************************
uart_init();
uart_transmit(cam_header); 	Wait(2); 	// header
uart_transmit(cam_ID_H); 	Wait(2); 	// ID H
uart_transmit(cam_ID_L); 	Wait(2); 	// ID L
uart_transmit(REG_H); 		Wait(2); 	// Register H
uart_transmit(REG_L); 		Wait(2); 	// Register L
uart_transmit(DAT1_H); 		Wait(2);	// Data 1 H
uart_transmit(DAT1_L); 		Wait(2);	// Data 1 L
uart_transmit(DAT2_H); 		Wait(2);	// Data 2 H
uart_transmit(DAT2_L); 		Wait(2);	// Data 2 L
uart_transmit(CHECKSUM_H); 	Wait(2);	// Send calculated checksum 1
uart_transmit(CHECKSUM_L); 	Wait(2);	// Send calculated checksum 2
//***********************************************************************
}


This is better than before. Although it works, there are still two problems. The first is the clumsy duplication of the same pattern over and over again in the last eleven lines. When you find yourself writing this kind of code, you should almost always be using a loop instead. That way, if the pattern changes, you only have to change it once instead of eleven times. Also, the loop will use lots less code space.

The other problem is the way that you have decided to deal with the bytes in the packet as individual entities. As a result of this decision, you had to declare a whole bunch of temporary variables (REG_H, REG_L, ... etc.), and you had to name each one of them explicitly in the checksum calculation. What if the packet was 20 bytes long? Or 100? You'd eventually get tired of declaring variables, and the checksum calculation would eventually get to be unmanageably long.

Consider rewriting the function yet again, according to these instructions:
  1. Replace the potload of temporary variables with a single character array that will be used to store the entire packet.
  2. Use #define or 'enum' to create meaningful names for the individual elements of the array. While you're at it, also create a symbolic name for the length of the packet.
  3. Explicitly initialize the first three elements of the array with 'cam_header', 'cam_ID_H', and 'cam_ID_L'.
  4. Call Hex2Ascii() six times as you have been to find the values for the next six elements of the array
  5. Use a loop to read the bytes one at a time from the array and add each one to the checksum.
  6. After calculating the checksum, add it to the array with two more calls to Hex2Axcii().
  7. Use a loop to call uart_transmit() for each of the bytes in the array.
If you follow this approach, I believe your program will be both smaller and easier to maintain.

-- Russ

<heresy>PS: If you really have tons of code space to burn, OR if you are already using formatted I/O someplace else in your program, then you could consider using sprintf() to format the packet instead of all this manual horsing around.</heresy>

List of 35 messages in thread
TopicAuthorDate
Problem with the toascii() w/ clarification            01/01/70 00:00      
   toascii not what you want            01/01/70 00:00      
      Ah yes.....makes sense            01/01/70 00:00      
         C does know ASCII            01/01/70 00:00      
            the final result:            01/01/70 00:00      
               That is a LOT of code            01/01/70 00:00      
                  It won't compile in its state because...            01/01/70 00:00      
               Grossly inefficient!            01/01/70 00:00      
                  A small trick            01/01/70 00:00      
                     small trick is cool.....            01/01/70 00:00      
                        Same as Neil's            01/01/70 00:00      
                           Ah makes sense.....            01/01/70 00:00      
                              You can still do better            01/01/70 00:00      
                                 LOL....Russ.......LOL            01/01/70 00:00      
                                    sprintf()            01/01/70 00:00      
                                       I had you at <>            01/01/70 00:00      
                                          So why not sprintf()?            01/01/70 00:00      
                                             You are right......I did say that            01/01/70 00:00      
                        How the small trick works            01/01/70 00:00      
                           Is it worth it?            01/01/70 00:00      
                              Same assembly generated for me            01/01/70 00:00      
                           You said index.....click click....very nice            01/01/70 00:00      
                              fast (sic?) lookup table            01/01/70 00:00      
                                 Faster? Probably not.            01/01/70 00:00      
               What's in a name?            01/01/70 00:00      
                  true.....but at this point.......            01/01/70 00:00      
                     Tricks and treats            01/01/70 00:00      
                     there is no time lost by doing it right            01/01/70 00:00      
                        You guys are completely right,            01/01/70 00:00      
                           the very simple way to (almost) do it right            01/01/70 00:00      
                           For the sake of learning            01/01/70 00:00      
                              Good point            01/01/70 00:00      
   UART doesn't know ASCII            01/01/70 00:00      
      Good point....but            01/01/70 00:00      
   Unhelpful documentation            01/01/70 00:00      

Back to Subject List