课程1:昉·星光开发板使用基础和GPIO点灯
昉·星光开发板搭载RISC-V SiFive U74双核64位RV64GC ISA的芯片平台(SoC)及4GB LPDDR4 RAM,具有丰富的外设I/O接口,如USB3.0、40-Pin GPIO Header、千兆以太网、MicroSD卡插槽等,为开发者提供了一个完善的创新应用平台。
本次课程为昉·星光开发板IoT开发系列课程的第一讲,将带领同学们了解昉·星光开发板的硬件情况,那装Ubuntu官方提供的RISC-V版本Ubuntu系统并学习基础使用,然后在通过板载的GPIO接口控制LED。
一、学习目标
- 了解昉·星光开发板硬件
- 学习昉·星光开发板安装RISC-V版本Ubuntu系统
- 学习昉·星光开发板通过GPIO控制LED
二、准备工作
在开始本次课程的实际操作之前,同学们需要做好一些准备工作,课程中涉及到的硬件如下:
- 开发板:昉·星光开发板
- LED:
- 单色LED模块
- 双色LED模块
- 红绿灯模块
- LED:
- 存储卡:闪迪32G高速存储卡
- USB2TTL模块:CP2102 USB转串口模块
- Type-C数据线:1条
- 杜邦线:若干
除了以上的需要的准备的硬件外,我们还需要一台电脑连接到昉·星光开发板进行操作和编程。昉·星光开发板也支持通过HDMI连接到显示器进行操作,但本课程的内容,主要为通过电脑进行远程操作。
三、了解昉·星光开发板硬件
通过《昉·星光单板计算机快速入门指南》,我们可以了解到昉·星光开发板的具体规格,以及各组成部分:
要进行IoT开发,我们关注的主要重点为40 Pin GPIO Header(以下简称40Pin),其具体的定义如下:
在上图中,所有的GPIO引脚都可以配置为不同的功能,包括但不限于SDIO、Audio、SPI、I2C、UART和PWM。请注意每个GPIO引脚的最大安全电流为39mA,但是当多个GPIO同时使用时,总电流应小于100mA,超过最大值将损坏引脚。
本次课程,将会用到40Pin中的GPIO13(UART RX)、GPIO14(UART TX)、GPIO0、GPIO2、GPIO4、GND。
四、昉·星光开发板安装RISC-V版本Ubuntu系统
拿到昉·星光开发板之后,第一件事情,就是安装系统。在官方社区,提供了多种系统可供选择,我们这里选择Ubuntu官方提供支持的RISC-V版本Ubuntu。
4.1. 下载RISC-V版本Ubuntu系统
下载地址:Download Ubuntu for RISC-V Platforms | Ubuntu
下载的具体文件如下:
注意:下载的文件名中,需要包含 visionfive,才表示是专门适配昉·星光开发板的版本。
4.2、安装RISC-V版本Ubuntu系统
因为Ubuntu官方提供的适配版本是preinstalled-server的镜像文件,所以只需要将该镜像,写入到MicroSD卡上,就可以使用了。
将MicroSD卡插入读卡器,连接到电脑上,然后参考下面的步骤进行操作。
4.2.1 Linux或macOS电脑
在Linux系统或macOS系统上,不需要额外的工具,使用系统提供的xz和dd命令即可。
- Linux系统安装:
# 请在读卡器插入前后,分别执行一次,查看新增的存储设备(如/dev/sdb),执行dd命令的时候需要使用;切勿选择错误
sudo fdisk -l
# 根据上一部的结果,卸载挂载的分区,具体数量,根据上一部结果而定
sudo umount /dev/sdb1 /dev/sdb2 /dev/sdb3 /dev/sdb4
# 解压镜像文件压缩包
xz -d ubuntu-22.04.1-preinstalled-server-riscv64+visionfive.img.xz
# 写入镜像到MicroSD卡
sudo dd if=ubuntu-22.04.1-preinstalled-server-riscv64+visionfive.img of=/dev/sdb bs=1m status=progress
- macOS系统安装:
# 请在读卡器插入前后,分别执行一次,查看新增的存储设备(如/dev/disk2),执行dd命令的时候需要使用;切勿选择错误
sudo diskutil list
# 根据上一部的结果,卸载挂载的分区
sudo diskutil unmountDisk /dev/disk2
# 解压镜像文件压缩包
xz -d ubuntu-22.04.1-preinstalled-server-riscv64+visionfive.img.xz
# 写入镜像到MicroSD卡
dd if=ubuntu-22.04.1-preinstalled-server-riscv64+visionfive.img bs=1m | pv -s 5G | sudo dd of=/dev/disk2 bs=1m
4.2.2 Windows电脑
在Windows电脑上,可以使用Win32 Disk Imager工具来将镜像文件写入MicroSD卡,操作步骤如下:
- 解压下载的镜像文件压缩包
- 下载win32diskimager-1.0.0-binary.zip并解压
- 使用Win32 Disk Imager写入镜像:
注意:选择的镜像文件后解压后的ubuntu-22.04.1-preinstalled-server-riscv64+visionfive.img文件。
写入完成后,取下读卡器和MicroSD卡,但先不要插入到昉·星光开发板的MicroSD卡插槽中。
五、RISC-V版本Ubuntu系统基础使用
在系统启动时,为了方便查看到启动过程,可以使用HDMI将昉·星光开发板连接到显示器查看。
既然是搞IoT开发,那这里就使用USB2TTL模块连接开发板,进入串口终端查看启动过程,并进行操作。
待网络设置好以后,后续就可以通过ssh远程连接到昉·星光开发板进行操作了。
5.1 连接昉·星光开发板串口
参考下图,将USB2TTL模块与昉·星光开发板做好连接,然后接入到电脑:
实物连接如下:
5.2 连接串口终端
- Linux或macOS系统:
# 请在USB2TTL模块插入前后,分别执行一次,查看新增的串口设备,如tty.usbserial-0001
ls -l /dev/ | grep -Ei "tty.*usb"
# 安装minicom,请根据系统实际情况使用包管理命令安装
# 如Ubuntu: sudo apt install minicom
# 如macOS: brew install minicom
# 连接到串口终端
minicom -c on -b 115200 -D /dev/tty.usbserial-0001
# 如果要退出minicom,可以按Esc+Z,再按X
-
Windows系统:
-
先通过系统设备管理器查看连接到的串口设备:
-
再使用Putty连接串口终端:
- Putty下载地址:https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html,下载【64-bit x86: putty.zip】
- 下载解压后,运行其中的putty.exe打开连接设置界面,进行设置连接:
-
-
连接成功后,将昉·星光开发板上电,就可以看到启动信息了;如果没有看到,请检查USB2TTL与昉·星光开发板的连线是否松动,并按RST按键重启,检查是否有启动信息输出。
5.3 启动Ubuntu系统
将昉·星光开发板断电,将MicroSD卡插入MicroSD卡插槽,然后上电,就能再次看到启动信息,并启动MicroSD卡上的Ubuntu系统了。
首次启动时,Ubuntu系统需要进行一些初始化,才能进行登录,所以请稍等一会,待出现以下提示信息后:
再使用默认用户ubuntu和默认密码ubuntu进行登录。首次登录时,会提示修改密码:
注意:后续的命令行操作,如非特别说明,默认情况下,都指通过ssh连接到昉·星光开发板进行操作。
5.4 Ubuntu系统基础设置
登录到Ubuntu系统之后,我们需要进行一些基础的设置,以便系统更好用,相关的指令如下:
# 设置系统时区:
sudo tzselect
# 依次输入Asia、China、Beijing Time、Yes 选项所对应的数值并回车即可
# 当前环境生效
echo "TZ='Asia/Shanghai'; export TZ" >> ~/.profile
. ~/.profile
# 查看当前时间
date
# 输出类似:Tue Jun 28 02:45:05 CST 2022,时区为CST表示设置正确,但是时间不对,后面将安装ntp进行同步
# 设置WiFi网络
ls /sys/class/net
# 输出:eth0 lo wlan0,其中wlan0表示WiFi接口
# 查看网络配置:
ls /etc/netplan/
# 输出:50-cloud-init.yaml,表示云连接初始化配置文件
# 修改云连接初始化配置文件
sudoedit /etc/netplan/50-cloud-init.yaml
# 按照如下格式,添加wifis及其后的wlan0部分,注意保持缩进关系
# 要退出,请按界面提示信息,按Ctrl+X,然后根据提示回车保存文件再退出
# 查看配置,应确保输入格式正确
cat /etc/netplan/50-cloud-init.yaml
![1-11.1.WiFi设置|690x429](upload://eAPPCdTAqHqpA4p3VYYMilWahTy.png)
# 修改好以后,应用新的配置
sudo netplan apply
# 查看网络配置:
ip addr show wlan0
从上面的信息可以查看到,WiFi连接成功,获得了192.168.1.117的IP地址。
注意:要连接到网络,也可以直接使用网线,将昉·星光开发板连接到路由器,将自动获得IP地址。为了更方便使用,首选无线网络连接。
为了方便后续的操作,建议在无线路由器中,参考看如下设置,进行昉·星光开发板WiFi Mac地址绑定:
后续的操作,都将使用在其他电脑上,通过ssh连接该ip地址到昉·星光开发板来进行。
到这里,就可以不再使用USB2TTL来进行串口连接了,除非后续遇到问题,系统无法正常启动联网,需要再次试用串口终端进行问题排查。
5.5 使用ssh连接到昉·星光开发板
- Linux或macOS系统:在Linux或macOS系统上,可以直接使用ssh命令进行连接:
ssh ubuntu@192.168.1.117
- Windows系统:在Windows系统上,可以使用连接串口终端的工具Putty进行连接:
ssh连接成成功后,可以尝试一下具体的操作:
# 更新apt索引
sudo apt update
# 更新系统
sudo apt upgrade -y
# 重启系统
sudo reboot
# 重启系统后,ssh需要重新连接
# 关闭默认时间同步服务
sudo timedatectl set-ntp no
# 安装ntp服务
sudo apt install ntp
# 查看ntpd可以连接到的服务器
ntpq -p
# 输出:为当前可以连接到的ntp服务器
# 查看当前时间
date
# 输出:Fri Oct 7 16:48:31 CST 2022 当前时间已经成功更新
# 以下操作更新系统的locales,以免ssh连接时出现以下错误:
# 登录成功后的错误提示:-bash: warning: setlocale: LC_ALL: cannot change locale (zh_CN.UTF-8)
sudo purge locales
sudo apt autoclean
sudo apt install locales
sudo /usr/share/locales/install-language-pack zh_CN.UTF-8
sudo dpkg-reconfigure locales
# 在设置界面中的每一步,都选择 zh_CN.UTF-8即可
# 设置完成后,使用ssh重新登录,将不会出现LC_ALL的错误提示,系统的locale也会自动设置
# ssh重新连接后查看当前系统时间:
date
# 输出:2022年 10月 07日 星期五 17:01:23 CST
六、通过GPIO控制LED模块
在前面的环节中,我们已经可以通过ssh连接到昉·星光开发板了,现在我们就可以开始通过GPIO控制LED模块了。
要在Ubuntu系统上操控GPIO,可以通过shell命令,也可以通过编程来实现,后续的课程中,我们使用的主要语言为Python。
6.1 单色LED模块的GPIO连线
单色LED模块只有两根线,一根接地,一根用于接收控制信号。
参考上图,将单色LED的【+】连接到40-GPIO0,【-】连接到39-GND,实物连线如下:
6.2 使用shell指令控制LED
连接后,我们通过如下的指令,就可以操控GPIO0,从而控制LED的亮灭:
# 进入系统gpio设备目录
cd /sys/class/gpio
# 启用GPIO0对应的GPIO设备
echo 448 | sudo tee export
# 设置输出方向
echo out | sudo tee gpio448/direction
# 输出1,点亮LED
echo 1 | sudo tee gpio448/value
# 输出0,熄灭LED
echo 0 | sudo tee gpio448/value
注意:在昉·星光开发板的Ubuntu系统中,GPIO0在系统中的GPIO设备号为448,GPIO1为449,其他均以此类推。
6.3 使用Python编程控制LED
要在Ubuntu上的Python中,操控GPIO,可以使用Python的gpio模块,需要先安装:
# 安装Python的包管理工具
sudo apt install python3-pip
# 安装Python的gpio包:https://github.com/vitiral/gpio https://test.pypi.org/project/gpio-test
sudo pip3 install -i https://test.pypi.org/simple/ gpio-test
安装完成以后,就可以编写程序控制GPIO了。
其他可供使用的Python的GPIO库:
- hankso/gpio4: Improved gpio module based on Sysfs and gpio3, drop-in replacement of RPi.GPIO (github.com)
- Python gpiod | loliot
6.3.3 控制单色LED模块
使用如下的指令编写Python程序:
# 建立专用目录
mkdir -p ~/projects/gpio
cd ~/projects/gpio
# 新建并编辑py脚本文件:
nano gpio_one_color.py
# 在上述界面,输入下面gpio_one_color.py的代码
# 要退出,请按界面提示信息,按Ctrl+X,然后根据提示回车保存文件再退出
gpio_one_color.py的代码:
# -*- coding: utf-8 -*-
# file: ~/projects/gpio/gpio_one_color.py
import time
# 引入GPIO模块
import gpio as GPIO
# 设置LED的GPIO设备号:GPIO设备号为448,GPIO1为449,其他均以此类推
LED = 448
# 设置该GPIO设备为输出
GPIO.setup(LED, GPIO.OUT)
# 死循环
while True:
# 输出高dmpk
GPIO.output(LED, GPIO.HIGH)
# 延时1s
time.sleep(1.0)
# 输出低电平
GPIO.output(LED, GPIO.LOW)
# 再次延时1s
time.sleep(1.0)
注意:编写Python程序的时候,代码的缩进就表示了程序逻辑的层级,需要严格对齐。通常情况下,应使用空格来进行缩进,而不要使用Tab制表符。
编写完上述的程序,使用如下的指令执行:
sudo python3 ./gpio_one_color.py
执行后,单色LED就会一秒一次,交替亮灭。
6.3.3 控制双色LED模块
在控制单色LED模块的基础上,我们再进行双色LED模块的控制。
单色LED模块有两个线,双色LED模块有三根线,一根为接地,另外两根分别用于控制两个颜色,实际上是控制其内部的两个LED。
参考上图,将双色LED模块的【-】连接到39-GND,将另外两脚bb别连接到40-GPIO0、38-GPIO2,实物;连接如下:
然后编写参考编写 gpio_one_color.py 的指令,编写 gpio_two_color.py 程序,具体代码如下:
# -*- coding: utf-8 -*-
# file: ~/projects/gpio/gpio_two_color.py
import time
import gpio as GPIO
LED1 = 448
LED2 = 450
GPIO.setup(LED1, GPIO.OUT)
GPIO.setup(LED2, GPIO.OUT)
while True:
GPIO.output(LED1, GPIO.HIGH)
GPIO.output(LED2, GPIO.LOW)
time.sleep(1.0)
GPIO.output(LED1, GPIO.LOW)
GPIO.output(LED2, GPIO.HIGH)
time.sleep(1.0)
代码的基本逻辑,为交替输出高低电平,从而控制双色LED模块内部两种颜色对应的LED的亮灭。
编写完毕,使用下面的命令执行:
sudo python3 gpio_two_color.py
程序运行后,双色LED灯的两种颜色,就会交替点亮:
6.3.3 控制交通灯模块
单色LED模块有两根线,双色LED模块有三根线,交通灯模块有三个灯四根线,类似双色LED模块,一根线用于接地,另外三根线,用于控制红黄绿三种颜色。
参考上图,分别连接好交通灯模块的4根线,实物连接如下:
然后,编写如下的程序:
# -*- coding: utf-8 -*-
# file: ~/projects/gpio/gpio_traffic_led.py
import time
import gpio as GPIO
LED_R = 448
LED_Y = 450
LED_G = 452
GPIO.setup(LED_R, GPIO.OUT)
GPIO.setup(LED_Y, GPIO.OUT)
GPIO.setup(LED_G, GPIO.OUT)
while True:
GPIO.output(LED_R, GPIO.HIGH)
GPIO.output(LED_Y, GPIO.LOW)
GPIO.output(LED_G, GPIO.LOW)
time.sleep(1.0)
GPIO.output(LED_R, GPIO.LOW)
GPIO.output(LED_Y, GPIO.HIGH)
GPIO.output(LED_G, GPIO.LOW)
time.sleep(1.0)
GPIO.output(LED_R, GPIO.LOW)
GPIO.output(LED_Y, GPIO.LOW)
GPIO.output(LED_G, GPIO.HIGH)
time.sleep(1.0)
编写完毕,使用下面的命令执行:
sudo python3 gpio_traffic_led.py
程序运行后,交通灯模块的三种颜色的灯,就会依次点亮:
七、总结
在这次课程中,我们学习了昉·星光开发板的硬件,及RISC-V版本Ubuntu系统的安装和基础使用。然后,我们又学习了使用shell命令控制LED,使用Python程序控制LED。
学习IoT开发,点灯就是“Hello World”,点亮就是成功了一半!希望大家都能跟随本课程,学用结合,收获满满!
八、课后作业
- 了解 Python语言的语法:Python3 菜鸟教程 (https://www.runoob.com/python3/python3-tutorial.html)
- 找到7个LED,编写Python程序进行控制
- 找到一段单音节的简谱,结合LED控制和延时,实现LED跟随音符点亮