The Raspberry Pi

Download Report

Transcript The Raspberry Pi

EEE305 Microcontroller Systems
Lecture 9: GPIO on the Raspberry Pi
Teaching resources are at www.eej.ulst.ac.uk
My office 5B18, telephone 028 90 366364
My email [email protected]
Background
The following website was accessed on 25/4/13
http://codeandlife.com/2012/07/03/benchmarking-raspberry-pi-gpio-speed/
This compares the speed of doing GPIO in a variety of ways, at least
for simple output – the examples show how to generate a square
wave by outputting ‘1’s and ‘0’s.
The site concludes
Hence either the BCM2835 or wiringPI libraries look good!
Summary of methods for GPIO from http://codeandlife.com
The details are in the raspberry Pi Wiki at
http://elinux.org/RPi_Low-level_peripherals
Some more examples at
https://sites.google.com/site/semil
leroadt/raspberry-pi-tutorials/gpio
Using /sys/class/gpio “files” is a
useful convenient but slow method
of access from ANY language, there
is also pseudo files in /proc/sys that
can be used in a similar way.
Another alternative for Python are the wiringPi Python
bindings.
C: Maximum performance
The Raspberry Pi Wiki gives a nice C code example for true
hardware-level access to the GPIO. The interfacing is slightly
more difficult, but code isn’t too bad. …[he] took the example
program and simplified the main method after setup_io() to this:
Note you do not need to use the << operator, use 0x10 instead
With a performance of 14MHz this is the fastest; but the code is
complex, there is simpler ways of doing GPIO in C, at “reasonable
speed” I think I favour the wiringPi library, but the BCM2835
library is good too. Time will tell which is “best” In 12 months
time use the one getting more use and with a more vibrant user
forum
BCM2835 C library by Mike McCauley
http://www.airspayce.com/mikem/bcm2835/index.html
It provides functions for reading digital inputs and setting digital outputs, using
SPI and I2C, and for accessing the system timers. Pin event detection is
supported by polling (interrupts are not supported).
There is support at https://groups.google.com/forum/?fromgroups#!forum/bcm2835
Installation
Note that you need to add the option –l bcm2835 when compiling your own
code.
Notes on using BCM2835
Physical Addresses:
Functions bcm2835_peri_read(), bcm2835_peri_write() and bcm2835_peri_s
et_bits() are low level peripheral register access functions. They are designed
to use physical addresses. The library can use other boards as well as the Pi.
In the Pi the base address of the various peripheral registers are available
with the following externals:
•
•
•
•
•
•
•
•
bcm2835_gpio
bcm2835_pwm
bcm2835_clk
bcm2835_pads
bcm2835_spio0
bcm2835_st
bcm2835_bsc0
bcm2835_bsc1
Pin Numbering
• The GPIO pin numbering as used by RPi is different to and inconsistent with the
underlying BCM 2835 chip pin numbering.
• RPi has a 26 pin IDE header that provides access to some of the GPIO pins on
the BCM 2835, as well as power and ground pins. Not all GPIO pins on the BCM
2835 are available on the IDE header.
• RPi Version 2 also has a P5 connector with 4 GPIO pins, 5V, 3.3V and Gnd.
• The functions in this library are designed to be passed the BCM 2835 GPIO pin
number and not the RPi pin number. There are symbolic definitions for each of
the available pins that you should use for convenience. See RPiGPIOPin.
(http://www.airspayce.com/mikem/bcm2835/group__constants.html#ga63c02
9bd6500167152db4e57736d0939 )
• I will not talk about SPI or I2C here, see the original article at
http://www.airspayce.com/mikem/bcm2835/index.html
Benchmarking the BCM code from the codeandspace
website
Compiling the code is done with the -l bcm2835 compiler flag to include the library.
Benchmark code looked like this (note that in Broadcom numbering, GPIO 4 is
P1_07):
bcm2835 documentation on the previous code+ other functions
int bcm2835_init(void);// returns 1 if successful else 0
Initialise the library by opening /dev/mem and getting pointers to the internal memory
for BCM 2835 device registers. You must call this (successfully) before calling any other
functions in this library. If bcm2835_init() fails by returning 0, calling any other function
may result in crashes or other failures. Prints messages to stderr in case of errors. Nb call
bcm2835_close at the end of your program, it is has an end! See OHP 11 for PIN
assignments, e.g #define PIN
RPI_GPIO_P1_07
void bcm2835_gpio_fsel(uint8_t pin,uint8_t mode);// mode can be
BCM2835_GPIO_FSEL_INPT or BCM2835_GPIO_FSEL_OUTP or others…
void bcm2835_gpio_write(uint8_t pin, uint8_t on);// use HIGH or LOW for on
uint8_t bcm2835_gpio_lev(uint8_t pin);// reads level on PIN, returns HIGH/LOW
void bcm2835_delay(unsigned int millis); // uses the nanosleep system call – RTFM
void bcm2835_delayMicrosecs(uint64_t micros); // delays are approx for both of these
The functions above are enough to use simple i/o on the rPi – I list some miscellaneous
snippets on the overheads following to give you the flavour of the full library
Guide to size of bcm2835 library – see website
RPI_GPIO_P1_03
Version 1, Pin P1-03.
RPI_GPIO_P1_05
Version 1, Pin P1-05.
RPI_GPIO_P1_07
Version 1, Pin P1-07.
RPI_GPIO_P1_08
Version 1, Pin P1-08, defaults to alt function 0 UART0_TXD.
RPI_GPIO_P1_10
Version 1, Pin P1-10, defaults to alt function 0 UART0_RXD.
RPI_GPIO_P1_11
Version 1, Pin P1-11.
RPI_GPIO_P1_12
Version 1, Pin P1-12.
RPI_GPIO_P1_13
Version 1, Pin P1-13.
RPI_GPIO_P1_15
Version 1, Pin P1-15.
RPI_GPIO_P1_16
Version 1, Pin P1-16.
RPI_GPIO_P1_18
Version 1, Pin P1-18.
RPI_GPIO_P1_19
Version 1, Pin P1-19, MOSI when SPI0 in use.
RPI_GPIO_P1_21
Version 1, Pin P1-21, MISO when SPI0 in use.
RPI_GPIO_P1_22
Version 1, Pin P1-22.
RPI_GPIO_P1_23
Version 1, Pin P1-23, CLK when SPI0 in use.
RPI_GPIO_P1_24
Version 1, Pin P1-24, CE0 when SPI0 in use.
RPI_GPIO_P1_26
Version 1, Pin P1-26, CE1 when SPI0 in use.
RPI_V2_GPIO_P1_03
Version 2, Pin P1-03.
RPI_V2_GPIO_P1_05
Version 2, Pin P1-05.
RPI_V2_GPIO_P1_07
Version 2, Pin P1-07.
RPI_V2_GPIO_P1_08
Version 2, Pin P1-08, defaults to alt function 0 UART0_TXD.
RPI_V2_GPIO_P1_10
Version 2, Pin P1-10, defaults to alt function 0 UART0_RXD.
RPI_V2_GPIO_P1_11
Version 2, Pin P1-11.
RPI_V2_GPIO_P1_12
Version 2, Pin P1-12.
RPI_V2_GPIO_P1_13
Version 2, Pin P1-13.
RPI_V2_GPIO_P1_15
Version 2, Pin P1-15.
RPI_V2_GPIO_P1_16
Version 2, Pin P1-16.
RPI_V2_GPIO_P1_18
Version 2, Pin P1-18.
RPI_V2_GPIO_P1_19
Version 2, Pin P1-19, MOSI when SPI0 in use.
RPI_V2_GPIO_P1_21
Version 2, Pin P1-21, MISO when SPI0 in use.
RPI_V2_GPIO_P1_22
Version 2, Pin P1-22.
RPI_V2_GPIO_P1_23
Version 2, Pin P1-23, CLK when SPI0 in use.
RPI_V2_GPIO_P1_24
Version 2, Pin P1-24, CE0 when SPI0 in use.
RPI_V2_GPIO_P1_26
Version 2, Pin P1-26, CE1 when SPI0 in use.
RPI_V2_GPIO_P5_03
Version 2, Pin P5-03.
RPI_V2_GPIO_P5_04
Version 2, Pin P5-04.
RPI_V2_GPIO_P5_05
Version 2, Pin P5-05.
RPI_V2_GPIO_P5_06
Version 2, Pin P5-06.
Some notes on the hardware
see http://elinux.org/RPi_Low-level_peripherals
GPIO voltage levels are 3.3 V and are not 5 V tolerant.
All the GPIO pins can be reconfigured to provide alternate functions,
SPI, PWM, I²C and so.
At reset only pins GPIO 14 & 15 are assigned to the alternate function
UART, these two can be switched back to GPIO to provide a total of 17
GPIO pins[3].
You must not drive a 3.3V GPIO input from a 5 Volt chip output.
You can drive a 5 volt chip with a 3.3 Volt output from the GPIO.
Use level shifter ICs, or potential dividers or open collector transistors.
Rev.2 boards (>sept ‘12) have an extra connector with 4 more GPIO
and some changes to P1 (pins 3,5 become the second I2C, pin 13
chnages from GPIO21 to GPIO27)
WiringPI: (writted to be easy for arduino programmers)
see https://projects.drogon.net/raspberry-pi/wiringpi/
Pin numbering
• WiringPi supports both an Arduino style pin
numbering scheme which numbers the pins
sequentially from 0 upwards, as well as the
Raspberry Pi’s native BCM_GPIO pin
numbering scheme.
• Note that when using the BCM_GPIO
numbering scheme, you must take into
account the board revision! Some pins
changed their meaning and numbers from
revision 1 to revision 2.
• So Arduino pin 7 is actually GPIO 4, see the
next slide.
• Different Arduino boards use different AVR
chips with differently named PORTS and I/O
pins. But the PCB connectors are kept the
same and the language uses the PCB
numbers not the PORT and PIN numbers
The following tables give
the mapping of the
Raspberry Pi GPIO Pins to
the GPIO connector in
relation to the pin
numbers and the physical
location on the connector.
This is a representation of
the GPIO connector as
viewed looking at the
board from above, with
the USB power at the top
and the GPIO to the topright of the board.
If using the connector pin
numbering, then note that
Pin 1 on the connector is
the 3.3v supply. Pin 2 is
the 5V supply, and pin 26
is marked CE1 below.
Rev 1 boards are marked R1 (3 pins differ on Rev 2 boards)
WiringPi functions
https://projects.drogon.net/raspberry-pi/wiringpi/functions/
Before using the WiringPi library, you need to include its header file:
#include <wiringPi.h>
You may also need to add
-I/usr/local/include -L/usr/local/lib -lwiringPi
to the compile line of your program depending on the environment you are using. The
important one is -lwiringPi
Setup Functions
there are three ways to initialise wiringPi. int wiringPiSetup (void) ; int wiringPiSetupGpio
(void) ; or int wiringPiSetupSys (void) ;
I will describe wiringPiSetup(void) ;
This initialises the wiringPi system and assumes that the calling program is going to be using
the wiringPi pin numbering scheme.
This is a simplified numbering scheme which provides a mapping from virtual pin numbers 0
through 16 to the real underlying Broadcom GPIO pin numbers. See the pins page for a
table which maps the wiringPi pin number to the Broadcom GPIO pin number to the
physical location on the edge connector.
This function needs to be called with root privileges.
General wiring functions
void pinMode(int pin, int mode) ;
This sets the mode of a pin to either INPUT, OUTPUT, or PWM_OUTPUT. Note that
onlywiringPi pin 1 (BCM_GPIO 18) supports PWM output. The pin number is the
number obtained from the pins table. (int p
void digitalWrite (int pin, int value) ;
Writes the value HIGH or LOW (1 or 0) to the given pin which must have been
previously set as an output.
int digitalRead (int pin) ;
This function returns the value read at the given pin. It will be HIGH or LOW (1 or 0)
depending on the logic level at the pin.
There are also functions to write bytes and setup pwm values as well as controlling
activation of pullup or pull down resistors on individual pins. There are some useful
timing functions as well; void delay(unsigned int milliseconds) and void
delayMicroseconds(unsigned int micros) do what you would expect. The function
unsigned int millis(void) returns the number of milliseconds since you called Setup
Simple installation
https://projects.drogon.net/raspberry-pi/wiringpi/download-and-install/
Click on the word snapshot on the righthand side of the page:
https://git.drogon.net/?p=wiringPi;a=summary
This downloads a tar.gz file with a name like wiringPi-98bcb20.tar.gz. Note that the numbers
and letters after wiringPi (98bcb20 in this case) will probably be different – they’re a unique
identifier for each release.
You then need to do this to install:
tar xfz wiringPi-98bcb20.tar.gz
cd wiringPi-98bcb20
./build
Remember the actual filename will be different – you will have to check the name and adjust
accordingly.
Test wiringPi’s installation
run the gpio command to check the installation: (you need to be root to do this)
gpio -v
gpio readall
That should give you some confidence that it’s working OK.
The GPIO utility
You can use the gpio command from the command line once you install the
wiringPi library. – it supports thePiFACE interface board as well as the GPIO
pins.
Run man gpio to see the options, gpio –v gives the version number
Using –g as an argument allows pin numbers to be interpreted as BCM_GPIO
rather than wiringPI numbers
gpio [-g] mode <pin> in/out/pwm/up/down/tri
This sets the mode of a pin to be input, output or pwm and additionally can
set the internal pull-up/down resistors to pull-up, pull-down or none.
gpio [-g] write <pin> 0/1
This sets an output pin to high (1) or low (0)
gpio [-g] read <pin>
Reads and prints the logic value of the given pin. It will print 0 (low) or 1
(high).
Examples of command line gpio
gpio mode 0 out
gpio write 0 1
This uses the wiringPi pin numbers to set pin 0
as an output and then sets the pin to a logic 1.
gpio -g mode 0 in
gpio -g read 0
This uses the BCM_GPIO pin numbering scheme
and reads pin 0 (SDA0 on a Rev. 1 Raspberry Pi)
PiFace Commands (if you have a board!)
• The PiFace is somewhat limited in that it has 8 inputs pins
and 8 output pins and these are fixed in the hardware, so
only the write and read commands are implemented:
gpio -p write <pin> 0/1
• Writes the value 0 (off) or 1 (on) to the output pin on the
PiFace
gpio -p read <pin>
• Reads and prints the value on the given input pin.
gpio -p mode <pin> up/tri
• This enables (up) or disables (tri) the internal pull-up
resistor on the given input pin. You need to enable the
pull-up if you want to read any of the on-board switches
on the PiFace board.
The PiFACE:
http://piface.openlx.org.uk/
PiFace Digital communicates to the Raspberry Pi using the SPI
interface. The SPI interface driver is included in the later
Raspbian distributions but is not enabled by default. You can
always enable the SPI driver, or you can load it by hand when
required.
Always enabling SPI
To always enable the SPI driver:
After logging in, edit /etc/modprobe.d/raspi-blacklist.conf
sudo nano etc/modprobe.d/raspi-blacklist.conf
Insert a # at the start of the line containing blacklist spibcm2708
#blacklist spi-bcm2708
Alternatively, to load the SPI driver by hand (will not be loaded
on reboot):
Type in a terminal:
sudo modprobe spi-bcm2708
Next, you we need to install the PiFace Digital libraries and change
the permissions of the SPI interface. The following script
automates this into one command. To install and setup the
software, ensure your Pi can access the Internet and type:
sudo apt-get update
wget -O - http://pi.cs.man.ac.uk/download/install.txt | bash
The software will complete installing in a few minutes.
Reboot your Pi by typing:
sudo reboot
Testing use GPIO or
After installing the
software and
restarting,
login and startx.
Start the PiFace
emulator by typing
in a terminal:
piface/scripts/piface-emulator
http://piface.openlx.org.uk/ see also https://www.modmypi.com/piface-digital-raspberry-pi-expansion-board
Suggested experiments (without PiFace)
• Wire up an LED to a couple of GPIO pins (and
3.3V thru a 120 Ohm resistor. Get it blinking!
• Wire up a 7 segment display and get it
displaying, you’ll need 7 series resistors.
• Wire up a keypad, 4 lines for output and 4 lines
for input. You will need series resistors on the
output and pulldowns on the inputs (in case you
hit two keys and short outputs together)
• Write code that inputs a 4 digit number and then
displays it, decrementing at once per second.
The series resistors
Are in case you hit two
keys at once (in the
same column)
That would short two
outputs together. R1-R4
can be 330 Ohms to
limit the current to
10mA. The pulldowns
can be any value higher
than a k (so that the
potential divider being
formed still causes a ‘1’
to be read)