Introduction: How to Use Computer Registers - Lesson 1 - Bit Basics, Masking, Logic Operations

Picture of How to Use Computer Registers - Lesson 1 - Bit Basics, Masking, Logic Operations
Computer registers are tricky to use but worth learning how to use. They look like numbers, but act like a series of check boxes. Every single bit can have a different function. Putting a 1 or a check will turn something on. Changing the 1 to a 0 will turn it off. But how to do you change just the third bit without affecting the other seven?

Registers are used by all sorts of IC devices. A sensor can have register where it stores the status of what the sensor is measuring. Because computers and microcontrollers understand and use registers, it makes it easy for a computer/microcontroller to read information from a register on a sensor.

Step 1: Things You Need to Know

Things you need/need to know:

1. What is a binary number.

2. What is a byte.

3. Basic programming, especially programming Arduino.

Read up on these before starting this lesson.

Step 2: Find the Register Hidden in the Arduino Code

Picture of Find the Register Hidden in the Arduino Code
Programming the Arduino is easy because they have made many abstractions. They changed complex or unfamiliar computer concepts and replaced them with more understandable names or processes.

For example, on the Arduino each pin has been given a number. There are 14 digital pins and 6 analog pins.

Pin 13 is the pin that is connected to an LED. You practice your first code by writing to that pin to turn on the LED. http://www.arduino.cc/en/Tutorial/Blink?from=Tutorial.BlinkingLED

Arduino Code Sample 1.

pinMode(13, OUTPUT); // turn pin 13 to output

digitalWrite(13, HIGH); // turn on pin 13 using digitalWrite

That is all nice, but it is not even close to what is really happening. The Arduino Uno uses the ATmega328P-PU microcontroller. What Arduino is calling pin 13 is PB5. That means it is the fifth bit in port B register. http://www.arduino.cc/en/Hacking/PinMapping168

Step 3: Sail Into Ports

A port is a group of related I/O pins. Port B is a register with eight bits or one byte. Each bit represents the status of a pin. The pin is high or low, depending on if a 1 or 0 was written to each bit. Port B is associated with eight physical pins on the ATmega328.

The name of each bit is an abbreviation of the port and bit position. We have bits 0-7 or PB0 thru PB7. (Counting always starts with zero.) Bits PB0 thru PB5 are the Arduino digital pins 8-13. Bits PB6 & PB7 are used for connecting to the crystal, xtal1 & xtal2 .

Port B

I/O

PB7

PB6

PB5

PB4

PB3

PB2

PB1

PB0

Arduino Pins

Crystal2

Crystal1

Pin13

Pin12

Pin11

Pin10

Pin9

Pin8

The rest of the Arduino digital pins come from Port D. The analog pins are connected to Port C. http://www.atmel.com/images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet_Complete.pdf

Working with all these different ports is a little confusing. Arduino simplifies this by renaming them as pins 0-13 and A0-A5.

Step 4: Every Bit Does Something

Because there are 8 bits, then the allowed numbers are 0-255. Since each bit represents a pin, then any number you write to the register can affect multiple pins.

For example, if you write the decimal number 10 or in binary 00001010. For every 0 you are turning off the pin, and for every 1 you are turning on the pin. You turned on pins PB1 and PB3, and you turned off pins PB0, PB2, PB4-PB7. On the Arduino you turned on pins 9 & 11, and turned off 8, 10, 12, 13, xtal1, & xtal2.

http://www.avr-tutorials.com/digital/digital-input...

Sample Code 2.

PORTB = B01100000 // write B00001010 to Port B

Port B I/O

PB7

PB6

PB5

PB4

PB3

PB2

PB1

PB0

Data Byte

B00001010

0

0

0

0

1

0

1

0

Arduino Pins

Crystal2

Crystal1

Pin13

Pin12

Pin11

Pin10

Pin9

Pin8

Status

(On/Off)

Off

Off

