文章目录

  • PIO介绍
    • 状态机
  • PIO指令详解
  • PIO语法详解
  • 函数详解
    • 【MicroPython】PIO有关函数详解
      • @asm_pio装饰器
      • rp2.StateMachine函数详解
      • PIO_ASM
    • 例程地址
  • 实操

PIO介绍

RP2040的一个特殊的外设
它可以基于RP2040的设备上创建新的或者额外的硬件接口

作用:其本质接近FPGA,也就是现场可编程逻辑门阵列
通过简单的状态机来模拟所以接口,当然前提是满足对应的时钟频率

假设以下场景:

  • 场景一
  • 你需要使用某些通讯接口,但是现在的外设满足不了你的需求
  • 场景二
  • 你需要使用某些接口,如单总线协议,VGA,DVI等,但是RP2040没有现存的外设

以上场景中,我们都可以通过PIO自定义创建我们需求的接口,来满足对应的需求

不同于软件模拟,PIO并不会占用内核时间

状态机

因为每个PIO有4个独立的状态机,可以实现超高速且可编程的输入输出

状态机可以理解为一个极简的内核,只能用于处理特定的指令实现实现特定的功能

RP2040有两个PIO块,每个块都有4个状态机和指令寄存器组成
它们可以独立地执行顺序程序来操作GPIO和传输数据
与通用处理器不同,PIO状态机高度专注于IO控制和精确的时钟控制

  • 每个状态机都配备了一个32位PC寄存器,用于指向正在执行的指令地址

  • 两个32位移位寄存器(ISR和OSR)

  • 移位寄存器顾名思义数据能在其中移动

  • 而且此处的移位寄存器可以与对应的先进先出存储器直接传输数据

  • 先进先出存储器都可以英文缩写FIFO代替

  • 两个32位的暂存寄存器,称之为X寄存器和Y寄存器

  • 在接收和传输方向上各有4*32位总线FIFO

    • 可重构为8*32位单方向的FIFO,可以通过FIFO可以实现数据的推入或者拉出
  • 一个16位整数,8位小数的小数时钟分频器

    • 输入时钟为系统时钟,最低可以将状态机时钟降低到系统时钟的65536分 之一
  • DMA接口,持续吞吐量高达1字每系统时钟,若系统时钟为100Mhz,每秒最高吞吐量为100M字

  • IRQ中断表示位,PIO总共有8个中断表示位,可以用于同步状态机或者其他用途

  • 每个状态机都可以进行灵活的GPIO映射,映射方式有四种,分别为

    • 输入映射
    • 输出映射
    • 设置映射
    • 侧置映射
  • 详细了解GPIO映射

  • 首先我们需要知道映射寄存器都是32位的

  • 如果让其一位对应着一个GPIO引脚,我们应该用32个GPIO引脚对应

  • 即RP2040只有30个GPIO,我们应当假设其存在32个GPIO,也就是GPIO30和GPIO31,我们也可以戏称之为“消失的引脚”

  • 输入映射

  • 我们可以指定输入GPIO的初始引脚。这个初始引脚在PIO的输入映射中将会被视为引脚0,并将其他引脚按照顺序进行(循环)计数,这里就会遇到“消失的引脚”

    • 如果设定GPIO29为初始引脚也就是引脚0,然后依次递增
    • 经过GPIO30和GPIO31,引脚3也就是对应GPIO0

输出映射和输入映射接近,但需要设置输出引脚的数量,最高为32
设置和侧置映射与输出映射工作方式相同,但最多映射5个IO,设置和侧置映射引脚是允许重叠的

PIO指令详解

状态机类似于极简的内核,只允许很简单的二进制程序
其采用了接近机器语言的PIO汇编进行编写,其支持9种指令分别为:

  • JMP
  • WAIT
  • IN
  • OUT
  • PUSH
  • PULL
  • MOV
  • IRQ
  • SET

我们编写的PIO ASM指令会被编译器编译成对应的指令再交给PIO的状态机运行

