esp32的micropython,怎样利用si24r1与SI24R2E(2.4GHz 超低功耗有源 RFID 标签系统 SoC 单芯片)进行通讯,之前参考王铭东up主的教程成功将两个si24r1进行了通讯,但是想与SI24R2E通讯,尝试了好几天,未果,实在想不出解决办法了,在此希望各位帮忙解答。以下分别是库的代码,和我的代码
"""NRF24L01 driver for MicroPython
"""
# NRF24L01库的名字,注释是我微软翻译成中文的
from micropython import const
import utime
# nRF24L01+ registers
CONFIG = const(0x00) #读配置寄存器,低5位为寄存器地址
EN_RXADDR = const(0x02) #
SETUP_AW = const(0x03)
SETUP_RETR = const(0x04)
RF_CH = const(0x05)
RF_SETUP = const(0x06)
STATUS = const(0x07)
RX_ADDR_P0 = const(0x0A)
TX_ADDR = const(0x10)
RX_PW_P0 = const(0x11)
FIFO_STATUS = const(0x17)
DYNPD = const(0x1C)
# CONFIG register
EN_CRC = const(0x08) # enable CRC
CRCO = const(0x04) # CRC encoding scheme; 0=1 byte, 1=2 bytes
PWR_UP = const(0x02) # 1=power up, 0=power down
PRIM_RX = const(0x01) # RX/TX control; 0=PTX, 1=PRX
# RF_SETUP register
POWER_0 = const(0x00) # -18 dBm
POWER_1 = const(0x02) # -12 dBm
POWER_2 = const(0x04) # -6 dBm
POWER_3 = const(0x06) # 0 dBm
SPEED_1M = const(0x00)
SPEED_2M = const(0x08)
SPEED_250K = const(0x20)
# 状态寄存器
RX_DR = const(0x40) # RX data ready; write 1 to clear
TX_DS = const(0x20) # 发送的 TX 数据;写入 1 以清除
MAX_RT = const(0x10) # max retransmits reached; write 1 to clear
# FIFO_STATUS注册
RX_EMPTY = const(0x01) # 1 if RX FIFO is empty
# 指令常量
R_RX_PL_WID = const(0x60) # read RX payload width
R_RX_PAYLOAD = const(0x61) # read RX payload
W_TX_PAYLOAD = const(0xA0) # write TX payload
FLUSH_TX = const(0xE1) # flush TX FIFO
FLUSH_RX = const(0xE2) # flush RX FIFO
NOP = const(0xFF) # 用于读取状态寄存器
class NRF24L01:
def __init__(self, spi, cs, ce, channel=46, payload_size=16):
#数据小于等于32位
assert payload_size <= 32
#设置缓冲区
self.buf = bytearray(1)
# 设置SPI
self.spi = spi
self.cs = cs
self.ce = ce
# 设置传输速率
self.init_spi(4000000)
# 重置所有内容
ce.init(ce.OUT, value=0)
cs.init(cs.OUT, value=1)
self.payload_size = payload_size
self.pipe0_read_addr = None
utime.sleep_ms(5)
# 将地址宽度设置为 5 字节并检查设备是否存在
self.reg_write(SETUP_AW, 0b11)
if self.reg_read(SETUP_AW) != 0b11:
raise OSError("nRF24L01+ 硬件无响应")
# 禁用动态有效负载
self.reg_write(DYNPD, 0)
# 自动重传延迟:1750us
# 自动重传次数:8
self.reg_write(SETUP_RETR, (6 << 4) | 8)
# 设置射频功率和速度
self.set_power_speed(POWER_3, SPEED_250K) # 最适合点对点链接
# 初始化 CRC
self.set_crc(2)
# 清除状态标志
self.reg_write(STATUS, RX_DR | TX_DS | MAX_RT)
# 设置通道
self.set_channel(channel)
# 清除缓冲区
self.flush_rx()
self.flush_tx()
def init_spi(self, baudrate):
try:
master = self.spi.MASTER
except AttributeError:
self.spi.init(baudrate=baudrate, polarity=0, phase=0)
else:
self.spi.init(master, baudrate=baudrate, polarity=0, phase=0)
def reg_read(self, reg):
self.cs(0)
self.spi.readinto(self.buf, reg)
self.spi.readinto(self.buf)
self.cs(1)
return self.buf[0]
def reg_write_bytes(self, reg, buf):
self.cs(0)
self.spi.readinto(self.buf, 0x20 | reg)
self.spi.write(buf)
self.cs(1)
return self.buf[0]
def reg_write(self, reg, value):
self.cs(0)
self.spi.readinto(self.buf, 0x20 | reg)
ret = self.buf[0]
self.spi.readinto(self.buf, value)
self.cs(1)
return ret
def flush_rx(self):
self.cs(0)
self.spi.readinto(self.buf, FLUSH_RX)
self.cs(1)
def flush_tx(self):
self.cs(0)
self.spi.readinto(self.buf, FLUSH_TX)
self.cs(1)
# 权力是POWER_x定义之一;速度是SPEED_x定义之一
def set_power_speed(self, power, speed):
setup = self.reg_read(RF_SETUP) & 0b11010001
self.reg_write(RF_SETUP, setup | power | speed)
# 长度(以字节为单位):0、1 或 2
def set_crc(self, length):
config = self.reg_read(CONFIG) & ~(CRCO | EN_CRC)
if length == 0:
pass
elif length == 1:
config |= EN_CRC
else:
config |= EN_CRC | CRCO
self.reg_write(CONFIG, config)
def set_channel(self, channel):
self.reg_write(RF_CH, min(channel, 40))
# 地址应为长度为 5 字节的字节对象
def open_tx_pipe(self, address):
assert len(address) == 3
self.reg_write_bytes(RX_ADDR_P0, address)
self.reg_write_bytes(TX_ADDR, address)
self.reg_write(RX_PW_P0, self.payload_size)
# 地址应为 5 字节长的字节对象
# 管道 0 和 1 有 5 字节地址
# 管道 2-5 使用与管道 1 相同的 4 个最高有效字节,外加 1 个额外的字节
def open_rx_pipe(self, pipe_id, address):
assert len(address) == 3
assert 0 <= pipe_id <= 5
if pipe_id == 0:
self.pipe0_read_addr = address
if pipe_id < 2:
self.reg_write_bytes(RX_ADDR_P0 + pipe_id, address)
else:
self.reg_write(RX_ADDR_P0 + pipe_id, address[0])
self.reg_write(RX_PW_P0 + pipe_id, self.payload_size)
self.reg_write(EN_RXADDR, self.reg_read(EN_RXADDR) | (1 << pipe_id))
def start_listening(self):
self.reg_write(CONFIG, self.reg_read(CONFIG) | PWR_UP | PRIM_RX)
self.reg_write(STATUS, RX_DR | TX_DS | MAX_RT)
if self.pipe0_read_addr is not None:
self.reg_write_bytes(RX_ADDR_P0, self.pipe0_read_addr)
self.flush_rx()
self.flush_tx()
self.ce(1)
utime.sleep_us(130)
def stop_listening(self):
self.ce(0)
self.flush_tx()
self.flush_rx()
# 如果有任何数据可用于接收,则返回 True
def any(self):
return not bool(self.reg_read(FIFO_STATUS) & RX_EMPTY)
def recv(self):
# 得到数据
self.cs(0)
self.spi.readinto(self.buf, R_RX_PAYLOAD)
buf = self.spi.read(self.payload_size)
self.cs(1)
# 清除 RX 就绪标志
self.reg_write(STATUS, RX_DR)
return buf
# 阻止等待 TX 完成
def send(self, buf, timeout=500):
self.send_start(buf)
start = utime.ticks_ms()
result = None
while result is None and utime.ticks_diff(utime.ticks_ms(), start) < timeout:
result = self.send_done() # 1 == success, 2 == fail
if result == 2:
raise OSError("send failed")
# 非阻塞 TX
def send_start(self, buf):
# 向上
self.reg_write(CONFIG, (self.reg_read(CONFIG) | PWR_UP) & ~PRIM_RX)
utime.sleep_us(150)
# 发送数据
self.cs(0)
self.spi.readinto(self.buf, W_TX_PAYLOAD)
self.spi.write(buf)
if len(buf) < self.payload_size:
self.spi.write(b"\x00" * (self.payload_size - len(buf))) # pad out data
self.cs(1)
# 启用芯片,使其可以发送数据
self.ce(1)
utime.sleep_us(15) # needs to be >10us
self.ce(0)
# 如果发送仍在进行中,则返回 None,1 表示成功,2 表示失败
def send_done(self):
if not (self.reg_read(STATUS) & (TX_DS | MAX_RT)):
return None # TX 未完成
# 完成或失败:获取并清除状态标志,关闭电源
status = self.reg_write(STATUS, RX_DR | TX_DS | MAX_RT)
self.reg_write(CONFIG, self.reg_read(CONFIG) & ~PWR_UP)
return 1 if status & TX_DS else 2
#以下是应用代码
import ustruct as struct
import utime, time
from machine import Pin, SPI
from NRF24L01 import NRF24L01
from micropython import const
_RX_POLL_DELAY = const(15)
cfg = {"spi": -1, "miso": 17, "mosi": 16, "sck": 4, "csn": 2, "ce": 15}
# Addresses are in little-endian format. They correspond to big-endian
pipes = (b"\xe5\xe3\xe7", b"\xe5\xe3\xe7")
nrf = None
def call_back(*argc):
# print(argc)
print("有数据...")
if nrf.any():
while nrf.any():
buf = nrf.recv()
(millis, ) = struct.unpack("i", buf)
print("received:", millis)
utime.sleep_ms(_RX_POLL_DELAY)
def slave():
global nrf
p5 = Pin(5, Pin.IN)
p5.irq(trigger=Pin.IRQ_FALLING, handler=call_back)
csn = Pin(cfg["csn"], mode=Pin.OUT, value=1)
ce = Pin(cfg["ce"], mode=Pin.OUT, value=0)
spi = SPI(-1, sck=Pin(cfg["sck"]), mosi=Pin(cfg["mosi"]), miso=Pin(cfg["miso"]))
nrf = NRF24L01(spi, csn, ce, payload_size=4)
nrf.open_tx_pipe(pipes[0])
nrf.open_rx_pipe(0, pipes[0])
nrf.stop_listening()
nrf.start_listening()
print("NRF24L01 slave mode, waiting for packets... (ctrl-C to stop)")
while True:
print("waiting ....")
time.sleep(1)
slave()
你把教程发给我看一下有没有错误地方