banner



How To Read Pind Register

Hello young man readers, today I will write a bit virtually the digital pins and how to read and write digital values to then, its a simple subject simply of a bang-up importance, because well-nigh everything that our micro-controller does is using its inputs and outputs to talk with leds, motor drivers, lcd's, shift-register, to read data from digital sensors and a lot other things, so lets start reading near how to do information technology.
Our micro-controller, the Atmega328p as registers, those registers are associated with the input/output ports, each port as a specific name and the associated registers, in fact our atmega as port B,C and D, and each port as a dissimilar number of pins(this is a brake of the 28 pins PDIP package and non from the micro-controller, because an twoscore pins PDIP for example as 4 ports with the full 8 bits each ane), the only port that equally the total 8 input/output pins is PORTD.

Every bit you may already know, each pin can have multiple functions, like pwm generation, or ADC capabilities, the pins 7 and vii from PORTB are as well the input pins for the crystal oscillator, and pin half-dozen from PORTC is the reset button.
In this paradigm you can run into all the alternative functions that each pin tin can take, the chip in question is the Atmega328p.

And here is the mapping betwixt arduino port names and their real name:

Then, how tin we interact with our digital pins?
Well, to begin in that location is a defended register for each PORT that defines if each pin is a input or an output, that register is the DDRx, where 10 is the alphabetic character from the PORT that nosotros want to configure, in the case of the Arduino in that location is DDRB, DDRC and DDRD. As every logic value, each flake in the DDRx registers tin be either 1 or 0, beingness that putting a specific fleck of DDRx at 1 configures the pivot every bit output and putting it at 0 will configure the pin as an input, lets see a small case that configures pins 0,ane,2,3 as digital inputs and pins 4,5,6,vii as digital outputs:

DDRD = 0b11110000;        

And all pins equally outputs:

DDRD = 0b11111111;        

And if y'all demand all outputs? Try information technology yourself, or wait a few days and I volition release my bit-manipulation tutorial.
In that location should be some care when using PORTD and Serial/USART considering pins 0 and 1 from the PORTD are the ones used by the USART and if y'all put both of them as inputs or outputs the USART may be unable to read or write data in those pins.

We tin can already say to the Atmega how the pins should be handled, but we want to know how to read an write information to those said pins, then to write information to a given port, we use the PORTx register, this 1 is easy to remember, where ten is the port name, after configuration a pin as an output its just a matter of putting 0 or ane in the PORTx register to bulldoze that pin depression or high respectively, lets come across some code for it:

DDRD = 0b11111111;    //All pins in PORTD are outputs PORTD = 0b11111111;    //All pins in PORTD are loftier        
DDRD = 0b11111111;    //All pins in PORTD are outputs PORTD = 0b00000000;    //All pins in PORTD are low        

And how about a design of on,off,on,..?

DDRD = 0b11111111;    //All pins in PORTD are outputs PORTD = 0b10101010;    //The minor on,off,on,.. blueprint        

Now, the only thing left is how to read on pin so we tin read data from sensors or fifty-fifty the mighty push-button, to read the state of a digital pin configured equally input, we will used a 3rd register called PINx, where over again ten is the port name of where the pin is located, so first using DDRx we say to the micro-controller that we desire some pins as digital inputs, then using PINx we read their values, seems easy right, then lets dig into the code:

DDRD = 0b00000000;    //All pins in PORTD are inputs char my_var = 0;    //Create a variable to shop the data read from PORTD my_var = PIND;        //Read the PORTD and put the values in the variable        

Its every bit like shooting fish in a barrel equally it can exist, and when compared with the Arduino digitalWrite and  Read functions, using direct port access you save space in flash and besides win a lot of speed, considering the Arduino functions can take more than 40 clock cycles to read or write a single fleck in a port and the same fourth dimension to read some other single bit, and the code is pretty circuitous with a load of lines that occupy at least some 40 bytes, it might be a small save in flash but its a huge steep to speed up any program, but they are easy to use by the people that don't understand a lot about programming/micro-controllers, and then every implementation as its advantages and drawbacks, but lets continue.