PIO指令编码表

  • 首先我们可以看到一条指令的长度为16位,高3位用于标识这条指令功能或者作用

  • 12-8位则用于标识延迟或者侧置,7-0位则会根据指令的不同有不同的功能

  • JMP指令的作用是将达到某些条件的情况下将程序跳转到指定地址

    • JMP指令有两个参数,分别是condition和 target

      • target:允许数值0-31,因为 PIO只有32条指令空间
      • condition:
        • !X OR !Y: X,Y寄存器为0
        • X-- OR Y–: X,Y寄存器减1大于0
        • X != Y: X不等于Y
        • PIN: 输入引脚为高电平
        • !(OSER):输入移位寄存器OSR为0

当程序达成时,程序就会根据target跳转指定地址
当然可以不填写条件,则会无条件跳转到指定地址

  • WAIT指令的作用为在条件达成前等待

    • WAIT指令有三个参数,分别为Polarity极性 ,source源和Index指针
    • 极性是指等待目标出现0或者1
    • 源指对应等待的目标类型,可以为绝对GPIO,引脚映射后PIN和中断标志IRQ
    • 指针对应等待的目标编码
  • IN指针指令的作用将数据存入ISR寄存器中

    • IN指令有两个参数为Source源, Bitcount位数
    • 源指对应读取数据的源类型
    • 位数对应着读取数据的位数
  • OUT指令和IN指令功能相反,指令作用是将OSR输出到目标

  • OUT指令有两个参数destination目标和Bitcount位数

  • 目标对应着数据输出的目标

  • 位数对应着输出位数

  • PUSH指令作用为将ISR内容推送到RX FIFO中并清空ISR

  • 有两个参数 ,为满 和 阻塞

  • 若为满为1,则ISR达到阈值,才可以进行推送

  • 若阻塞为1且RX FIFO达到阈值,则会将数据推送到ISR寄存器中

  • 否则会等待RX FIFO达到阈值,若为0则RX FIFO达不到阈值时,则不会进行推送
    -

  • PULL指令的作用将TX FIFO数据读到OSR寄存器

  • 有两个参数为 空 和 阻塞

  • 若为空为1,则只有TXFIFO达到阈值,OSR才会接收TXFIFO的数据

  • 其中阻塞和PUSH的阻塞一致

  • MOV指令的作用是将数据从源移动到目标寄存器中
    - 有三个参数 目标destination,源sourcr和操作Operation
    - 目标将数据写入的寄存器,可以为一下几种!

    需要注意的是,EXEC解码寄存器,其作用为从外部读取一条指令并执行,理论上是可以执行外部的PIO代码的
    - 源为数据来源,可以为一下几种

    操作有三种
    -

  • IRQ指令的作用为设置或者清空中断标识

  • 有3个参数: 选项 , 中断标志位 和 REL

  • 选项有一下几种

  • 中断标识可以为0-7

  • 若REL存在则中断标识irq_num和状态机编码sm_num进行模4加法运算

  • 若状态机2设置中断标识OX11,最后的中断值则为0X03

  • SET指令会将数据写入目标地址,通常用于控制设置映射引脚

  • 参数 destination 目标地址

  • data 数据为写入的数据,这里只能为绝对值

PIO语法详解

以上就是PIO ASM的9个指令,但是如果你看过PIO ASM的程序,你会发现指令后面还会跟着一些小尾巴
比如说方括号带着一个数字,这代表延迟

在正常程序中我们的每一条指令执行所需要时间为1个时钟周期
但往往我们需要等待或者不需要这么快的速度,这时候我们就需要进行这个延迟

  • 现在有两种方法

    1. 使用一条无意义指令,这个指令将y寄存器的数值赋给y寄存器,这是一条没有意义的指令,但是他会占用状态机的一个时钟周期,还有个缺点,他会占用PIO的 指令空间,因为状态机的指令空间只能容纳32条指令,所以说不推荐这种用法

    2. 使用PIO ASM中的延迟特性
      这条指令会将PINS设置为1,之后延迟2个时钟周期,这就是PIO汇编的延迟特性

      当然延迟时间也是有特性的,最大的延迟时钟为31个时钟周期

  • 侧置Side-set

  • 我们可以在执行任何指令的同时改变被设置为侧置映射引脚,最多5个引脚

  • 需要注意的是,侧置和延迟是共享指令的12-8位,所以说侧置和延迟是无法完美兼容的,但是可以根据你的需求进行设置

