Toggle navigation
首页
(current)
问答
文章
话题
商城
登录
注册
合宙Air系列模块外部总线接口常见用法-SPI总线,中
SPI
入门教程
720SL
目前合宙Air系列模块外部可用的通用总线接口基本上有UART,I2C,SPI这三种,下面我将结合有限的知识,对这三种总线进行一一介绍,并结合常用外部器件对总线进行实测。 本文的上部提到了SPI的基本知识,本文将结合一个小的demo对合宙4G模块的SPI功能做一简要测试。
## Air720SL模块 SPI接口简介 Air720模块的29,30,31,32 引脚构成了一个标准4线式SPI接口,在Air720SL EVB开发板上对应关系如下: SPI1_CS <-> GPIO_34 <-> Pin30 SPI1_CLK <-> GIOP_33 <-> Pin32 SPI1_DO <-> GPIO_36 <-> Pin29 SPI1_DI <-> GPIO_35 <-> Pin31 在进行接口测试的时候,我们只需要短接SPI_DO与SPI_DI,就可以对SPI接口进行打环测试。 ![](/static/editormd/php/../uploads/5_11737.jpg) ## SPI测试代码编写 对于一个数据总线,其操作无外乎读写。 SPI总线是双工总线,这意味着读和写是同时进行的,我们使用一个demo发送一组字符串,或者16进制序列来模拟总线读写。 local modname = ... local M = {} _G[modname] = M require "pins" -- -- module locals -- local CS_PIN = 30 -- set CSN gpio level local function csn(value) local level = (value > 0) and 1 or 0 pins.setup(CS_PIN,level) end spi.setup(0,0,0,8,800000,1) sys.taskInit(function(...) while true do log.info("test","SPI test Begin @ Port",spi.SPI_1) sys.wait(2000) csn(0) local msg="ABCDEFG" log.info("test","SPI Sending #",msg) log.info("test","SPI Receiving #",spi.send_recv(0,msg)) csn(1) sys.wait(2000) csn(0) local snd={0,1,2,3,4,5} --准备发送数据的表 local rsv={} --准备接收数据的表 local ss="" for i = 1, #snd, 1 do ss=ss..string.char(snd[i]) end local rr=spi.send_recv(0,ss) for i = 1, #rr, 1 do table.insert(rsv,string.byte(rr:sub(i,i))) end log.info("test","SPI Sending #",table.concat(snd)) log.info("test","SPI Receiving #",table.concat(rsv)) csn(1) end end) ## SPI硬件连接: 下面是在Air720sl开发板上进行自测试的具体连接方式 ![](/static/editormd/php/../uploads/5_78204.jpg) 实际的连线效果如下 ![](/static/editormd/php/../uploads/5_10039.jpg) 测试的效果如下: ![](/static/editormd/php/../uploads/5_93884.jpg) 可以看到,发送的字符串“ABCDE” 和二进制数0,1,2,3,4,5被成功的回显了出来,您也可以尝试把DI与GND相连,这时候将得到的返回是一串0 ## 编写一个基本的SPI驱动 有了上面的测试成果,就可以尝试编写设备的底层驱动了,下面是我为测试nRF24L01 2.4G收发模组初步编写的底层函数: -- 设置CE引脚,此引脚用来打开nRF24X芯片 local function nrf24_ce(value) local level = (value > 0) and 1 or 0 pins.setup(CE_PIN,level) end -- 设置CS引脚,此引脚用来选通nRF24X的SPI引脚 local function nrf24_csn(value) local level = (value > 0) and 1 or 0 pins.setup(CS_PIN,level) end -- reverse 5byte pipe address local function reverse_addr(addr_in) local addr_out = {} for i = 1, 5 do addr_out[i] = addr_in[5 - i + 1] or 0x0 end return addr_out end -- -- module exports -- -- 初始化模组 function M.nrf24_hw_init() --打开SPI引脚的供电 pmd.ldoset(6,pmd.LDO_VMMC) spi.setup(0,0,0,8,110000,1) pins.setup(CE_PIN,1) pins.setup(CS_PIN,1) end --发送一条指令,返回发送命令的长度 function M.nrf24_send_cmd(cmd) nrf24_csn(0) local ret=0 ret=spi.send(0,string.char(cmd)) nrf24_csn(1) return ret end --发送一条含数据参数的命令,并返回状态 function M.nrf24_msend_cmd(cmd, values) nrf24_csn(0) local ret=spi.send_recv(0,string.char(cmd)..table.concat(values)) nrf24_csn(1) return string.byte(ret:sub(1,1)) end --发送NOP指令,返回状态 function M.nrf24_get_status() nrf24_csn(0) local status=spi.send_recv(0, string.char(NOP)) nrf24_csn(1) return string.byte(status) end --发送一条单字节请求,并返回单字节数据 function M.nrf24_send_req(req) nrf24_csn(0) local rsp=spi.send_recv(0, string.char(req)..string.char(0xff)) nrf24_csn(1) return string.byte(rsp:sub(2,2)) end --发送一条请求,并返回指定字节长度的数据 function M.nrf24_msend_req(req, len) input = {} for i = 1, len do input[i] = string.char(0xff) end nrf24_csn(0) local output=spi.send_recv(0, string.char(req)..table.concat(input)) nrf24_csn(1) return stringtoTable(output:sub(2,-1)) end --读取单个寄存器的值 function M.nrf24_read_register(reg) nrf24_csn(0) local register=string.char(bit.bor(R_REGISTER, bit.band(REGISTER_MASK, reg))) local ret=spi.send_recv(0,register..string.char(0xff)) nrf24_csn(1) return string.byte(ret:sub(2,2)) end --读取多个寄存器的值 function M.nrf24_mread_register(reg, len) input = {} for i = 1, len do input[i] = string.char(0xff) end nrf24_csn(0) local register=string.char(bit.bor(R_REGISTER, bit.band(REGISTER_MASK, reg))) local output=spi.send_recv(0,register..table.concat(input)) nrf24_csn(1) return stringtoTable(output:sub(2,-1)) end --写入单个寄存器的值,返回状态 function M.nrf24_write_register(reg, value) nrf24_csn(0) local register=string.char(bit.bor(W_REGISTER, bit.band(REGISTER_MASK, reg))) local ret=spi.send_recv(0,register..string.char(value)) nrf24_csn(1) return string.byte(ret) end --写入多个寄存器的值,返回状态 function M.nrf24_mwrite_register(reg, values) nrf24_csn(0) local register=string.char(bit.bor(W_REGISTER, bit.band(REGISTER_MASK, reg))) local ret=spi.send_recv(0,register..table.concat(values)) nrf24_csn(1) return string.byte(ret:sub(1,1)) end 在本文的下篇,我将配合这些API底层函数对nRF24L01模块进行基本的通讯测试,敬请期待。 最后再次感谢您的阅读,祝您生活愉快,开发顺利。 特别提示:本文用到的固件包尚属于内测阶段,如果项目需要,请与您对应的销售经理联系。
发表于 2020-02-06 23:49
阅读 ( 2290 )
分类:
默认分类
0 推荐
收藏
你可能感兴趣的文章
记录720S系列使用阿里云升级过程中遇到的坑
1907 浏览
X、合宙Air模块Luat开发:全网首发,通过iic直接驱动OLED,720Sl开始有显时代
2734 浏览
合宙Air系列模块外部总线接口常见用法-SPI总线,上
2110 浏览
用合宙Air720的SPI接口驱动nRF24L01
1668 浏览
合宙2G、4G模块供电、取电杂谈
6358 浏览
相关问题
Air720G的SPI问题
0 回答
Air720怎么还没有支持SPI?
1 回答
Air202模块的SPI1管脚(PIN2、3、4、5)的电压域VMMC如何设置?
3 回答
0 条评论
请先
登录
后评论
柴松
技术销售
5 篇文章
作家榜
»
技术销售Delectate
43 文章
陈夏
26 文章
国梁
24 文章
miuser
21 文章
晨旭
20 文章
朱天华
19 文章
金艺
19 文章
杨奉武
18 文章
×
发送私信
发给:
内容:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!