D
D
Denis2014-12-14 20:00:17
Microcontrollers
Denis, 2014-12-14 20:00:17

Can you explain what magic happens in this code?

There is a program that I write under AT89C51. It has a piece that reads information from an external device byte by byte and displays it on the LCD screen:

void read_mem(){
  int iter;
  char now;
  char now2;
  char char1[4];
  char char2[2];
  for (iter=0; iter<=7;iter++){
    now = RX();
    memory[iter] = now;
    now2 = now;
    //TX(now);		  // commented magic
    sprintf (char1, "%2.2X", now);
    char2[0] = char1[0];
    char2[1] = char1[1];
    lcd_display(char2);
    ms_delay(300);
  }

Char2 is a crutch that serves to trim what is obtained in char1 (it turns out FF00 instead of just FF, if you tell me how to fix it humanly - thank you very much, but that's not even the question).
In this form, as it is now, something like: "000014 81 7F" is displayed instead of "00147F".
BUT! The code has commented magic in the form of a method that passes its char argument to the same external device:
void TX(unsigned char cmd){
 
  unsigned char temp = 0;
  unsigned char iter = 0;
  temp = cmd;
  for (iter=0;iter<8;iter++) {
      	if (temp&0x01) {
      		termopin = 0x0;     //transfer 1
          	us_5_delay();	 	
          	termopin = 0x1;
          	us_70_delay();
      	} else {                //transfer 0
      		termopin = 0x0;
          	us_70_delay();
          	termopin = 0x1;
          	us_5_delay();
      	}
    temp >>= 1;
    }
  us_70_delay();
}

If you uncomment this line, the correct text magically appears on the screen. Why??

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Armenian Radio, 2014-12-14
@Trans00

There is nothing "magic" in programming:
In this case, you are faced with the work of the optimizer. The optimizer, seeing that there was no special meaning in the now variable, did not create it, but simply passed to sprintf what it received from the RX procedure (and RX probably produces an int).
If you uncomment TX, the optimizer will not be able to throw out the variable, it will convert to char and you will get the correct result.
Solution: sprintf to convert byte to hex string - cannon shot at sparrow:

unsigned char toAlf(unsigned char c)
{
      if(c<10)
      {
          return(c+'0');
      }
      return(c-10+'A');
}
...
char[0]=toAlf(now>>4);
char[1]=toAlf(now&0x0F);

J
jcmvbkbc, 2014-12-15
@jcmvbkbc

Do this and everything will work for you:

void read_mem(){
  int iter;
  unsigned char now;
  char char1[4];
  for (iter=0; iter<=7;iter++){
    now = RX();
    memory[iter] = now;
    sprintf (char1, "%02X", now);
    lcd_display(char1);
    ms_delay(300);
  }

Namely:
- replace char with unsigned char to avoid sign expansion when converting to int when passed to sprintf;
- add 0 to the format string so that values ​​0...9 are displayed as 00 ... 09.
In addition, your char2 is not closed with zero at the end, so lcd_display can give you anything.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question