延迟的最大数值为31,换算成2进制也就是5位,也就是我们无法通过编码区分延迟和侧置
需要我们需要在程序里注明使用侧置位数

例程

.program spi_tx_fast
.side_set 1loop:
out pins, 1  side 0
jmp loop     side 1

该程序会模拟SPI发送数据的过程
其会不断地将OSR寄存器中的数值(依次)通过pins对应的引脚输出
与此同时,侧置引脚会不断地进行翻转
实现了两个时钟周期输出一位数据并输出时钟信号,使我们的程序更小更快

使用侧置功能时,我们还需要声明使用的侧置位数
这里我们使用一位侧置位数,他会占用侧置/延迟字段的高一位
意味着我们的延迟只能占用4位,也就是其数值范围为0-15

正常情况下,程序会从地址为0的指令开始运行,运行到地址为31的指令运行完成后,再从地址0的指令重复开始运行
下面这段程序将会将一个引脚设置为输出并循环输出占空比为50%且周期为4个时钟周期的方波
该程序的PC指针不会在0-31之间往复,所以说PIO引入了程序包装
通过程序包装可以告诉我们的状态机,从哪里结束并且从哪里重新开始

.program squarewave
set pindirs, 1 ; Set pin to output
again:set pins,1 [1];  Drive pin high  and delay for one cycleset pins, 0 ;    Drive pin lowjmp again ;      Set PC to label 'again'

例程

当程序运行到.wrap 时,程序将会返回到.wrap_target并运行
与上一个程序的区别就是不需要jmp指令进行跳转,可以节省一个指令

      set pindirs, 1 ; Set pin to output
.wrap_targetset pins, 1 [1] ; Drive pin high  and delay for one cycleset pins, 0 [1] ; Drive pin low  and delay for one cycle
.wrap

以上大致就是PIO的内容,虽然还有些小细节,但是不妨碍我们使用

函数详解

【MicroPython】PIO有关函数详解

MicroPython引入了一个新的@rp2.Asm_pio装饰器和rp2.PIO类.

  • PIO程序的定义和状态机的配置分为2个逻辑部分:

    1. 程序定义,包括使用了多少引脚,如果它们是in/out引脚。这在@rp2.asm_pio中定义。
    2. 程序,设置状态机的频率和绑定到哪个引脚。当设置一个状态机来运行特定的程序时,就会设置这些参数。

所有的程序配置(例如autopull)都是在@asm_pio装饰器中完成的,在状态机的构造函数中只需要设置频率和基础引脚。 只设置频率和基础引脚需要在StateMachine构造函数中设置。

@asm_pio装饰器

让其它函数不需要任何代码上的改动,增加额外的功能

@asm_pio(out_init=None,set_init=None,sideset_init=None,in_shiftdir=0,out_shiftdir=0,autopush=False,autopull=False,push_thresh=32,pull_thresh=32,fifo_join=0
)
  • out_init :输出引脚初始化

  • set_init :设置引脚初始化

  • sideset_init :侧置引脚初始化

  • 前三个引脚可以设置为rp2.PIN.OUT_HIGH 输出高电平

  •                                        PIN.OUT_LOW  输出低电平
    
  • 需要注意的是MicroPython 是通过侧置引脚初始化来计算使用了多少个侧置引脚,并决定测置和延迟字段的结构

  • in_shiftdir : 数据输入方向

  • out_shiftdir:数据输出方向

  • 以上决定了数据移动的方向

  • 如输出情况下,数据向左移动,则OSR的高位先进行输出,若向右移动,则低位先进行输出

  • autopush :自动推送,若开启,当ISR达到阈值,自动将ISR传输到RX-FIFO。

  • autopull :自动拉取,若开启,当OSR达到阈值,自动将TX-FIFO传输到OSR。

  • push_thresh :推送阈值

  • pull_thresh :拉取阈值

  • 字面意思,结合自动推送和自动拉取使用

  • fifo_join :fifo组合,指定一个FIFO,将另一个FIFO关闭并加入改FIFO,获取更深位数的FIFO.

  • 如果我们指定TXFIFO,我们就会获得一个8位深度的TXFIFO(32bit*8)