Off

Off

On

Off

On

Off


Changing the digital pins is ok, but possibly switching the crystal pins could cause problems. That would be a bad thing for a beginner to do. This is another benefit of how the Arduino programming works by preventing you from making such a big mistake.

Sometimes the Arduino way will make you write more lines of code. Instead of turning on/off digital pins 9-13 all at once, you have to individually write code to turn on/off each pin separately. That is more code and microseconds slower.

The slower code is a good trade off, because it makes your code much safer and easier to write.

Step 5: Masking Makes It Easy

How can you change only the bit(s) you want without changing the rest of the bit(s) in the register? You use what is called a mask. Think of it like painting. If you do not want to paint something, you cover it with tape to mask it from the paint. Masking bit works in a similar way.

Instead of writting the whole 8-bit number/byte and changing the whole register, you use logical operation and a special number to switch only the bit(s) you want changed.

Arduino has a web page tutorial for bit masking. http://www.arduino.cc/en/Tutorial/BitMask

The common operations are AND (&), OR (|), left shift (<<), and right shift (>>). Also useful are the NOT/complement (~), and the exclusive or/XOR (^) operators. With these operators you can move bits around, flip them from 1 to 0, combine, and/or subtract them. You can use several of these at the same time for complex bit changes.

A typical mask is a binary number with 0s where you do not want a change and 1s where you do want a change. A mask for PB5 would be B00100000. If we combine the mask with the value already at the register using the OR operator, then we can turn on PB5 without changing the status of the other bits.

Sample Code 3.

// we will use PBValue as the variable that holds the current contents of Port B.

// the current value of PBValue = B01001100

PBValue = PBValue | B00100000; // (result is 01101100)

The OR operator looks at each bit. If either or both is a 1 then the combination is a 1. If both are 0s then the combination is 0. Using the OR operator we turned on the bit we wanted to, and everything else remained the same.


Port B I/O

PB7

PB6

PB5

PB4

PB3

PB2

PB1

PB0

PBValue

0

1

0

0

1

1

0

0

PB5 Mask

0

0

1

0

0

0

0

0

OR

Results

0

1

1

0

1

1

0

0

http://playground.arduino.cc/Code/BitMath

Step 6: The OR Is a Great Tool.

What if PB5 was already on, and we tried to turn it on again? You get the same results because if either or both are 1 then the combination is 1.

Port B I/O

PB7

PB6

PB5

PB4

PB3

PB2

PB1

PB0

PBValue

0

1

1

0

1

1

0

0

PB5 Mask

0

0

1

0

0

0

0

0

OR

Results

0

1

1

0

1

1

0

0

Writing using OR and a mask allows to to turn on exactly which bits you want without knowing what is currently written in the register. It is a great first step in learning how to use registers.

Next time we will talk about using other operators.

Step 7:


Port B

I/O

PB7

PB6

PB5

PB4

PB3

PB2

PB1

PB0

Arduino Pins

Crystal2

Crystal1

Pin13

Pin12

Pin11

Pin10

Pin9

Pin8

Comments

tomatoskins (author)2015-06-01

This is a great intro! I remember learning about Logic opperations and Masks when learning how to program industreal PLCs! Thanks again for sharing!

JouleTime (author)tomatoskins2015-06-01

Thanks for the positive feedback. The instructable was written to help people who are supporting by Kickstarter project. I wanted them to have a background lesson on dealing with registers. I2C sensors, and parts are full of registers you have to read and write information to. Regular Arduino programming hides this complexity from the user.

About This Instructable

4,653views

182favorites

License:

Bio: We sell DIY kits for electronics. Please check out our website: http://www.jouletime.com/
More by JouleTime:I2C Talking to a Temperature Sensor - EMC1182How to Get Started With I2C - Wonderful World of Inter IC CommunicationBest? Electonic Parts Kit Ever! ADALP2000 by Analog Devices
Add instructable to: