LoRa无线通信技术介绍(四)基于STM32的SPI驱动
创始人
2024-06-03 13:36:54
0

SX1278芯片SPI时序逻辑介绍

LORA芯片的SX1278的SPI接口中CPOL=0和CPHA=0相对应的同步全双工协议从SPI接

口访问配置寄存器。仅在从机(slave)进行

有三种访问寄存器的方式:

  • 单访问:写访问时发送地址字节之后紧跟数据字节,读访问时地址字节之后紧跟读取字

节。NSS引脚在帧的起点拉低,并只在最后一个数据字节后才拉高。

  • 突发访问:地址字节之后跟有多个数据字节。该地址在各数据字节间自动内部递增。这

一模式在进行读访问和写访问时都是可用的。NSS引脚在帧的起点拉低并在各字节间

一直保持低位,仅在最后一个字节传输完后才拉高。

  • FIFO访问:如果地址字节与FIFO的地址一致,随后的数据字节将寻址FIFO。这一地址

不会自动递增,但会被记住,同时也不需要在各数据字节之间进行发送。NSS引脚在

帧的起点拉低并在各字节间一直保持低位,仅在最后一个字节传输完后才拉高

下图显示了对寄存器的典型SPI单次访问。

SPI时序图

MOSI在SCK下降沿由主机生成,并由SCK上升沿的从机(即SPI接口)进行抽样。MISO在

SCK下降沿由从机生成。

传输始终由变低的NSS引脚启动。当NSS较高时,MISO处在高阻抗状态。

第一个字节为地址字节,包括:

  • 一个wnr位,写访问时为1,读访问时为0;

  • 地址的7个位,首先为最高有效位。

无论是写访问中MOSI 主机发送的第二个字节还是读访问中MISO 主机接收的第二个字节

都是数据字节。该数据字节首先发送的是最高有效位。

进程中的字节可能通过MOSI(写访问)发送或MISO(读访问)接收,无需NSS 上升沿,

也无需重新发送地址。在FIFO 模式下,如果地址为FIFO 地址,这些字节将在FIFO 地址

中进行写/读。在突发模式下,如果地址不是FIFO 地址,该地址将在每收到一个新字节时

自动递增。

当NSS 变高时,帧结束。下一帧必须以一个地址字节开始。因此,单次访问模式是FIFO/

突发模式只有一个数据字节转移的一种特殊情况。

在写访问中,MISO 线路中由从机传输到主机的字节为写操作前被写入寄存器的值。

基于STM32F10XX的SPI驱动程序