rp2.StateMachine函数详解

MicroPython 使用PIO是以状态机为单位的,所以我们的函数都是围绕状态机的

  • rp2.StateMachine.init(sm_id ,program, freq=-1, *, in_base=None, out_base=None, set_base=None, jmp_pin=None, sideset_base=None, in_shiftdir=None, out_shiftdir=None, push_thresh=None, pull_thresh=None)

    • sm_id:使用状态机ID,0-3为PIO0,4-7为PIO1
    • program:PIO运行程序(状态机运行程序)
    • freq:状态机运行频率,默认为系统时钟频率,
      • 时钟分频器的分配因子计算公式为“系统时钟频率/频率”,所以 可能存在轻微的舍入误差。
      • 最小可能的时钟分频器是系统时钟的 65536 分之一:所以在默认系统时钟频率 125MHz下,最小值为1908。
      • 要以较慢的频率运行状态机,需要使用“machine.freq()”降低系统时钟速度。
    • in_base:用于in()指令的第一个引脚
    • out_base:用于out()指令的第一个引脚
    • set_base:用于set()指令的第一个引脚
    • jmp_pin:用于jmp(pin, …)指令的第一个引脚
    • sideset_base:是用于侧置的第一个引脚。
    • in_shiftdir:ISR将移动的方向,可为PIO.SHIFT_LEFT或者PIO.SHIFT_RIGHT
    • out_shiftdir: OSR 将移动的方向,可为PIO.SHIFT_LEFT或者PIO.SHIFT_RIGHT
    • push_thresh:推送阈值
    • pull_thresh:拉取阈值
  • StateMachine.active([value])

    • 获取或设置状态机当前是否正在运行。
    • 当value不为空时,设置状态机,反之获取运行状态。
  • StateMachine.restart()

    • 重新启动状态机并跳转到程序的开头。
  • StateMachine.exec(instr)

    • 执行单个 PIO 指令。使用 asm_pio_encode 编码 来自给定指令字符串 instr 的指令。
  • StateMachine.get(buf=None, shift=0)

    • 从状态机的RX-FIFO中提取一个字。
    • 如果FIFO为空,它会阻塞直到数据到达(即状态机推一个字)。
    • shift为在返回之前右移位数
    • 返回值是“word >> shift”
  • StateMachine.put(value, shift=0)

    • 将一个字推送到状态机的 TX FIFO。
    • 如果 FIFO已满,它将阻塞直到有空间(即状态机拉一个字)。
    • shift为在返回之前右移位数
    • 返回值是“word >> shift”
  • StateMachine.rx_fifo()

    • 返回状态机的 RX FIFO 中的字数。值为0表示 FIFO 为空。
    • 用于在调用之前检查数据是否正在等待读取StateMachine.get()
  • StateMachine.tx_fifo()

    • 返回状态机的 RX FIFO 中的字数。值为0表示 FIFO 为空。
    • 用于在调用之前检查数据是否正在等待读取StateMachine.put()
  • StateMachine.irq(handler=None, trigger=0|1, hard=False)

    • 返回给定 StateMachine 的 IRQ 对象。

