lua软件模拟spi

本代码可实现功能,但是不推荐使用,速度与spi外设相比,极慢

下面是正常的spi外设代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
require"utils"
require"pm"
pm.wake("wake11")
require"pins"

if _G.moduleType == 2 then pmd.ldoset(6,pmd.LDO_VMMC) end
local result = spi.setup(spi.SPI_1,0,0,8,800000,1,0)--初始化spi

log.info("spi1",spi.SPI_1)
log.info("testSpiFlash.init",result)
local cs = pins.setup(moduleType == 2 and pio.P0_10 or pio.P1_2,1)
local s = string.fromHex("9f000000000000")

sys.taskInit(function ()
sys.wait(5000)
while true do
cs(0)--需要手动下拉cs引脚电平
log.info("testSpiFlash.readFlashID",spi.send_recv(spi.SPI_1,s):toHex())--收发读写
cs(1)
sys.wait(200)
end
spi.close(spi.SPI_1)
end)

可以用下面的代码来代替(gpio需要自行更改):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
require"utils"
require"pins"

--软件模拟
local clk = pins.setup(33,0)
local cs = pins.setup(34,1)
local opin = pins.setup(36,0)
local ipin = pins.setup(35)
--pio.pin.setpull(pio.PULLDOWN,35)

sys.taskInit(function ()
log.info("spi start")
while true do
sys.wait(1000)
local r = {}--待接收到的数组
local s = string.char(0x9f,0,0,0,0,0,0)--待发送的字符串
cs(0)
for i=1,#s do
local rd = 0--临时存储的接收
local td = s:byte(i)--临时的发送数据
for j=1,8 do
opin(bit.isset(td,8-j) and 1 or 0)--根据发送的位来决定高低电平
clk(1)--时钟线拉高,开始采样
if ipin() == 1 then--如果接收线是高,那么把接受临时变量相应位置1
rd = bit.set(rd,8-j)--把接受临时变量相应位置1
end
clk(0)--时钟线拉低,准备下次
end
table.insert(r, string.char(rd))--接收数据,存到待接收到的数组中
end
cs(1)

local rec = table.concat(r, "")--接收到的数据连起来
log.info("receive data",rec:toHex())
end
end)

可以根据自己的需求。更改代码

上次更新 2021-01-28