树莓派移植SX1278 LoRa通信--使用wiringPiSPI移植SPI通信接口

一、SPI接口

树莓派3B+上的SPI接口如下所示,有两组SPI,分别由CE0和CE1来进行选择。

首先查看树莓派的SPI是否启用,在/dev查看是否有spidev0.0和spidev0.1

如果不存在spi设备号,需要在raspi-config中启用,在命令行输入:sudo raspi-config 

选Interfacing Options,选择SPI,选择enable。

二、wiringPiSPI库

wiringPISPI库提供了树莓派的SPI驱动调用,包含四个接口函数。

2.1 获取SPI的描述符 wiringPiSPIGetFd    

int wiringPiSPIGetFd     (int channel) ;

输入参数为通道,由CE0和CE1决定连接的是哪一个SPI,CE0连接SPI0,CE1连接SPI1。

2.2 SPI读写函数 wiringPiSPIDataRW  

int wiringPiSPIDataRW    (int channel, unsigned char *data, int len) ;

由于SPI是上升沿下数据,下降沿读数据的,因此,一个时钟即可同时完成读写。wiringPiSPIDataRW函数同时执行读写,因此,读取的数据会覆盖写入的数据空间,即读写命令都会操作data指针指向的buff。调用一次即完成一次读写,片选使能CE0和CE1由该函数自动设置,无需再次操作。

2.3 SPI模式设置函数 wiringPiSPISetupMode 

int wiringPiSPISetupMode (int channel, int speed, int mode) ;

该函数设置SPI的模式,包括通道(0,1),SPI速度,和SPI模式(0,1,2,3)。SPI有四种工作模式,各个工作模式的不同在于SCLK不同, 具体工作由CPOL,CPHA决定

  • CPOL: (Clock Polarity),时钟极性

          当CPOL为0时,时钟空闲时电平为低;

          当CPOL为1时,时钟空闲时电平为高;

  • CPHA:(Clock Phase),时钟相位

          当CPHA为0时,时钟周期的上升沿采集数据,时钟周期的下降沿输出数据;

          当CPHA为1时,时钟周期的下降沿采集数据,时钟周期的上升沿输出数据;

一般采用模式0,可以设置为:

wiringPiSPISetupMode (0, 500000, 0);//500kHz

2.4 SPI默认模式0设置 wiringPiSPISetup    

int wiringPiSPISetup     (int channel, int speed) ;

此函数直接默认了SPI模式为0,只需设置通道和速度即可。

三、SX1278 移植SPI

根据SX1278的接口函数驱动代码可知,只需要自己实现LoRa_Write_Buff和LoRa_Read_Buff即可。两者函数的接口形式为:

void LoRa_Write_Buff(uint8_t addr,uint8_t *buffer,uint8_t size);

void LoRa_Read_Buff(uint8_t addr, uint8_t *buffer, uint8_t size);

即调用上述函数对SX1278的寄存器进行指定长度的读写。根据手册,可知在进行SPI读写之前需要先发送操作地址码,同时读操作的地址最高位为1,写操作的地址最高位为地址0。

因此,可以在读写之前需要进行寄存器的地址读写配置,static uint8_t Cfg_SpiModeRW(uint8_t rw, uint8_t val)。

/*!
* \brief   Configure the SPI read and write mode
* \para    rw,uint8_t, read mode = SPI_LORA_READ and write mode = SPI_LORA_WRITE
           SPI_LORA_READ = 0, SPI_LORA_WRITE = 1, a Marao define
* \retval  a_val:uint8_t,cfg_addr
*/
static uint8_t Cfg_SpiModeRW(uint8_t rw, uint8_t val)
{
	uint8_t a_val;
	if(rw == SPI_LORA_READ)
	{
		a_val = 0x7F & val;
	}
	else if(rw == SPI_LORA_WRITE)
	{
		a_val = 0x80 | val;
	}
	return a_val;
}

SX1278的SPI时序图如下:

wiringPiSPI的wiringPiSPIDataRW 函数同时执行读写,且自动控制CE接口,因此,LoRa_Write_Buff和LoRa_Read_Buff中需要把数据buff和地址操作CMD提前准备好,然后调用一次wiringPiSPIDataRW函数即可实现指定长度和寄存器的SPI读写。具体移植如下:

/*!
* \brief   LoRa write buff with SPI, using wiringPiSPI wiringPiSPIDataRW interface
* \para    addr:uint8_t, LoRa Reg addr
           buffer:uint8_t pointer, write buffer
           size:uint8_t,size of buffer byte to write
* \retval  none
*/
void LoRa_Write_Buff(uint8_t addr,uint8_t *buffer,uint8_t size)
{
	uint8_t cmd;
	uint8_t buf[256];
	buf[0] = Cfg_SpiModeRW(SPI_LORA_WRITE,addr);
	memcpy(buf+1,buffer,size);
	wiringPiSPIDataRW(SPI_CHANNEL_0,buf,size+1);//build addr+buff cmd
}
/*!
* \brief   LoRa read buff with SPI, using wiringPiSPI wiringPiSPIDataRW interface
* \para    addr:uint8_t, LoRa Reg addr
           buffer:uint8_t pointer, read buffer
           size:uint8_t,size of buffer byte to read
* \retval  none
*/
void LoRa_Read_Buff(uint8_t addr, uint8_t *buffer, uint8_t size)
{	
	uint8_t cmd;
	uint8_t buf[257];
	buf[0] = Cfg_SpiModeRW(SPI_LORA_READ,addr);
	wiringPiSPIDataRW(SPI_CHANNEL_0,buf,size+1);
	memcpy(buffer,buf+1,size);//remove fisrt val, which means addr
}

移植的时候,别忘了头文件

#include "wiringPi.h"
#include "wiringPiSPI.h"

至此,SPI移植完毕。

其他:

树莓派移植SX1278 LoRa通信--使用wiringPi 移植GPIO中断

树莓派移植SX1278 LoRa通信--使用wiringPiSPI移植SPI通信接口

树莓派UART串口编程--使用wiringPi库-C开发【1-基础应用】

树莓派UART串口编程--使用wiringPi库-C开发【2-修改驱动】

树莓派Raspberry 操作GPIO--LED

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值