PIO_ASM

  1. JMP (condition) target

    1. target :跳转地址,允许数值0-31,因为PIO只有32条指令空间。
    2. condition :
      1. !X OR !Y:
      2. X– OR Y–
      3. X!=Y :
      4. PIN :
      5. !(OSRE):
    • JMP指令作用是将达到某些条件的情况下将程序跳转到指定地址.
    • 当条件达成时,程序就会根据target跳转指定地址
    • 当然也可以不填写条件,则会无条件跳转指定地址。
  2. WAIT Polarity Source Index

    1. Polarity: 等待 0 OR 1
    2. Source:
      1. GPIO:绝对GPIO
      2. PIN:引脚映射后的引脚
      3. IRQ:中断标志
    3. Index:
      1. GPIO_num:对应GPIO源,GPIO数值
      2. pin_num:对应pin源,pin数值
      3. IRQ_num:对应IRQ源,指定等待的引脚或者位,这里IRQ_NUM也是支持使用(_rel)
    • WAIT指令作用为在条件达成前等待
  3. IN Source,Bitcount

    1. Source :

      1. PINS
      2. X
      3. Y
      4. NULL
      5. ISR
      6. OSR
    2. Bitcount :读取位数
    • IN指令作用将数据存入ISR寄存器
  4. OUT destination,Bitcount

    1. destination :

      1. PINS
      2. X
      3. Y
      4. NULL
      5. PINDIRS
      6. PC
      7. ISR
      8. OSR
    2. Bitcount :读取位数
    • OUT和IN功能相反,指令作用将OSR寄存器输出到目标
  5. PUSH (IfFull) (Block/noBloc k)

    1. IfFull,若为1则只有ISR到达阈值,才能推送.
    2. Block,若为1且RX FIFO达到阈值,就会进行将数据推送到ISR中,否则会等待RXFIO达到阈值,若为0则RXFIFO达不到阈值,则不会进行推送。
    • PUSH指令的作用为将ISR中内容推送到RX FIFO和清空ISR
  6. PULL (IfEmpty) (Block/noBloc k)

    1. IfEmpty:若为1则只有OSR才会接收TXFIFO的数据。
    2. Block:1则TXFIFO为空则等待TXFIFO.
    • PUSH指令的作用将从TXFIFO数据读出到OSR寄存器。
  7. MOV destinationmov,(Operation ),source

    1. destination:

      1. PINS:输出映射
      2. X:
      3. Y:
      4. EXEC:解码寄存器
      5. PC:PC寄存器(JUM)
      6. ISR
      7. EXEC:
    2. source:
      1. PINS:
      2. X
      3. Y
      4. NULL:空,用于清零
      5. STATUS:表示不同状态,如fifo满或者空。
      6. ISR:
      7. OSR:
    3. Operation:
      1. 00:不改变
      2. 01:位取反
      3. 10:位翻转,高低位互换。
    • MOV 指令其作用为将数据从源移动目标寄存器。
  8. IRQ (option) irq_num (_rel)

    1. irq_num:0-7 中断标志位
    2. option
      1. set(默认):设置
      2. nowait(默认):不等待清除
      3. wait:等待清除后,运行
      4. clear:清除
    3. _rel:若存在则将irq_num和状态机编码sm_num相加并进行模四运行并将高位置1,若状态机2设置中断标识3,中断值则为0X11
    • irq_flag=(sm_id+irq_num) %4 + 0x10
    • IRQ指令作用为设置或者清空中断标识
  9. SET destination,data

    1. destination:目标地址

      1. PINS :SET映射引脚
      2. PINDIRS :引脚方向,将第一个映射GPIO1为输出,0为输入
      3. X : 暂存寄存器,暂存数据
      4. Y : 暂存寄存器,暂存数据
    2. data :数据, 0-31
    • set指令会将数据写入目标地址.通常用于控制设置映射引脚。

例程地址

  • Github仓库

MicroPython源码

实操

原理图

Pico 的GPIO4连接到WS2812B的数据输入引脚

  • WS2812B是一款单总线驱动的控制电路与发光电路于一体的智能外控LED光源
    - 可采用单线输出方式,串接LED使之输出动作同步;
    - 数据协议采用单极性归零码
    - 因为内部基础控制电路,显示更趋细腻平滑,解决拍摄画面暗条纹问题
    - 数据发送速度可达800Kbps

  • WS2812的通讯协议

该协议与之前的协议不太一样,其是通过电平的时长来判断数据为0还是1
如果我们需要发送数据0,需要先拉高电平220ns - 380 ns 紧接着拉低电平580ns-1us

数据1也是相同的原理,

