樹莓派4B學習札記
防靜電
樹莓派比較容易被靜電損壞,要做好以下預防措施
- 使用的時候不要用手去觸控PCB和針腳!特別是上電之後!
- 拿板卡的時候,要習慣性拿板卡的邊緣
- 勤洗手,勤摸牆壁,釋放身上的靜電
系統安裝
- 8GB以上的Mirco SD卡
- 讀卡器
將SD卡連線到電腦,格式化SD卡
在樹莓派官網下載燒錄程式,從左到右完成設定,寫入SD卡
完成後將SD卡插入卡槽,首次啟動還需要連線鍵盤滑鼠和顯示器(HDMI轉接線),連線電源線後給樹莓派上電,完成初始化設定。
使用命令列查詢樹莓派的硬體引數
檢視CPU資訊
$ lscpu
Architecture: armv7l Byte Order: Little Endian CPU(s): 4 On-line CPU(s) list: 0-3 Thread(s) per core: 1 Core(s) per socket: 4 Socket(s): 1 Vendor ID: ARM Model: 3 Model name: Cortex-A72 Stepping: r0p3 CPU max MHz: 1500.0000 CPU min MHz: 600.0000
檢視記憶體的使用情況。
free -h
檢視SD卡的儲存情況
$ sudo fdisk -l
檢視作業系統的資訊
$ uname -a
Linux raspberrypi 5.10.63-v7l+ #1459 SMP Wed Oct 6 16:41:57 BST 2021 armv7l GNU/Linux
檢視網路介面
$ ifconfig
這個命令很重要!!!
查看板卡資訊
$ pinout
從這裡可用知道這塊樹莓派是Model 4B
型號,BCM2711
,可以去讀對應的官方文件。
區域網遠端桌面
安裝xrdp
檢查樹莓派的網路,使用ping
命令
輸入命令
$ sudo apt-get install xrdp
回車之後會自動進入安裝,安裝完成後輸入命令
$ ifconfig
記住劃線處的IP地址
遠端桌面
在主機,按下win + r
組合鍵,輸入cmd
,回車,ping剛剛加下的地址
確認連通後,按下win + q
,輸入遠端桌面
輸入之前記下的IP地址
輸入使用者名稱pi
和密碼,連線
連線成功!
用遠端桌面來操控樹莓派,可以省去很多麻煩。
需要注意的事項
- 樹莓派和主機需要處在同一個區域網內,連線之前多ping幾次確認連通
- 使用
win + Q
搜尋遠端桌面開啟,輸入使用者名稱pi
注意不要大寫,否則會出現load failed for Display 0
的錯誤
參考
https://shumeipai.nxez.com/2013/10/06/windows-remote-desktop-connection-raspberry-pi.html
SPI匯流排通訊
SPI是什麼
SPI匯流排是一種序列匯流排
MOTOROLA公司的SPI匯流排的基本訊號線為3根傳輸線,即
- MOSI:主片資料輸出和從片資料輸入
- MISO:從片資料輸出和主片資料輸入
- SCK: 主片在這條線上發出SCK頻率,用來決定傳輸速率
主片通過發出片選訊號/cs
來選擇和哪個從片進行通訊,當某個從片的/cs
訊號有效時,便能通過MOSI傳輸線接受指令、資料,並通過MISO傳輸線發回資料。
對具有SPI介面的從片器件來講,SCK、MOSI是輸入訊號,MISO是輸出訊號。
- SCK用於主片和從片通訊的同步
- MOSI用於將資訊傳輸到器件
指令、地址和資料的變化在SCK的低電平期間進行,並由SCK訊號的上升沿鎖存。
- MISO用於將資訊從器件傳出
傳出的資訊包括狀態和資料,資訊在SCK訊號的下降沿送出。
利用SPI匯流排進行自發自收
樹莓派提供了一組GPIO介面,找到MOSI和MISO引腳
在官方文件中進一步查詢得到更多資訊
用一個跳線帽短接MOSI和MISO,讓樹莓派通過SPI匯流排實現自發自收
在樹莓派的終端輸入
$ sudo raspi-config
回車,進入設定介面
![image](https://img20
按下選到3 Interface Options
回車開啟SPI匯流排後,退出設定介面
用命令列建立一個c語言檔案,將下列程式碼貼上到裡面儲存
/*程式碼來源:https://blog.csdn.net/u014357799/article/details/112376163/*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "SPISet.h"
#include <stdint.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>
#include <asm/ioctl.h>
#include <linux/spi/spidev.h>
static const char *spiDev0 = "/dev/spidev0.0";
static const char *spiDev1 = "/dev/spidev0.1";
static uint8_t spiBPW = 8;
static uint16_t spiDelay = 0;
static uint32_t spiSpeeds [2];
static int spiFds [2];
int SPIDataRW ( int channel, unsigned char *tx_data, unsigned char *rx_data, int len );
int SPISetupMode ( int channel, int speed, int mode );
int SPISetup( int channel, int speed );
int initSPI();
int main(){
char tx_Data[] = {1,2,3,4,5,6,7,8,9,10};
char rx_Data[] = {0,0,0,0,0,0,0,0,0,0};
int i = 0;
initSPI();
while(1){
SPIDataRW(0, tx_Data, rx_Data, 10);
printf("read SPI_rx_data is: \n");
for( i = 0; i < 10; i++ ){
printf("%d\t",rx_Data[i]);
}
printf("\n");
sleep(1);
}
return 0;
}
int initSPI(){
int spiFd;
spiFd = SPISetup(0,500000);
if( spiFd == -1 ){
printf("init spi failed!\n");
}
}
int SPIDataRW (int channel, unsigned char *tx_data, unsigned char *rx_data, int len) {
int i = 0;
struct spi_ioc_transfer spi ;
channel &= 1 ;
memset (&spi, 0, sizeof (spi)) ;
spi.tx_buf = (unsigned long)tx_data ;
spi.rx_buf = (unsigned long)rx_data ;
spi.len = len ;
spi.delay_usecs = spiDelay ;
spi.speed_hz = spiSpeeds [channel] ;
spi.bits_per_word = spiBPW ;
return ioctl (spiFds [channel], SPI_IOC_MESSAGE(1), &spi) ; //SPI_IOC_MESSAGE(1)的1表示spi_ioc_transfer的數量
}
int SPISetupMode (int channel, int speed, int mode) {
int fd ;
if ((fd = open (channel == 0 ? spiDev0 : spiDev1, O_RDWR)) < 0) {
printf("Unable to open SPI device: %s\n", strerror (errno)) ;
return -1;
}
spiSpeeds [channel] = speed ;
spiFds [channel] = fd ;
if (ioctl (fd, SPI_IOC_WR_MODE, &mode) < 0) {
printf("Can't set spi mode: %s\n", strerror (errno)) ;
return -1;
}
if (ioctl (fd, SPI_IOC_RD_MODE, &mode) < 0) {
printf("Can't get spi mode: %s\n", strerror (errno)) ;
return -1;
}
if (ioctl (fd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0) {
printf("Can't set bits per word: %s\n", strerror (errno)) ;
return -1;
}
if (ioctl (fd, SPI_IOC_RD_BITS_PER_WORD, &spiBPW) < 0) {
printf("Can't get bits per word: %s\n", strerror (errno)) ;
return -1;
}
if (ioctl (fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0) {
printf("Can't set max speed hz: %s\n", strerror (errno));
return -1;
}
if (ioctl (fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) {
printf("Can't get max speed hz: %s\n", strerror (errno));
return -1;
}
return fd ;
}
int SPISetup (int channel, int speed) {
return SPISetupMode (channel, speed, 0) ;
}
儲存後用gcc
命令編譯生成.out
檔案,執行
取下跳線帽後,再次執行
至此完成了樹莓派通過SPI匯流排自收自發的任務
SPI通訊的最大速率?
留坑
WIFI傳輸資料?
留坑
參考連結
https://blog.csdn.net/u014357799/article/details/112376163
https://panqiincs.me/2020/07/10/rpi-stm32-spi-communication/
官方文件參見
仔細閱讀官方文件是學習樹莓派的必由之路
https://www.raspberrypi.com/documentation/
SD Card for Raspberry Pi
Raspberry Pi computers use a micro SD card, except for very early models which use a full-sized SD card.
WARNING | Because of a hardware limitation in the Raspberry Pi Zero, 1 and 2, the boot partition on the SD card must be 256GB or less otherwise the device will not boot up. Later models of Raspberry Pi 2 with a BCM2837 SoC, Raspberry Pi 3, 4, and Raspberry Pi 400 do not have this limitation. This does not affect Raspberry Pi OS, which always uses a small boot partition. |
---|---|
Recommended Capacity
We recommend using an SD card of 8GB or greater capacity with Raspberry Pi OS. If you are using the lite version of Raspberry Pi OS, you can use a 4GB card. Other operating systems have different requirements: for example, LibreELEC can run from a smaller card. Please check with the supplier of the operating system to find out what capacity of card they recommend.
Troubleshooting
We recommend buying anPi SD card from one of our official resellers. The official SD cards are micro SD cards and are supplied with an adaptor which allows them to be used in a full-sized SD card slot.
If you are having problems with your SD card:
- Make sure you are using a genuine SD card. The best way to avoid fake SD cards is to always buy from a reputable supplier.
- Make sure you are using a good quality power supply: we recommend using an official Raspberry Pi power supply.
- The cable from the power supply unit to the Raspberry Pi can also cause problems. This is usually due to the resistance of the wires in the USB power cable; to save money, USB cables have as little copper in them as possible, which causes a voltage drop across the cable.
- Make sure you shut down the operating system correctly before you power down the Raspberry Pi.
Connecting a Display
Connecting using HDMI
The Raspberry Pi has an HDMI port which you can connect directly to a monitor or TV with an HDMI cable. This is the easiest solution; some modern monitors and TVs have HDMI ports, some do not, but there are other options.
Serial Peripheral Interface (SPI)
Raspberry Pi computers are equipped with a number of SPI buses. SPI can be used to connect a wide variety of peripherals - displays, network controllers (Ethernet, CAN bus), UARTs, etc. These devices are best supported by kernel device drivers, but the spidev
API allows userspace drivers to be written in a wide array of languages.
SPI Hardware
Rapsberry Pi Zero, 1, 2 and 3 have three SPI controllers:
- SPI0, with two hardware chip selects, is available on the header of all Pis; there is also an alternate mapping that is only available on compute modules.
- SPI1, with three hardware chip selects, is available on all Raspberry Pi models except the original Pi 1 models A and B.
- SPI2, also with three hardware chip selects, is only available on Compute Module 1, 3 and 3+.
On the Raspberry Pi 4, 400 and Compute Module 4 there are four additional SPI buses: SPI3 to SPI6, each with 2 hardware chip selects. These extra SPI buses are available via alternate function assignments on certain GPIO pins - see the BCM2711 ARM Peripherals datasheet.
Chapter 10 in the BCM2835 ARM Peripherals datasheet describes the main controller. Chapter 2.3 describes the auxiliary controller.
Pin/GPIO mappings
SPI0
SPI Function | Header Pin | Broadcom Pin Name | Broadcom Pin Function |
---|---|---|---|
MOSI | 19 | GPIO10 | SPI0_MOSI |
MISO | 21 | GPIO09 | SPI0_MISO |
SCLK | 23 | GPIO11 | SPI0_SCLK |
CE0 | 24 | GPIO08 | SPI0_CE0_N |
CE1 | 26 | GPIO07 | SPI0_CE1_N |
SPI0 alternate mapping (compute modules only, except CM4)
SPI Function | Broadcom Pin Name | Broadcom Pin Function |
---|---|---|
MOSI | GPIO38 | SPI0_MOSI |
MISO | GPIO37 | SPI0_MISO |
SCLK | GPIO39 | SPI0_SCLK |
CE0 | GPIO36 | SPI0_CE0_N |
CE1 | GPIO35 | SPI0_CE1_N |
SPI1
SPI Function | Header Pin | Broadcom Pin Name | Broadcom Pin Function |
---|---|---|---|
MOSI | 38 | GPIO20 | SPI1_MOSI |
MISO | 35 | GPIO19 | SPI1_MISO |
SCLK | 40 | GPIO21 | SPI1_SCLK |
CE0 | 12 | GPIO18 | SPI1_CE0_N |
CE1 | 11 | GPIO17 | SPI1_CE1_N |
CE2 | 36 | GPIO16 | SPI1_CE2_N |
SPI2 (compute modules only, except CM4)
SPI Function | Broadcom Pin Name | Broadcom Pin Function |
---|---|---|
MOSI | GPIO41 | SPI2_MOSI |
MISO | GPIO40 | SPI2_MISO |
SCLK | GPIO42 | SPI2_SCLK |
CE0 | GPIO43 | SPI2_CE0_N |
CE1 | GPIO44 | SPI2_CE1_N |
CE2 | GPIO45 | SPI2_CE2_N |
SPI3 (BCM2711 only)
SPI Function | Header Pin | Broadcom Pin Name | Broadcom Pin Function |
---|---|---|---|
MOSI | 03 | GPIO02 | SPI3_MOSI |
MISO | 28 | GPIO01 | SPI3_MISO |
SCLK | 05 | GPIO03 | SPI3_SCLK |
CE0 | 27 | GPIO00 | SPI3_CE0_N |
CE1 | 18 | GPIO24 | SPI3_CE1_N |
SPI4 (BCM2711 only)
SPI Function | Header Pin | Broadcom Pin Name | Broadcom Pin Function |
---|---|---|---|
MOSI | 31 | GPIO06 | SPI4_MOSI |
MISO | 29 | GPIO05 | SPI4_MISO |
SCLK | 26 | GPIO07 | SPI4_SCLK |
CE0 | 07 | GPIO04 | SPI4_CE0_N |
CE1 | 22 | GPIO25 | SPI4_CE1_N |
SPI5 (BCM2711 only)
SPI Function | Header Pin | Broadcom Pin Name | Broadcom Pin Function |
---|---|---|---|
MOSI | 08 | GPIO14 | SPI5_MOSI |
MISO | 33 | GPIO13 | SPI5_MISO |
SCLK | 10 | GPIO15 | SPI5_SCLK |
CE0 | 32 | GPIO12 | SPI5_CE0_N |
CE1 | 37 | GPIO26 | SPI5_CE1_N |
SPI6 (BCM2711 only)
SPI Function | Header Pin | Broadcom Pin Name | Broadcom Pin Function |
---|---|---|---|
MOSI | 38 | GPIO20 | SPI6_MOSI |
MISO | 35 | GPIO19 | SPI6_MISO |
SCLK | 40 | GPIO21 | SPI6_SCLK |
CE0 | 12 | GPIO18 | SPI6_CE0_N |
CE1 | 13 | GPIO27 | SPI6_CE1_N |
Master modes
Signal name abbreviations
SCLK - Serial CLocK
CE - Chip Enable (often called Chip Select)
MOSI - Master Out Slave In
MISO - Master In Slave Out
MOMI - Master Out Master In
Standard mode
In Standard SPI mode the peripheral implements the standard 3 wire serial protocol (SCLK, MOSI and MISO).
Bidirectional mode
In bidirectional SPI mode the same SPI standard is implemented, except that a single wire is used for data (MOMI) instead of the two used in standard mode (MISO and MOSI). In this mode, the MOSI pin serves as MOMI pin.
LoSSI mode (Low Speed Serial Interface)
The LoSSI standard allows issuing of commands to peripherals (LCD) and to transfer data to and from them. LoSSI commands and parameters are 8 bits long, but an extra bit is used to indicate whether the byte is a command or parameter/data. This extra bit is set high for a data and low for a command. The resulting 9-bit value is serialized to the output. LoSSI is commonly used with MIPI DBI type C compatible LCD controllers.
NOTE | Some commands trigger an automatic read by the SPI controller, so this mode cannot be used as a multipurpose 9-bit SPI. |
---|---|
Transfer modes
- Polled
- Interrupt
- DMA
Speed
The CDIV (Clock Divider) field of the CLK register sets the SPI clock speed:
SCLK = Core Clock / CDIV
If CDIV is set to 0, the divisor is 65536. The divisor must be a multiple of 2, with odd numbers rounded down. Note that not all possible clock rates are usable because of analogue electrical issues (rise times, drive strengths, etc).
See the Linux driver section for more info.
Chip Selects
Setup and hold times related to the automatic assertion and de-assertion of the CS lines when operating in DMA mode are as follows:
- The CS line will be asserted at least 3 core clock cycles before the msb of the first byte of the transfer.
- The CS line will be de-asserted no earlier than 1 core clock cycle after the trailing edge of the final clock pulse.
SPI Software
Linux driver
The default Linux driver is spi-bcm2835
.
SPI0 is disabled by default. To enable it, use raspi-config, or ensure the line dtparam=spi=on
is not commented out in /boot/config.txt
. By default it uses 2 chip select lines, but this can be reduced to 1 using dtoverlay=spi0-1cs
. dtoverlay=spi0-2cs
also exists, and without any parameters it is equivalent to dtparam=spi=on
.
To enable SPI1, you can use 1, 2 or 3 chip select lines, adding in each case:
dtoverlay=spi1-1cs #1 chip select
dtoverlay=spi1-2cs #2 chip select
dtoverlay=spi1-3cs #3 chip select
to the /boot/config.txt
file. Similar overlays exist for SPI2, SPI3, SPI4, SPI5 and SPI6.
The driver does not make use of the hardware chip select lines because of some limitations - instead it can use an arbitrary number of GPIOs as software/GPIO chip selects. This means you are free to choose any spare GPIO as a CS line, and all of these SPI overlays include that control - see /boot/overlays/README
for details, or run (for example) dtoverlay -h spi0-2cs
(dtoverlay -a | grep spi
might be helpful to list them all).
Speed
The driver supports all speeds which are even integer divisors of the core clock, although as said above not all of these speeds will support data transfer due to limits in the GPIOs and in the devices attached. As a rule of thumb, anything over 50MHz is unlikely to work, but your mileage may vary.
Supported Mode bits
SPI_CPOL - Clock polarity
SPI_CPHA - Clock phase
SPI_CS_HIGH - Chip Select active high
SPI_NO_CS - 1 device per bus, no Chip Select
SPI_3WIRE - Bidirectional mode, data in and out pin shared
Bidirectional or "3-wire" mode is supported by the spi-bcm2835
kernel module. Please note that in this mode, either the tx or rx field of the spi_transfer struct must be a NULL pointer, since only half-duplex communication is possible. Otherwise, the transfer will fail. The spidev_test.c source code does not consider this correctly, and therefore does not work at all in 3-wire mode.
Supported bits per word
- 8 - Normal
- 9 - This is supported using LoSSI mode.
Transfer modes
Interrupt mode is supported on all SPI buses. SPI0, and SPI3-6 also support DMA transfers.
SPI driver latency
This thread discusses latency problems.
spidev
spidev
presents an ioctl-based userspace interface to individual SPI CS lines. Device Tree is used to indicate whether a CS line is going to be driven by a kernel driver module or managed by spidev on behalf of the user; it is not possible to do both at the same time. Note that Raspberry Pi’s own kernels are more relaxed about the use of Device Tree to enable spidev
- the upstream kernels print warnings about such usage, and ultimately may prevent it altogether.
Using spidev from C
There is a loopback test program in the Linux documentation that can be used as a starting point. See the Troubleshooting section.
Using spidev from Python
There are several Python libraries that provide access to spidev
, including spidev
(pip install spidev
- see https://pypi.org/project/spidev/) and SPI-Py
(https://github.com/lthiery/SPI-Py).
Using spidev from a shell such as bash
# Write binary 1, 2 and 3
echo -ne "\x01\x02\x03" > /dev/spidev0.0
Other SPI libraries
There are other userspace libraries that provide SPI control by directly manipulating the hardware: this is not recommended.
Troubleshooting
Loopback test
This can be used to test SPI send and receive. Put a wire between MOSI and MISO. It does not test CE0 and CE1.
wget https://raw.githubusercontent.com/raspberrypi/linux/rpi-3.10.y/Documentation/spi/spidev_test.c
gcc -o spidev_test spidev_test.c
./spidev_test -D /dev/spidev0.0
spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)
FF FF FF FF FF FF
40 00 00 00 00 95
FF FF FF FF FF FF
FF FF FF FF FF FF
FF FF FF FF FF FF
DE AD BE EF BA AD
F0 0D
Some of the content above has been copied from the elinux SPI page, which also borrows from here. Both are covered by the CC-SA license.