Raspberry Pi Developer's Guide: GPIO
GPIO (General Purpose Input/Output) pins on the Raspberry Pi
Overview
This page expands on the technical features of the GPIO pins available on BCM2835 in general.For usage examples, see the GPIO Usage section.
When reading this page, reference should be made to the BCM2835 ARM Peripherals Datasheet, section 6.
GPIO pins can be configured as either general-purpose input, general-purpose output or as one of up to 6 special alternate settings, the functions of which are pin-dependent.
There are 3 GPIO banks on BCM2835.
Each of the 3 banks has its own VDD input pin.
On Raspberry Pi, all GPIO banks are supplied from 3.3V.
Connection of a GPIO to a voltage higher than 3.3V will likely destroy the GPIO block within the SoC.
A selection of pins from Bank 0 is available on the P1 header on Raspberry Pi.
Power-ON States
All GPIOs revert to general-purpose inputs on power-on reset.The default pull states are also applied, which are detailed in the alternate function table in the ARM peripherals datasheet.
Most GPIOs have a default pull applied.
Interrupts
Each GPIO pin, when configured as a general-purpose input, can be configured as an interrupt source to the ARM.Several interrupt generation sources are configurable:
- Level-sensitive (high/low)
- Rising/falling edge
- Asynchronous rising/falling edge
The normal rising/falling edge detection has a small amount of synchronisation built into the detection.
At the system clock frequency, the pin is sampled with the criteria for generation of an interrupt being a stable transition within a 3-cycle window, i.e. a record of "1 0 0" or "0 1 1". Asynchronous detection bypasses this synchronisation to enable the detection of very narrow events.
Alternative Functions
Almost all of the GPIO pins have alternative functions.Peripheral blocks internal to BCM2835 can be selected to appear on one or more of a set of GPIO pins, for example the I2C buses can be configured to at least 3 separate locations.
Pad control, such as drive strength or Schmitt filtering, still applies when the pin is configured as an alternate function.
For more detailed information see the Low level peripherals page on the elinux wiki
GPIO Pads
The GPIO connections on the BCM2835 package are sometimes referred to in the peripherals datasheet as "pads" - a semiconductor design term meaning "chip connection to outside world".The pads are configurable CMOS push-pull output drivers/input buffers. Register-based control settings are available for
- Internal pull-up / pull-down enable/disable
- Output drive strength
- Input Schmitt-trigger filtering
Version 2 has pin 27 replacing pin 21 but it otherwise the same.
The latest Pinouts:
The numbering
- BCM Broadcom pin number, commonly called "GPIO", these are the ones you probably want to use with RPi.GPIO and GPIO Zero
- WiringPi Wiring Pi pin number (shown as a tooltip), for Gordon Henderson's Wiring Pi library. WiringPi is a PIN based GPIO access library written in C for the BCM2835 used in the Raspberry Pi.
- Physical Number corresponding to the pin's physical location on the header
- Rev 1 Pi Alternate BCM numbers for the original, 26-pin model "A" and "B" Pi
As well as supplying power (GND, 3.3V and 5V) all the GPIO pins can be used as either digital inputs or outputs. The pins labelled SCL and SDA can be used for I2C. The pins labelled MOSI, MISO and SCKL can be used to connect to high speed SPI devices.
Of the 40 pins, 26 are GPIO pins and the others are power or ground pins (plus two ID EEPROM pins which you should not play with unless you know your stuff!)
All the pins have 3.3V logic levels and are not 5V-safe so the output levels are 0-3.3V and the inputs should not be higher than 3.3V. If you want to connect a 5V output to a Pi input, use a level shifter.
A popular way to actually make the connections to the Raspberry Pi is to use a Pi Cobbler.
This uses a ribbon cable to connect the GPIO connector to solderless breadboard, where you can add your own components.
Configuring The GPIO Serial Port
UART and RS-232
RS 232 voltage levels defined for transmitters and receivers :
SIGNAL VOLTAGE LEVELS VOLTS | LOGICAL STATE |
---|---|
-3 to -25 | 1 |
+3 to +25 | 0 |
Most microcontrollers these days have built in UARTs (universally asynchronous receiver/transmitter) that can be used to receive and transmit data serially.
This method of serial communication is sometimes referred to as TTL(transistor-transistor logic) serial . Serial communication at a TTL level will always remain between the limits of 0V and Vcc, which is often 5V or 3.3V. A logic high ('1') is represented by Vcc, while a logic low ('0') is 0V.
The UART and RS-232 differ solely at a hardware level:
By the RS-232 standard a logic high ('1') is represented by a negative voltage – anywhere from -3 to -25V, while a logic low ('0') transmits a positive voltage that can be anywhere from +3 to +25V. On most PCs these signals swing from -13 to +13V.
The more extra voltages of an RS-232 signal help to make it travel longer physical distances than their TTL counterparts, while still providing a reliable data transmission.
The following timing diagram shows both a TTL (bottom) and RS-232 signal sending 0b01010101:
Therefore, to connect UART and RS-232 ports, you not only have to invert the signals, but you also have to deal with regulating the potentially harmful RS-232 voltages to something that won't destroy a micro-controller's serial pins.
There are a handful of solutions to this problem of voltage converting and inverting.
USB-serial TTL adaptor
The USB TTL Serial cables are a range of USB to serial converter cables which provide connectivity between USB and serial UART interfaces. A range of cables are available offering connectivity at 5V, 3.3V or user specified signal levels with various connector interfaces.
- FTDI Basic(USB轉TTL FT232) The FT232R is a USB to serial UART interface
- 採用FTDI公司的FT232RL晶片
- 帶3個LED:TXD 、RXD 、POWER
- USB供電,支持3種供電模式:5V對外供電;3.3V對外供電;由外部供電(要求3.3V-5V)
- Broadcom's BCM9SERIAL_ADPT uses FT4232H
- a USB 2.0 High Speed (480Mb/s) to UART/MPSSE ICs
- Single chip USB to quad serial ports with a variety of configurations.
- +1.8V (chip core) and +3.3V I/O interfacing (+5V Tolerant).
- +3.3V single supply operating voltage range.
UART on the Raspberry Pi
The SoCs used on the Raspberry Pis have two built-in UARTs,
- UART0: Full UART (/dev/ttyAMA0)
- Based on ARM Primecell PL011
- Larger FIFO buffers
- 16x8 transmit, 16x12 receive
- High performance full feature serial
- UART1: “mini UART” (/dev/ttyS0)
- A secondary low throughput UART
- 8 symbols deep FIFOs for receive and transmit
- Baudrate derived from system clock
The Bluetooth on Raspberry Pi 3/4
Pi 3 | Pi 4 | |
SoC | BCM2837 | BCM2711 (quad-core CPU design of the BCM2837) |
Wireless chip | BCM43438(CYW43438) | BCM43455(CYW43455) |
How to Connect Raspberry Pi with a Serial Console
By default,
- On Raspberry Pis equipped with the wireless/Bluetooth module (Raspberry Pi 3/4 and Raspberry Pi Zero W), the PL011 UART is connected to the Bluetooth module, while the mini UART is used as the primary UART and will have a Linux console on it.
- On all other models, the PL011 is used as the primary UART.
- UART0, /dev/ttyAMA0 /dev/ttyAMA0 refers to the PL011
- UART1, /dev/ttyS0 /dev/ttyS0 refers to the mini UART
The primary UART is the one assigned to the Linux console, which depends on the Raspberry Pi model as described above.
There are also symlinks: /dev/serial0, which always refers to the primary UART (if enabled), and /dev/serial1, which similarly always refers to the secondary UART (if enabled).
By default, the UART transmit and receive pins are on GPIO 14 and GPIO 15 respectively, which are pins 8 and 10 on the GPIO header.
序列傳輸介面至少需要有三條線,包括接地(GND)、接收(RX)和傳送(TX),參考接線圖如下:
The mini UART has smaller FIFOs. Combined with the lack of flow control, this makes it more prone to losing characters at higher baudrates. It is also generally less capable than the PL011, mainly due to its baud rate link to the VPU clock speed.
/dev/ttyAMA0 was a hardware serial port (uart) and high performance .
The baud rate of the mini UART is derived from the core frequency of the VPU on the VC4 GPU.
- If the PL011 UART is selected for use as the serial console UART This application is for full UART and Slow Bluetooth or BLE. By default, it will be disabled. To enable it on Pi, add the following line to config.txt,
enable_uart=1
To use bluetooth, the following 2 lines need to be added to /boot/config.txt, dtoverlay=pi3-miniuart-bt core_freq=250This will also fix the core frequency to 250MHz (unless force_turbo is set, when it will be fixed to the VPU turbo frequency). Device Tree Overlay(DTO) is used to remap the pins. “pi3-miniuart-bt” uses the mini-uart (/dev/ttyS0) for Bluetooth.
enable_uart=1 core_freq=250otherwise the mini UART will not work. As Raspberry Pi 4 which is not working for the following environment:
$ cat cmdline.txt console=serial0,115200 console=tty1 root=PARTUUID=6c586e13-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait $ dmesg | grep tty [ 0.000000] Kernel command line: coherent_pool=1M 8250.nr_uarts=1 cma=64M cma=256M smsc95xx.macaddr=DC:A6:32:7A:CD:B8 vc_mem.mem_base=0x3ec00000 vc_mem.mem_size=0x40000000 console=ttyS0,115200 console=tty1 root=PARTUUID=6c586e13-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait [ 0.000698] console [tty1] enabled [ 0.390957] fe201000.serial: ttyAMA0 at MMIO 0xfe201000 (irq = 34, base_baud = 0) is a PL011 rev2 [ 0.397116] console [ttyS0] disabled [ 0.397162] fe215040.serial: ttyS0 at MMIO 0x0 (irq = 36, base_baud = 62500000) is a 16550 [ 1.554301] console [ttyS0] enabled $ sudo ls -l /dev | grep serial lrwxrwxrwx 1 root root 5 May 8 21:19 serial0 -> ttyS0 lrwxrwxrwx 1 root root 7 May 8 21:19 serial1 -> ttyAMA0 $ ps aux | grep tty root 567 0.0 0.0 4308 1276 tty1 Ss+ 22:32 0:00 /sbin/agetty -o -p -- \u --noclear tty1 linux root 568 0.0 0.0 6616 1580 ttyS0 Ss+ 22:32 0:00 /sbin/agetty -o -p -- \u --keep-baud 115200,38400,9600 ttyS0 vt220 pi 683 0.0 0.0 4884 544 pts/0 S+ 22:35 0:00 grep --color=auto tty
After appending the following 2 lines in /boot/config.txt,
enable_uart=1 core_freq=250
The console is working:
[ 198.093681] reboot: Restarting system [ 0.000000] Booting Linux on physical CPU 0x0 [ 0.000000] Linux version 4.19.97-v7l+ (dom@buildbot) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611)) #1294 SMP Thu Jan 30 13:21:14 GMT 2020 [ 0.000000] CPU: ARMv7 Processor [410fd083] revision 3 (ARMv7), cr=30c5383d ... [ 0.000000] Kernel command line: coherent_pool=1M 8250.nr_uarts=1 cma=64M cma=256M smsc95xx.macaddr=DC:A6:32:7A:CD:B8 vc_mem.mem_base=0x3ec00000 vc_mem.mem_size=0x40000000 earlyprintk console=ttyS0,115200 console=tty1 root=PARTUUID=6c586e13-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait ... [ 0.000247] Console: colour dummy device 80x30 [ 0.000700] console [tty1] enabled ... [ 0.031062] Serial: AMBA PL011 UART driver ... [ 0.288176] Serial: 8250/16550 driver, 1 ports, IRQ sharing enabled ... [ 0.396587] Loading compiled-in X.509 certificates [ 0.404248] uart-pl011 fe201000.serial: cts_event_workaround enabled [ 0.404328] fe201000.serial: ttyAMA0 at MMIO 0xfe201000 (irq = 34, base_baud = 0) is a PL011 rev2 [ 0.409694] console [ttyS0] disabled [ 0.409742] fe215040.serial: ttyS0 at MMIO 0x0 (irq = 36, base_baud = 31250000) is a 16550 [ 1.567811] console [ttyS0] enabled ... Raspbian GNU/Linux 10 raspberrypi ttyS0 raspberrypi login: pi Password: Last login: Sat May 9 14:06:46 CST 2020 on ttyS0 Linux raspberrypi 4.19.97-v7l+ #1294 SMP Thu Jan 30 13:21:14 GMT 2020 armv7l The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. pi@raspberrypi:~$
In a default install of Raspbian, the primary UART (serial0) is assigned to the Linux console. Using the serial port for other purposes requires this default behaviour to be changed. Kernel Command-Line:
- earlyprintk For kernel development/testing, and are experiencing early boot problems.
- console=serial0 Use the serial console.
- console=tty0 To use a virtual terminal console (HDMI/USB keyboard).
Disabling the Serial Console
To use the serial port as a terminal to log in, you need to enable the serial port for “console” login which is serviced by “getty”.If you are using the serial port and want to disable the console login, you needs to disable the console login service.
The console login service is related to the serial port, to disable the service:
- /dev/ttyAMA0
$ sudo systemctl stop serial-getty@ttyAMA0.service $ sudo systemctl disable serial-getty@ttyAMA0.service
$ sudo systemctl stop serial-getty@ttyS0.service $ sudo systemctl disable serial-getty@ttyS0.service
How to setup a serial connection with Pi
Ubuntu Linux Installation Guide for FTDI
- To get the USB VendorID and ProductID After the USB serial adaptor is plugged, query information about currently plugged USB devices:
$ sudo lsusb [sudo] password for jerry: Bus 002 Device 006: ID 0a5c:5801 Broadcom Corp. BCM5880 Secure Applications Processor with fingerprint swipe sensor Bus 002 Device 028: ID 047f:c009 Plantronics, Inc. Bus 002 Device 036: ID 0403:6011 Future Technology Devices International, Ltd FT4232H Quad HS USB-UART/FIFO IC ...For the FTDI Basic(USB轉TTL FT232),
Bus 002 Device 006: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC
# For FTDI FT232 & FT245 USB devices with Vendor ID = 0x0403, Product ID = 0x6011
SYSFS{idProduct}==”6011”, SYSFS{idVendor}==”0403”, RUN+=”/sbin/modprobe –q ftdisio product=0x6011 vendor=0x0403”
Note that “0x6011” is a value for the PID; you will enter the PID assigned to you from FTDI. For a VID assigned by the USB-IF, also modify the “idVendor” value above to match the assigned VID.
sudo udevadm control --reload-rules
sudo udevadm trigger
dmesg | grep FTDI
[135271.322122] usb 2-1.2: Manufacturer: FTDI [135271.324167] ftdi_sio 2-1.2:1.0: FTDI USB Serial Device converter detected [135271.324688] usb 2-1.2: FTDI USB Serial Device converter now attached to ttyUSB0 [135271.326515] ftdi_sio 2-1.2:1.1: FTDI USB Serial Device converter detected [135271.326948] usb 2-1.2: FTDI USB Serial Device converter now attached to ttyUSB1 [135271.328745] ftdi_sio 2-1.2:1.2: FTDI USB Serial Device converter detected [135271.329176] usb 2-1.2: FTDI USB Serial Device converter now attached to ttyUSB2 [135271.330984] ftdi_sio 2-1.2:1.3: FTDI USB Serial Device converter detected [135271.331401] usb 2-1.2: FTDI USB Serial Device converter now attached to ttyUSB3
sudo apt-get remove brltty
ls /dev/ttyUSB* /dev/ttyUSB0 /dev/ttyUSB1 /dev/ttyUSB2 /dev/ttyUSB3
sudo apt-get install putty
sudo putty
Then, click the "Open" button.
Mac OS X Installation Guide for FTDI
The Mac OS X FTDI USB-Serial driver can be downloaded from the Drivers section of the FTDI web site. Run the installer by double clicking on the FTDI USB-Serial Driver.dmg icon. Click Continue to proceed with the installation and follow the instructions on screen. When the installation is complete, reboot the computer. When the computer has rebooted, plug in the device. If the device is installed properly, you will see entries in the /dev directory:/dev/cu.usbserial-xxxxxxxx /dev/tty.usbserial-xxxxxxxxMake sure you can find dev/cu.usbserial-xxxxxxxx Then, use the following to connect the Pi's console:
screen /dev/cu.usbserial 115200As Raspberry Pi model 3+ as an example, the Broadcom's serial adaptor is used:
$ ls /dev/tty.usb*
/dev/tty.usbserial-100_1216230 /dev/tty.usbserial-100_1216232 /dev/tty.usbserial-100_1216231 /dev/tty.usbserial-100_1216233
screen /dev/tty.usbserial-100_1216232 115200
Adafruit Console Lead
This cable has 3.3V logic levels so its safe to use, but not all cables are 3.3V! Only use the Adafruit console cable for this tutorial to avoid damaging your Pi's GPIO pins. The Console lead has four female connections that can be plugged directly onto the GPIO header of the Raspberry Pi.For this experiment, the serial lead is going to power the Raspberry Pi. So, DO NOT attach the Pi's USB power adapter. If you would rather power the Pi from your USB power adapter then leave the Red lead from the Serial lead un-attached. The important thing here is to only power it from one source, the USB power adaptor or the Console Lead BUT NOT BOTH. Attach the leads as shown below:
- The red lead should be connected to 5V
- The black lead to GND,
- The white lead to TXD.
- The green lead to RXD.
Install Python Module RPi.GPIO
The RPi.GPIO python module offers easy access to the general purpose IO pins on the Raspberry Pi.
sudo apt-get install python-dev python-rpi.gpio
raspberry-gpio-python
Inputs
There are several ways of getting GPIO input into your program. The first and simplest way is to check the input value at a point in time. This is known as 'polling' and can potentially miss an input if your program reads the value at the wrong time. Polling is performed in loops and can potentially be processor intensive. The other way of responding to a GPIO input is using 'interrupts' (edge detection). An edge is the name of a transition from HIGH to LOW (falling edge) or LOW to HIGH (rising edge).Pull up / Pull down resistors
Pull up / Pull down resistors If you do not have the input pin connected to anything, it will 'float'. In other words, the value that is read in is undefined because it is not connected to anything until you press a button or switch. It will probably change value a lot as a result of receiving mains interference. To get round this, we use a pull up or a pull down resistor. In this way, the default value of the input can be set. It is possible to have pull up/down resistors in hardware and using software. In hardware, a 10K resistor between the input channel and 3.3V (pull-up) or 0V (pull-down) is commonly used. The RPi.GPIO module allows you to configure the Broadcom SOC to do this in software:
GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# or
GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
The pull-up/downs supply that voltage so that the gpio will have a defined value UNTIL overridden by a stronger force. You should set a pull-down (to 0) when you expect the stronger force to pull it up to 1. You should set a pull-up (to 1) when you expect the stronger force to pull it down to 0. Inputs polling
while GPIO.input(channel) == GPIO.LOW:
time.sleep(0.01) # wait 10 ms to give CPU chance to do other things
while GPIO.input(channel) == GPIO.LOW: time.sleep(0.01) # wait 10 ms to give CPU chance to do other things Interrupts and Edge detection
An edge is the change in state of an electrical signal from LOW to HIGH (rising edge) or from HIGH to LOW (falling edge). Quite often, we are more concerned by a change in state of an input than it's value. This change in state is an event. To avoid missing a button press while your program is busy doing something else, there are two ways to get round this:- the wait_for_edge() function The wait_for_edge() function is designed to block execution of your program until an edge is detected. In other words, the example above that waits for a button press could be rewritten as:
GPIO.wait_for_edge(channel, GPIO.RISING)
Note that you can detect edges of type GPIO.RISING, GPIO.FALLING or GPIO.BOTH. The advantage of doing it this way is that it uses a negligible amount of CPU, so there is plenty left for other tasks. If you only want to wait for a certain length of time, you can use the timeout parameter:
# wait for up to 5 seconds for a rising edge (timeout is in milliseconds)
channel = GPIO.wait_for_edge(channel, GPIO_RISING, timeout=5000)
if channel is None:
print('Timeout occurred')
else:
print('Edge detected on channel', channel)
GPIO.add_event_detect(channel, GPIO.RISING) # add rising edge detection on a channel
do_something()
if GPIO.event_detected(channel):
print('Button pressed')
Note that you can detect events for GPIO.RISING, GPIO.FALLING or GPIO.BOTH.
def my_callback(channel):
print('This is a edge event callback function!')
print('Edge detected on channel %s'%channel)
print('This is run in a different thread to your main program')
GPIO.add_event_detect(channel, GPIO.RISING, callback=my_callback) # add rising edge detection on a channel
If you wanted more than one callback function:
def my_callback_one(channel):
print('Callback one')
def my_callback_two(channel):
print('Callback two')
GPIO.add_event_detect(channel, GPIO.RISING)
GPIO.add_event_callback(channel, my_callback_one)
GPIO.add_event_callback(channel, my_callback_two)
Note that in this case, the callback functions are run sequentially, not concurrently. This is because there is only one thread used for callbacks, in which every callback is run, in the order in which they have been defined.
- add a 0.1uF capacitor across your switch.
- software debouncing
- a combination of both
# add rising edge detection on a channel, ignoring further edges for 200ms for switch bounce handling
GPIO.add_event_detect(channel, GPIO.RISING, callback=my_callback, bouncetime=200)
or
GPIO.add_event_callback(channel, my_callback, bouncetime=200)
GPIO.remove_event_detect(channel)
留言