ws2812传输数据结构如表格,且ws2812的数据发送是先进行高位发送,也就是数据是向左移动的


# 先导入需要的库
import time
from machine import Pin
import rp2# WS2812的PIO驱动程序
# 通过asm_pio装饰器初始化pio
# 初始化了侧置引脚,因为这里只有一个初始化信息,说明侧置引脚的数量为1
# 数据输出移动方向为由右向做移动
# 开启自动拉取,当OSR达到阈值,自动将TXFIFO中的数据拉取到OSR中
# 拉取阈值为24位,也就是发送数据的长度
@rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW, out_shiftdir=rp2.PIO.SHIFT_LEFT, autopull=True, Pull_thresh=24)def ws2812():T1 = 2T2 = 5T3 = 3# wrap_target()和wrap()进行了程序包装,让程序在两者间运行wrap_target()label("bitloop")out(x, 1)               .side(0)     [T3 - 1]   # 将OSR的数据读取1位取到X寄存器中,并将侧置引脚设置为0,延迟等待2时钟周期jmp(not_x, "do_zero")   .side(1)     [T1 - 1]   # 如果X中的数值为0则跳转标签“do_zero",反之则顺序执行下一条指令,同时将侧置引脚设置为1,延迟等待1时钟周期jmp("bitloop")          .side(1)     [T2 - 1]   # 如果顺序运行则会跳转标签"bitloop"并同时将侧置引脚设置为1,延迟等待4时钟周期,用于表示数据1label("do_zero")                     # 如果跳转到标签do_zero,执行一条无意义的指令并将侧置引脚设置为0nop()                   .side(0)     [T2 - 1]   # 延迟等待4时钟周期,用于表示数据0,随后返回wrap()wrap()# 主程序
# 创建我们的状态机0使用ws2812程序,时钟频率为8Mhz,基础侧置引脚为4
# 打开状态机
sm = rp2.StateMachine(0, ws2812, freq=8_000_000, sideset_base=Pin(4))
sm.ative(1)# 在循环中,我们不断地改变RGB数值,并通过是sm.put()函数将数组传输给TXFIFO
# TXFIFO会自动的被状态机拉取到OSR寄存器中
# 并指向WS2812驱动程序实现不同颜色的呼吸灯
while True:for i in range(0,max_lum):r = ib = max_lum-irgb=(g<<24) | (r<<16) | (b<<8)sm.put(rgb)time.sleep_ms(10)time.sleep_ms(300)for i in range(0,max_lum):g = ir = max_lum-irgb=(g<<24) | (r<<16) | (b<<8)sm.put(rgb)time.sleep_ms(10)time.sleep_ms(300)for i in range(0,max_lum):b = ig = max_lum-irgb=(g<<24) | (r<<16) | (b<<8)sm.put(rgb)time.sleep_ms(10)time.sleep_ms(300)

微雪PICO教程