Its a bit uncommon that you lot demand to read or write a total port at each fourth dimension, for case if yous want to lite a led, or to read a push nosotros but need to use one pivot, and writing all those bits one by i every time that nosotros want to change a value in a PORT is a boring task, just the AVR lib-c as some little squeamish defined Px0..7 "words" where x is again the port that nosotros want to use and 0..vii is the value of the private pivot of the said port, then to lite a led we would do something like this:

DDRD = (1<<PD2);    //Pin two of portd is an output PORTD = (one<<PD2);    //Pivot 2 of portd as at present the logic value ane        

Or reading a push button value:

DDRD = 0b11111101;        //Pin 1 of PORTD is an input, all others are outputs char my_var = 0;        //Create a variable to shop the data read from PORTD my_var = (PIND & (ane<<PD1));    //Read the PORTD pin 1 value and put it in the variable        

We can also use this Px0..seven matter multiple times in a statement, for example in this slice of lawmaking, at that place will be some code executed only if two buttons are pressed at the same time:

DDRD = 0b11111100;        //Portd pins 0 and 1 are inputs, all the others are outputs if(PIND & ((ane<<PD0) | (ane<<PD1))){  //Lawmaking inside the if() statement volition be executed when both buttons are high }        

I think that you lot are getting the signal, only the bit manipulation tutorial volition assist a flake nigh this subjects
There is yet some more than things that we can do with our input and output pins/ports that is very useful for i2c interfaces, and for case to utilize buttons, I'm talking well-nigh the pull-ups that our micro-controller and inside it and I will bear witness you how you can enable them and why should you utilize them when using push-buttons.

When you lot have a push button-button it can have ii states, one is disconnected, and when you push information technology it will brand the connection between the micro-controller pivot and lets say, ground, but when it is disconnected there is cypher forcing a stable value in the input pin, to the untrained middle we could assume that the pin will be reading i, because when we printing the button it read 0, only the fact is that the pin can read either 1's or 0's because the pivot is very sensitive to electro-magnetic noise, much similar a fiddling antenna, so we can solve this problem in two similar ways, one is to adhere a resistor of 10Kohms or more between the Vcc(+5v) and the input pin, or just save some pennies and use the integrated pull-ups that our micro-controller as to offer, it also makes our circuits a chip simpler and that's besides a good affair.

To enable the pull-ups we need to exercise something that may seem a bit strange at the commencement look,because there is no dedicated register to enable or disable the pull-ups, their are enabled or disabled writing respectively 1 or 0 to the PORTx annals when the DDRx register is configured as inputs, lets see some code to clarify this:

DDRD = 0b00000000;    //All pins in PORTD are inputs PORTD = 0b00001111;    //Pull-ups enabled in the pins 0,1,2 and 3 and pull-ups disabled in pins 4,5,6 and vii char my_var = 0;        //Create a variable to store the information read from PORTD my_var = PIND;        //Read the PORTD and put the values in the variable        

If yous execute this code with nothing fastened to PORTD, the 4 high bits of the my_var variable may take ane's or 0's or any possible combination of them because they are floating(acting like little antennas), but the 4 lower $.25 will read all 1'southward because the pull-ups impose a weak 5v point that is read equally a 1 logic value.

In a basic sense this is all you demand to know to master the straight port manipulation just the bit manipulation tutorial will teach you more than things about swell things similar bitmask'southward, AND,OR, Non and XOR operations and how to set and clearer $.25 in a register and some prissy tricks nigh the shift left and shift right operations, all good things to know every bit they tin speed upwards your program and are handy when using the digital ports.

Lets now make a minor examination program that will have use of the digital inputs and outputs and also the pull-ups, considering this as been a very theoretical tutorial its nice to come up to the end and blink some leds!
This is the pseudo-lawmaking for our program, its intent is to read a switch and every-time that the switch is read information technology will toggle a led, so yous printing ounce and the led lights up, printing over again and the led goes off, and again from the start, this could be washed using some if's conditions just tin can be washed in a single line using the powerful XOR(^) operator.