#include 
#include  #include "stm32f10x.h"
#include "sx1276-Hal.h"void SpiInit( void );
uint8_t SpiInOut( uint8_t outData );void SX1276InitIo( void )
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |RCC_APB2Periph_AFIO, ENABLE );GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;// Configure NSS as outputGPIO_WriteBit( NSS_IOPORT, NSS_PIN, Bit_SET );GPIO_InitStructure.GPIO_Pin = NSS_PIN;GPIO_Init( NSS_IOPORT, &GPIO_InitStructure );// Configure radio DIO as inputsGPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;// Configure DIO0GPIO_InitStructure.GPIO_Pin =  DIO0_PIN;GPIO_Init( DIO0_IOPORT, &GPIO_InitStructure );// Configure DIO1GPIO_InitStructure.GPIO_Pin =  DIO1_PIN;GPIO_Init( DIO1_IOPORT, &GPIO_InitStructure );// Configure DIO2GPIO_InitStructure.GPIO_Pin =  DIO2_PIN;GPIO_Init( DIO2_IOPORT, &GPIO_InitStructure );// Configure DIO3GPIO_InitStructure.GPIO_Pin =  DIO3_PIN;GPIO_Init( DIO3_IOPORT, &GPIO_InitStructure );// Configure DIO4GPIO_InitStructure.GPIO_Pin =  DIO4_PIN;GPIO_Init( DIO4_IOPORT, &GPIO_InitStructure );// Configure DIO5GPIO_InitStructure.GPIO_Pin =  DIO5_PIN;GPIO_Init( DIO5_IOPORT, &GPIO_InitStructure );GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Pin = RESET_PIN;GPIO_Init( RESET_IOPORT, &GPIO_InitStructure );//SX1278 PA CONTROLGPIO_InitStructure.GPIO_Pin = TR_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(TR_IOPORT, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = PAEN_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(PAEN_IOPORT, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = PABYP_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(PABYP_IOPORT, &GPIO_InitStructure);GPIO_WriteBit( RESET_IOPORT, RESET_PIN, Bit_RESET );
}void SX1276Write(uint8_t addr, uint8_t data )
{//NSS = 0;NSS_IOPORT->BRR = NSS_PIN;SpiInOut( addr | 0x80 );SpiInOut( data);//NSS = 1;NSS_IOPORT->BSRR = NSS_PIN;
}void SX1276Read(uint8_t addr, uint8_t *data )
{//NSS = 0;NSS_IOPORT->BRR = NSS_PIN;SpiInOut( addr & 0x7F );*data = SpiInOut( 0 );//NSS = 1;NSS_IOPORT->BSRR = NSS_PIN;}void SX1276WriteBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
{uint8_t i;//NSS = 0;NSS_IOPORT->BRR = NSS_PIN;SpiInOut( addr | 0x80 );for( i = 0; i < size; i++ ){SpiInOut( buffer[i] );}//NSS = 1;NSS_IOPORT->BSRR = NSS_PIN;
}void SX1276ReadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
{uint8_t i;//NSS = 0;NSS_IOPORT->BRR = NSS_PIN;SpiInOut( addr & 0x7F );for( i = 0; i < size; i++ ){buffer[i] = SpiInOut( 0 );}//NSS = 1;NSS_IOPORT->BSRR = NSS_PIN;
}void SX1276WriteRxTx( uint8_t txEnable )
{if( txEnable != 0 ){PAEN_IOPORT->BSRR = PAEN_PIN;PABYP_IOPORT->BRR = PABYP_PIN;    //    PABYP_IOPORT->BSRR = PABYP_PIN;    TR_IOPORT->BSRR = TR_PIN;}else{//set RX modePAEN_IOPORT->BSRR = PAEN_PIN;PABYP_IOPORT->BRR = PABYP_PIN;    //    PABYP_IOPORT->BSRR = PABYP_PIN;    TR_IOPORT->BRR = TR_PIN;}
}//#define SPI_SIMULATION#define SPI_INTERFACE                               SPI2
#define SPI_CLK                                     RCC_APB1Periph_SPI2#define SPI_PIN_SCK_PORT                            GPIOB
#define SPI_PIN_SCK_PORT_CLK                        RCC_APB2Periph_GPIOB
#define SPI_PIN_SCK                                 GPIO_Pin_13#define SPI_PIN_MISO_PORT                           GPIOB
#define SPI_PIN_MISO_PORT_CLK                       RCC_APB2Periph_GPIOB
#define SPI_PIN_MISO                                GPIO_Pin_14#define SPI_PIN_MOSI_PORT                           GPIOB
#define SPI_PIN_MOSI_PORT_CLK                       RCC_APB2Periph_GPIOB
#define SPI_PIN_MOSI                                GPIO_Pin_15void SpiInit( void )
{SPI_InitTypeDef SPI_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;/* Enable peripheral clocks --------------------------------------------------*//* Enable SPIy clock and GPIO clock for SPIy */RCC_APB2PeriphClockCmd( SPI_PIN_MISO_PORT_CLK | SPI_PIN_MOSI_PORT_CLK |SPI_PIN_SCK_PORT_CLK, ENABLE );RCC_APB1PeriphClockCmd( SPI_CLK, ENABLE );#ifdef SPI_SIMULATION//tian change/* GPIO configuration ------------------------------------------------------*/GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin = SPI_PIN_SCK;GPIO_Init( SPI_PIN_SCK_PORT, &GPIO_InitStructure );GPIO_InitStructure.GPIO_Pin = SPI_PIN_MOSI;GPIO_Init( SPI_PIN_MOSI_PORT, &GPIO_InitStructure );GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  GPIO_InitStructure.GPIO_Pin = SPI_PIN_MISO;GPIO_Init( SPI_PIN_MISO_PORT, &GPIO_InitStructure );//end
#else/* GPIO configuration ------------------------------------------------------*/GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Pin = SPI_PIN_SCK;GPIO_Init( SPI_PIN_SCK_PORT, &GPIO_InitStructure );GPIO_InitStructure.GPIO_Pin = SPI_PIN_MOSI;GPIO_Init( SPI_PIN_MOSI_PORT, &GPIO_InitStructure );GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  GPIO_InitStructure.GPIO_Pin = SPI_PIN_MISO;GPIO_Init( SPI_PIN_MISO_PORT, &GPIO_InitStructure );// RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO, ENABLE );/* SPI_INTERFACE Config -------------------------------------------------------------*/SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;SPI_InitStructure.SPI_Mode = SPI_Mode_Master;SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;// SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; // 5 MHzSPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32; // 2.25 MHzSPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;SPI_InitStructure.SPI_CRCPolynomial = 7;SPI_Init( SPI_INTERFACE, &SPI_InitStructure );SPI_Cmd( SPI_INTERFACE, ENABLE );#endif}
#define SPI_DELAY(x)  delay(100*x)
#define NOP(x)  delay(2)
void delay(unsigned short t)
{while(t--);
}uint8_t SpiInOut( uint8_t outData )
{/* Send SPIy data */
#ifdef SPI_SIMULATIONuint8_t i,SdoData=0x00;for(i = 0; i < 8; i++){SPI_DELAY(20);GPIO_WriteBit(SPI_PIN_SCK_PORT,SPI_PIN_SCK,Bit_RESET);if(outData & 0x80)GPIO_WriteBit(SPI_PIN_MOSI_PORT,SPI_PIN_MOSI,Bit_SET);elseGPIO_WriteBit(SPI_PIN_MOSI_PORT,SPI_PIN_MOSI,Bit_RESET);SPI_DELAY(20);outData <<= 1;SdoData<<=1;//SPI_CLK = LOW;if(GPIO_ReadInputDataBit(SPI_PIN_MISO_PORT,SPI_PIN_MISO) == Bit_SET){SdoData |= 0x01;}else{SdoData &= 0xfe;}SPI_DELAY(20);    GPIO_WriteBit(SPI_PIN_SCK_PORT,SPI_PIN_SCK,Bit_SET);}SPI_DELAY(20);    GPIO_WriteBit(SPI_PIN_SCK_PORT,SPI_PIN_SCK,Bit_RESET);return SdoData;
#elseSPI_I2S_SendData( SPI_INTERFACE, outData );
//DBUG("%02x\r\n",outData);while( SPI_I2S_GetFlagStatus( SPI_INTERFACE, SPI_I2S_FLAG_RXNE ) == RESET );return SPI_I2S_ReceiveData( SPI_INTERFACE );
#endif
}

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...