微雪树莓派PICO笔记——8-PIO(可编程输入输出接口)相关推荐

  1. 微雪树莓派PICO笔记——1.基础介绍

    文章目录 基础硬件 原理图讲解 电路图重点讲解 点灯实操 基础硬件 长度51mm,宽度21mm,板厚1mm pcb使用了沉金工艺,所以引脚都做了半孔设计,即可焊接2.54mm的排针,也可以直接焊在主板 ...

  2. 微雪树莓派PICO笔记——3.PWM(脉冲宽度调制)

    文章目录 什么是PWM PWM的应用 RP2040 PWM框架图 PWM流程图 PWM内部框架图 [MicroPython]machine.PWM类函数详解 代码实现 什么是PWM 脉冲宽度调制 (P ...

  3. 微雪树莓派PICO笔记——7. SPI(串行外设接口)

    文章目录 SPI简介 硬件连接 通讯协议详解 RP2040 SPI 主要参数 RP2040 SPI 逻辑框图 machine.SPI类函数详解 例程地址 代码示例 代码实现 SPI简介 SPI全称为串 ...

  4. 微雪树莓派PICO笔记——4. ADC(模拟数字转换器)

    文章目录 什么是ADC RP2040 ADC技术参数 ADC大致框架图 [MicroPython]machine.ADC类函数详解 代码实现 如果我们需要使用PWM精准的控制LED的亮度,就需要反馈 ...

  5. 微雪树莓派PICO笔记——5. UART (异步收发传输器)

    文章目录 通讯协议 UART UART详解 RP2040 UART参数 UART流程图 函数详解 例程地址 码代码 通讯协议 MCU如果要说话需要约定一定的规则,这些规则,我们称为通信协议 常见的有U ...

  6. 微雪树莓派PICO笔记——6. I2C(集成电路总线)

    文章目录 简介 协议详解 RP2040 I2C主要参数 函数讲解 内存操作 软件I2C 例程地址 实操 程序讲解 简介 I2C 集成电路总线,一种串行通信总线,使用多主从架构 由飞利浦公司在20世纪8 ...

  7. 树莓派Pico直流步进电机接口技术及电机运动控制MicroPython+pioasm编程方法

    内容目录 一.树莓派Pico直流步进电机接口技术 1.直流步进电机及其驱动电路原理介绍 2.Pico开发板扩展GPIO口与步进电机驱动接口 二.树莓派Pico电机运动控制MicroPython+pio ...

  8. 树莓派Pico迷你开发板MicroPython多线程编程实践

    内容目录: 一.多线程基本知识 二.MicroPython/Python低层多线程API介绍 三.树莓派Pico 开发板MicroPython多线程编程实践举例 3.1 Pico RP2040 MCU ...

  9. [树莓派]PICO基础使用_微雪OLED显示

    简介 Raspberry Pi Pico是具有灵活数字接口的低成本,高性能微控制器板.它集成了Raspberry Pi自己的RP2040微控制器芯片,运行速度高达133 MHz的双核Arm Corte ...

  10. 首款微控制器级树莓派 Pico,超廉价只需4美元

    2021年1月21日,树莓派基金会发布了首款微控制器级产品:Raspberry Pi Pico. 该产品基于全新的 RP2040 芯片构建,售价仅 4 美元,国内标准售价 29.99 元人民币,目前在 ...

最新文章

  1. exception in initAndListen: 12596 old lock file, terminating
  2. Java谜题:等于,还是不等于?
  3. C#动态生成XML并在前台用javascript读取
  4. 【转】C#自定义控件:WinForm将其它应用程序窗体嵌入自己内部
  5. 切割日志 python版
  6. jvm类加载过程_详解JVM类加载
  7. python读取word文档结构图_python根据文章标题内容自动生成摘分享的实例
  8. 快手作者视频如何批量下载
  9. 将bilibili里面的缓存视频保存到电脑
  10. 女孩,请把第一胎留给丈夫!!!
  11. LeetCode 3:Longest Substring Without Repeating Charact
  12. 软件测试-按开发阶段划分
  13. 全新文案馆头像壁纸小程序源码+带后台的
  14. 硬盘IDE、SATA、AHCI模式的区别
  15. Eclipse delete键不能向后删除
  16. python拼图游戏代码的理解_Python编写的数字拼图游戏(含爬山算法人机对战功能)...
  17. ASO苹果搜索广告审核不通过的原因
  18. ssh提交 hadoop集群
  19. Python-shogun安装问题
  20. Java新AIO/NIO2:AsynchronousFileChannel以Future方式读

热门文章

  1. 程序员的奋斗史(三十三)——人在囧途之应聘篇(三)
  2. 知识付费平台包括哪些功能版块?
  3. 36氪专访| 友盟+CEO朋新宇:大数据赛道会越来越宽,同时也会越来越头部化
  4. 满满干货!15个经典面试问题及答案
  5. [推荐系统]互联网推荐系统比较研究
  6. 【渝粤题库】广东开放大学 标准化法律法规 形成性考核
  7. 中国网络游戏行业研究报告-2010
  8. 20210125比较常用的vim配置文件及说明
  9. TalkingData游戏统计对接
  10. 小甲鱼(鱼C)课后作业代码 39讲