Main{  Configure the pins, in this case code, I volition use PORTD  Space loop{  Read button value  If led is on and button==ane turn led off  If led is off and button==one turn led on  }  }        

Just ane more matter(I know I'1000 ever going a bit off-topic, but this i is important) when we use a push button wired to a digital input nosotros must be aware that a push-button doesn't give a nice and make clean transition from 0 to ane of from 1 to 0, only instead the indicate as some ringing and bouncing, this is due to the mechanical proprieties of the button and not a design flaw, the button as small metal reed inside, and when we press it the reed closes and close the circuit between its input and output just this reed will oscillate a fleck until it rests firmly in its stop, so we must take care of this, and equally usual there are 2 ways, using a small capacitor near the button to debounce the value, or brand this very aforementioned debouncing in lawmaking, which is easier to do when nosotros have a lot of buttons and again is cheaper than adding a lot of caps to our circuit.

If you google the terms button debouncing you will find a not bad variety of ways to debounce buttons in lawmaking, the way that I will use hither is the simplest of all, its just a small filibuster inserted between consecutive reads of the button, this is of course a blocking method considering our micro-controller will just end and sit there delaying for some miliseconds, there are smarter means that employ timers and other smart tricks but for 2-3 buttons and projects that don't need super precise timing this is a commonly used method.

To do this delay I will utilize the congenital-in delay routines provided by the AVR lib-c.
So lets showtime coding, all the code is straight forward if you understood everything that was written above.

#include <avr/io.h>        //This is our usual include #define F_CPU 16000000UL    //This says to the compiler at what frequency our Atmega is running, in this case its 16Mhz #include <util/filibuster.h>        //The delay functions/routines  uint8_t readButton(void);    //Declaration of the readButton office  int main(void){ DDRD &= ~(1<<PD2);    //Configure PORTD pivot ii every bit an input PORTD |= (i<<PD2);    //Activate pull-ups in PORTD pin 2 DDRB |= (1<<PB5);    //Configure PORTB pivot 5 an output, this is the digital 13 in the Arduino that equally the congenital-in led   while(1){                //Infinite loop  if(readButton()==1){        //Verify the button state  PORTB ^=(1<<PB5);    //This is the in a higher place mentioned XOR that toggles the led  }  _delay_ms(250);            //Delay betwixt consecutive button presses  } }  uint8_t readButton(void){  if((PIND & (1<<PD2)) == 0){        //If the button was pressed  _delay_ms(25); }        //Debounce the read value  if((PIND & (i<<PD2)) == 0){        //Verify that the value is the same that what was read  return 1; }            //If it is withal 0 its because we had a push press  else{                    //If the value is different the press is invalid  return 0; }  }        

I think that at that place is no need to prove how to create the project in AvrStudio at this point, but if you accept whatsoever doubts consult the other tutorials or exit a comment, and don't forget to press the reset button when you want to upload your code.
I also don't have a circuit schematic just I can get one if someone requests information technology, or when I have the fourth dimension to brand ane, the led used is the born led that Arduino equally in Digital pin 13, and the button is also easy, yous connect one of the legs of the button to the PORTD2 pivot, that is digital pin two and the other leg of the button you connect to the ground.

There is here a minor video showing you this code in action, the led doesn't ever toggle, simply this is "normal" because my button as already suffered a bit in its life and I tin can as well printing the button when the long filibuster of 250ms is being executed, but it works and here is the proof:

I have done some corrections to the text, and here is the code in an Avr Studio project ready to compile and upload:

http://code.google.com/p/avr-tutorials/downloads/item?proper noun=port.zip

Cheers for reading and don't forget to comment anything that y'all desire, and adept programming!

How To Read Pind Register,

Source: https://hekilledmywire.wordpress.com/2011/02/23/direct-port-manipulation-using-the-digital-ports-tutorial-part-3/

Posted by: staffordcood1937.blogspot.com

0 Response to "How To Read Pind Register"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel