Pages: [1]   Go Down
Author Topic: I need some code translated for me.  (Read 778 times)
0 Members and 1 Guest are viewing this topic.
Greenville, IL
Offline Offline
Edison Member
*
Karma: 11
Posts: 1310
Warning Novice on board! 0 to 1 chance of errors!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

 This code was posted 2 or 3 years ago from AVR freaks and the user is probably moved on. Therefore, I have been trying to understand what is going on line by line. I know that the user is pulsing the TX pin high and low for specific delay times but, I am having trouble understanding the lines that look like bit shifting and compounding. Basically, anywhere there are things that look like "bitwise" code, I get confused.

 If someone would have time to do something like...///"this line he is compound x and y to get x(y)"
Or other wise say TX_PORT &= ~_BV(TX_BIT);  ///"this line means this".

 I would be grateful for any help or direction to help me understand what this code is doing.

Thanks,
Mark


Code:
Sure, here is the init function. I just send address 0x33 and
my Accord's ECU responded correctly. I didn't bother using the UART
 for such a slow baud, just software bit toggling.

Code:

void send_address(uint8_t addr) {
   uint8_t i;
   uint8_t temp;
   
   /* idle high */
   TX_PORT |= _BV(TX_BIT);
   TX_DDR  |= _BV(TX_BIT);
   
   /* required idle delay w0 (2ms), be safe with 4ms */
   _delay_ms(4);
   
   /* start bit */
   TX_PORT &= ~_BV(TX_BIT);
   /* this is at 5bps */
   _delay_ms(200);
   
   /* send byte */
   for (i = 0; i < 8; i++) {
      temp = (addr >> i) & 0x01;
      if (((TX_PORT & _BV(TX_BIT)) >> TX_BIT) == temp) {
         /* already at the correct level, do nothing */
      } else {
         if (0 != temp) {
            TX_PORT |= _BV(TX_BIT);
         } else {
            TX_PORT &= ~_BV(TX_BIT);
         }
      }
      _delay_ms(200);
   }
   
   TX_PORT |= _BV(TX_BIT);
   _delay_ms(200);
   
   /* already idling high on TX */
   
   return;
}
Logged


Grand Blanc, MI, USA
Offline Offline
Faraday Member
**
Karma: 71
Posts: 3536
CODE is a mass noun and should not be used in the plural or with an indefinite article.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

From the avr-libc user manual (get it here):

Quote
11.6 What is all this _BV() stuff about?
When performing low-level output work, which is a very central point in microcontroller
programming, it is quite common that a particular bit needs to be set or cleared
in some IO register. While the device documentation provides mnemonic names for
the various bits in the IO registers, and the AVR device-specific IO definitions reflect
these names in definitions for numerical constants, a way is needed to convert a bit
number (usually within a byte register) into a byte value that can be assigned directly
to the register. However, sometimes the direct bit numbers are needed as well (e. g. in
an SBI() instruction), so the definitions cannot usefully be made as byte values in the
first place.

So in order to access a particular bit number as a byte value, use the _BV() macro.
Of course, the implementation of this macro is just the usual bit shift (which is done
by the compiler anyway, thus doesn’t impose any run-time penalty), so the following
applies:
_BV(3) => 1 << 3 => 0x08

However, using the macro often makes the program better readable.
"BV" stands for "bit value", in case someone might ask you. :-)

Example: clock timer 2 with full IO clock (CS2x = 0b001), toggle OC2 output on
compare match (COM2x = 0b01), and clear timer on compare match (CTC2 = 1). Make
OC2 (PD7) an output.
TCCR2 = _BV(COM20)|_BV(CTC2)|_BV(CS20);
DDRD = _BV(PD7);

So, the following statement clears the TX_BIT in the TX_PORT register. Refer to the datasheet to understand the register and bit mnemonics. Not sure which datasheet to refer you to, as TX_PORT and TX_BIT aren't in the few AVR datasheets that I'm familiar with.
Code:
TX_PORT &= ~_BV(TX_BIT)

Logged

MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 240
Posts: 24450
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

TX_PORT could be any port register, I'm guessing, because it looks like the code is just, doing bit-banging.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Greenville, IL
Offline Offline
Edison Member
*
Karma: 11
Posts: 1310
Warning Novice on board! 0 to 1 chance of errors!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


 Thank you Jack Christensen! You have solved the BV mystery that I was hung up in! I followed your link for the manual and found the quote for BV on page 77. I am that much wiser now.

@Awol, I think you are correct about the TX_PORT being a general define for a port register. I wasn't sure about it but, when it would not compile I suspected it as a variable that needed defined somewhere.

 Thanks you guys have gotten me closer to understanding how to put this to use.
Logged


Grand Blanc, MI, USA
Offline Offline
Faraday Member
**
Karma: 71
Posts: 3536
CODE is a mass noun and should not be used in the plural or with an indefinite article.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Glad to help. I was puzzled by the _BV thing at first too. Now I find I use it...  smiley-eek-blue
Logged

MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

Offline Offline
Edison Member
*
Karma: 17
Posts: 1041
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
void send_address(uint8_t addr) {
   uint8_t i;
   uint8_t temp;
   
   /* idle high */
   TX_PORT |= _BV(TX_BIT); // digitalWrite(TX_BIT on TX_PORT, HIGH);
   TX_DDR  |= _BV(TX_BIT); // pinMode(TX_BIT on TX_PORT, OUTPUT);
   
   /* required idle delay w0 (2ms), be safe with 4ms */
   _delay_ms(4); //delay(4);
   
   /* start bit */
   TX_PORT &= ~_BV(TX_BIT); // digitalWrite(TX_BIT on TX_PORT, LOW);
   /* this is at 5bps */
   _delay_ms(200); // delay(200);
   
   /* send byte */
   for (i = 0; i < 8; i++) { // go 8 times
      temp = (addr >> i) & 0x01;  //temp is the i-th bit of addr
      if (((TX_PORT & _BV(TX_BIT)) >> TX_BIT) == temp) { // if (digitalRead(TX_BIT) == temp)
         /* already at the correct level, do nothing */
      } else {
         if (0 != temp) { // if temp isn't 0
            TX_PORT |= _BV(TX_BIT); //digitalWrite(TX_BIT, HIGH);
         } else {
            TX_PORT &= ~_BV(TX_BIT); //digitalWrite(TX_BIT, LOW);
         }
      }
      _delay_ms(200); //delay(200);
   }
   
   TX_PORT |= _BV(TX_BIT); //digitalWrite(TX_BIT, HIGH);
   _delay_ms(200);  //delay(200);
   
   /* already idling high on TX */
   
   return;
}

The entire thing is essentially a copy of shiftOut()
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 240
Posts: 24450
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

...but without the clock.   smiley-wink

The start and stop bits are something of a give away.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Offline Offline
Edison Member
*
Karma: 17
Posts: 1041
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

...but without the clock.   smiley-wink

The start and stop bits are something of a give away.

Code:
shiftOut(TX_BIT, -1, LSBFIRST, addr);
Logged

Greenville, IL
Offline Offline
Edison Member
*
Karma: 11
Posts: 1310
Warning Novice on board! 0 to 1 chance of errors!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


 Thank you WizenedEE for taking the time to comment every part of that code! I looked up shiftOut() and I can see the similarity.  smiley
 I am going to take parts of the code and do some tests with an led and see if I can see it in action.

 @Awol thanks for pointing out the "without the clock" part, I found what you mean in the shift() tutorial.

 I will try to make good use of this new knowledge, thanks again!
Logged


Pages: [1]   Go Up
Jump to: