基于STM32的无线通信模块使用—A7130

2.4G Hz的无线通信芯片A7130。本文简单介绍A7130的使用。
注:相关资源在这里

  • A7130简介
  • A7130 SPI接口
  • A7130寄存器配置及初始化
  • A7130数据传输
  • A7130扩展
  • A7130总结

一、A7130简介

A7130 is a high performance and low cost 2.4GHz ISM band wireless transceiver.user can configure on-air data rates to either 3Mbps or 4Mbps.
A7130 supports fast settling time (100 us) for frequency hopping system. For packet handling, A7130 has built-in separated.64-bytes TX/RX FIFO (could be logically extended to 4K bytes) for data buffering and burst transmission, auto-ack and auto-resend, CRC for error packet filtering
A7130’s control registers are accessed via 3-wire or 4-wire SPI interface such as TX/RF FIFO, ID register, RSSI value.
Another one, via SPI as well, is the unique Strobe command, A7130 can be controlled from power saving mode (deep sleep, sleep, idle, standby), TX mode, RX mode. In addition to the SPI, other connections between A7130 and MCU are GIO1 and GIO2, multi-function GPIO, to output A7130’s status so that MCU could use either polling or interrupt scheme for radio control.

从datasheet上面的信息可以得知A7130的几个特性:
1、A7130的传输速度有3Mbps和4Mbps两种,可见这速度传输图片数据完全是没问题的。
2、A7130有64Bytes的TX/RX FIFO,可扩展到4KBytes,这么大的FIFO,说明读写效率蛮可观的。支持自动应答自动重传,CRC校验,这在一定程度上保证了数据传输的可靠性。
3、A7130的控制寄存器支持3线或者4线的SPI方式的读写,也就是说无论是读写寄存器还是读写FIFO,都是通过SPI方式实现的。
4、A7130支持多种模式,可保证低功耗。
上面的这些信息将有助于我们接下来程序的编写。

二、A7130 SPI接口

1、接口说明

A7130 only supports one SPI interface with maximum data rate up to 10Mbps. MCU should assert SCS pin low (SPI chip select) to active accessing of A7130. Via SPI interface, user can access control registers and issue Strobe command.
3-wire SPI (SCS, SCK and SDIO) or 4-wire SPI (SCS, SCK, SDIO and GIO1/GIO2) configuration is provided. For 3-wire SPI, SDIO pin is configured as bi-direction to be data input and output. For 4-wire SPI, SDIO pin is data input and GIO1 (or GIO2) pin is data output. In such case, GIO1S (0bh) or GIO2S (0ch) should be set to [0110].

手册上说了需将SCS引脚拉低以选中芯片。3线SPI方式,SDIO引脚要配置成双向输入输出引脚。对于4线的SPI,SDIO作为输入引脚,GIO1和GIO2配置成输出引脚。配置GIO1和GIO2需要将控制寄存器Reg0b的GIO1S置为0110或Reg0c的GIO2S置为0110.
A7130支持8中模式(Sleep,Idle,STBY,PLL,RX,TX,FIFO Write Reset,FIFO Read Reset)。在实际的编程中,后四种模式直接的状态切换需要特别的注意。

2、SPI接口配置

在程序中,我们使用的是4线的SPI方式,使用到GIO2作为输出。

STM32引脚 A7130引脚
SPI_CS SCS
SPI_CLK SCK
SPI_MISO GIO2
SPI_MOSI SDIO
GPIOA_P1 GIO1

至于为什么要把GIO1接到PA1上面。因为在手册中提到无论是数据从FIFO发出去完成还是从FIFO中接收完成,都将要有一个标记来进行判断,此处我们把GIO1配置成发送接收完成的标记。

在Reg0c中,我们将GIO1配置成WTR(Wait until TX or RX Finished)。

在发送模式下,进入TX Mode,然后在RF Port中经过一小段时间(PDL+TDL,这段时间可通过寄存器控制),芯片自动在数据前面加上Premable等数据然后发送出去,此时WTR(GIO1)为高电平,当数据传输结束之后,WTR置为低电平,芯片自动进去PLL Mode。这样我们就可以通过判断GIO1的引脚变化来判断数据发送或者接收是否完成。

配置相关的SPI引脚之后,我们调用

A7130_SPI_Init()

函数,且之后调用

A7130_CS_HIGH()

把A7130的SCS引脚拉高,只有当我们对A7130进行操作时才拉低该引脚。当然,上面那两个函数要自己去封装实现。

三、A7130寄存器配置及初始化

1、A7130配置代码生成器

当SPI配置完成后我们就要检验SPI是否通。最简单的方式就是去读写它的芯片ID,看返回值是否是正确的,但是这步还不能实现。因为要读写芯片的ID之前要对A7130进行初始化操作,具体怎么初始化,在手册上面并没有说。那么怎么验证呢?首先尝试着去读写某个寄存器,通过示波器看看时钟是否正确,SPI写入是否正确以及时序是否正确。当这些都确认无误后,我们再去初始化A7130。
笙科公司为开发人员提供了一个工具RC_A7130_ReferenceCodeGenerator.exe可生成A7130的寄存器配置代码,不过生成的代码是仿SPI时序的,不是我们用的STM32固件的SPI接口,所以还需要修改部分代码。


注意红色的区域要根据自己的配置进行选择。其中的RF IO Setting中除WTR外都可不用配置。

生成三个文件A7130reg.h(定义寄存器的名称),define.h(数据类型的相关定义),main.c(主程序)

2、main.c

2.1、各个寄存器的值

这里面包含A7130所有寄存器的配置信息以及数据发送接收的示例程序。这里只贴出配置信息。

//-----------------------------------------------------------------------------
// RF ID code
//-----------------------------------------------------------------------------
const Uint8 code ID_Tab[] =
{0x54, 0x75, 0xC5, 0x2A
};// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//                                   NOTE                                    !!
// !!         THIS CONFIG TABLE ONLY USE ON RF CRYSTAL = 16MHz               !!
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
const Uint16 code A7130Config[] =
{//      address   name              Descript//      -------   ----              ---------0x00,   //0x00  ; MODE_REG          only reset, not use on config0x62,   //0x01  ; MODE_CONTROL_REG  FIFO mode, Enable ARSSI, Enable AIF0x00,   //0x02  ; CALIBRATION_REG0x3F,   //0x03  ; FIFO1_REG         0x00,   //0x04  ; FIFO2_REG0x00,   //0x05  ; FIFO_REG0x00,   //0x06  ; IDCODE_REG0x00,   //0x07  ; RCOSC1_REG0x00,   //0x08  ; RCOSC2_REG0x00,   //0x09  ; RCOSC3_REG0x00,   //0x0A  ; CKO_REG0x01,   //0x0B  ; GIO1 register,    WTR0x19,   //0x0C  ; GIO2 register,    SDO 0x9F,   //0x0D  ; DATARATE_REG      0x00,   //0x0E  ; PLL1_REG0x0E,   //0x0F  ; PLL2_REG          RFbase 2400.001MHz0x96,   //0x10  ; PLL3_REG0x00,   //0x11  ; PLL4_REG0x04,   //0x12  ; PLL5_REG0x3C,   //0x13  ; ChannelGroup1 register0x78,   //0x14  ; ChannelGroup2 register0xAF,   //0x15  ; TX1_REG           0x40,   //0x16  ; TX2_REG0x10,   //0x17  ; DELAY1_REG        0x60,   //0x18  ; DELAY2_REG        0x70,   //0x19  ; RX_REG            0x6F,   //0x1A  ; RXGAIN10xC2,   //0x1B  ; RXGAIN20x3D,   //0x1C  ; RXGAIN30xE7,   //0x1D  ; RXGAIN40x00,   //0x1E  ; RSSI_REG0xF1,   //0x1F  ; ADC_REG0x07,   //0x20  ; CODE1_REG         0x06,   //0x21  ; CODE2_REG0x2A,   //0x22  ; CODE3_REG0x60,   //0x23  ; IFCAL1_REG0xFF,   //0x24  ; IFCAL2_REG0x80,   //0x25  ; VCOCCAL_REG       0xD0,   //0x26  ; VCOCAL1_REG0x00,   //0x27  ; VCOCAL2_REG0x70,   //0x28  ; VCO deviation 1 register0x00,   //0x29  ; VCO deviation 2 register0x00,   //0x2A  ; DSA register0xDC,   //0x2B  ; VCO Modulation delay register0xF0,   //0x2C  ; BATTERY_REG       0x37,   //0x2D  ; TXTEST_REG        0x47,   //0x2E  ; RXDEM1_REG0xF7,   //0x2F  ; RXDEM2_REG0xF0,   //0x30  ; CPC1_REG           0x37,   //0x31  ; CPC2_REG           0x55,   //0x32  ; CRYSTALTEST_REG0x15,   //0x33  ; PLLTEST_REG0x15,   //0x34  ; VCOTEST1_REG0x00,   //0x35  ; RF Analog register0x00,   //0x36  ; Key data register0x77,   //0x37  ; Channel select register0x00,   //0x38  ; ROM register0x00,   //0x39  ; DataRate register0x00,   //0x3A  ; FCR register0x00,   //0x3B  ; ARD register0x00,   //0x3C  ; AFEP register0x00,   //0x3D  ; FCB register0x00,   //0x3E  ; KEYC register0x00,   //0x3F  ; USID register
};const Uint8 code A7130_Addr2A_Config[]=
{0x34, //page0,0x49, //page1,0x00, //Page2,0x80, //page3,0x80, //page4,0x00, //page5,0x0A, //page6,0x00, //page7,
};const Uint8 code A7130_Addr38_Config[]=
{0x00, //page0,0x10, //page1,0x20, //page2,0x24, //page3,0x20, //page4,
};
2.2、初始化
void initRF(void)
{//init io pinSCS = 1;SCK = 0;SDIO = 1;GIO1 = 1;GIO2 = 1;A7130_Reset();    //reset A7105 RF chipA7130_WriteID();  //write ID codeA7130_Config();   //config A7105 chipA7130_Cal();     //calibration IF,VCO,VCOC
}initRF();
StrobeCmd(CMD_STBY);
A7130_WriteReg( IFCAL2_REG, 0xFF );     //
A7130_WriteReg( TXTEST_REG, 0x37 );     //  TX power = 5dBm
A7130_WriteReg( MODECTRL_REG, 0x62 );   //  FIFO mode
A7130_WriteReg( PLL1_REG, 100 );        // set radio channel
A7130_WriteReg( CODE1_REG, 0x0F);       //  enable CRC check function

初始化A7130要Reset芯片,写ID,配置,Cal校准,然后进入STBY Mode,接下来设置发射功率等。上述的这些操作无非就是写寄存器,最关键的一个函数当然是A7130_WriteReg(Uint8 addr, Uint8 dataByte)。

void A7130_WriteReg(Uint8 addr, Uint8 dataByte)
{Uint8 i;SCS = 0;addr |= 0x00; //bit cmd=0,r/w=0for(i = 0; i < 8; i++){if(addr & 0x80)SDIO = 1;elseSDIO = 0;SCK = 1;_nop_();SCK = 0;addr = addr << 1;}_nop_();//send data bytefor(i = 0; i < 8; i++){if(dataByte & 0x80)SDIO = 1;elseSDIO = 0;SCK = 1;_nop_();SCK = 0;dataByte = dataByte << 1;}SCS = 1;
}

这里使用的是仿SPI的时序来写寄存器,我们需要转换为STM32库的形式,变成如下:

uint8_t SPI_SendByte(SPI_TypeDef *SPIx, uint8_t byte)
{/*!< Loop while DR register in not empty */while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET);/*!< Send byte through the SPI1 peripheral */SPI_I2S_SendData(SPIx, byte);/*!< Wait to receive a byte */while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET);/*!< Return the byte read from the SPI bus */return SPI_I2S_ReceiveData(SPIx);
}void A7130_WriteReg(uint8_t addr, uint8_t dataByte)
{A7130_CS_LOW(); addr |= 0x00;                    // bit6 writeSPI_SendByte(SPI1, addr);        // locate register address for writeSPI_SendByte(SPI1, dataByte);    // write dataA7130_CS_HIGH();
}

当然,还有个读寄存器的函数

uint8_t A7130_ReadReg(uint8_t addr)
{uint8_t data;A7130_CS_LOW();addr |= 0x40;                      // bit6 readSPI_SendByte(SPI1, addr);data= SPI_SendByte(SPI1, 0xff);    // 0xff is dummy bytesA7130_CS_HIGH();return data;
}

注意读写寄存器的时候,要遵循数据包的格式进行书写

最终,我们将A7130的初始化和配置集成到一个函数A7130_Init(),然后我们调用A7130_ReadID()读取ID,看读出来的数据是不是与我们之前在RC_A7130_ReferenceCodeGenerator.exe中设置的一样。

四、A7130数据传输

1、发送数据

1、设置FIFO大小;
2、重置FIFO指针;
3、选中芯片
4、定位到TX FIFO寄存器;
5、写入数据到TX FIFO中;
6、取消选中;
7、发送数据;
8、等待发送完毕。
按照这六个步骤,把数据写入到TX FIFO中,A7130就会自动把FIFO中的数据发送出去。

void A7130_WriteData(uint8_t data)
{A7130_WriteReg(FIFO1_REG, 64);        // setting FIFO lengthA7130_StrobeCmd(CMD_TFR);             // reset TX FIFO pointer              A7130_CS_LOW();                       // select chipSPI_SendByte(SPI1, FIFO_REG);         // locate TX FIFOSPI_SendByte(SPI1, data);             // write data into TX FIFOA7130_CS_HIGH();A7130_StrobeCmd( CMD_TX );            // transmit data from RF portwhile( A7130_isTxRxFinish() );        // wait until TX finished
}

2、接收数据

uint8_t A7130_ReadData(void)
{uint8_t data = 0;A7130_StrobeCmd(CMD_RX);        // in RX Modewhile( A7130_isTxRxFinish() );  // wait until receieve finishedA7130_CS_LOW();SPI_SendByte(SPI1, FIFO_REG | 0x40);  // locate RX FIFOdata  = ARC_SPI_SendByte(SPI1, 0xff); // read dataA7130_CS_HIGH();return data;
}

五、A7130扩展

上述只是A7130的一些基本的操作,最终还是要根据项目来使用。为了保证数据的可靠传输,我们可以把发射功率设大,采用自动应答自动重传的机制进行数据传输。为了读写速率,我们可以扩展FIFO。当然这些都要配置相关的寄存器来实现。A7130还提供了诸多功能,用户可根据需要配置寄存器。

六、A7130总结

A7130在传输速度上已经很快了,但是有点遗憾的是数据传输的可靠性不高。经过验证,当数据量大时或距离稍远时或者干扰较大,A7130的自动应答和自动重传并不如意。如果要保证数据的可靠性传输,需要用户自己定义一种简单的通信协议。但是如果数据量较小的情况下,可对该数据进行编码,然后再接收端进行解码。至于采用哪种编码方式,需用户根据自己的情况做出取舍。

基于STM32的无线通信模块使用——A7130相关推荐

  1. 基于STM32的无线通信模块使用——HC_05蓝牙串口

    注:以下某些资料来自于该模块淘宝店里有介绍,规格书没找到啊. 模块介绍 PC端配置模块,手机端连接模块 STM32串口配置模块 串口通信 小结 一.模块介绍 1.供电电压3.3V~3.6V: 2.支持 ...

  2. 基于数字电路交通灯信号灯控制系统设计-基于单片机病房温度监测与呼叫系统设计-基于STM32的无线蓝牙心电监护仪系统设计-基于STM32的智能蓝牙温控风扇控制设计-基于STM32的智能温室控制系统设计

    1617基于数字电路交通灯信号灯控制系统设计(仿真电路,论文报告)  摘  要:交通灯控制系统在城市交通控制中发挥着重要的作用,本次课程设计就是以城市交通灯控制系统为背景的,主要通过运用学过的数字电路 ...

  3. 基于STM32的智能温室控制系统仿真电路设计(温控补光)-基于STM32的智能蓝牙温控风扇控制系统设计-基于STM32的无线蓝牙心电监护仪系统设计【毕设课设分享】

    1609 基于STM32的智能蓝牙温控风扇控制系统设计-毕设课设 1.LCD1602液晶显示当前温度,温度上下限值,风扇等级,自动手动模式: 2.设置有4个按键,按键1可以设置自动和手动2种模式切换: ...

  4. 基于STM32的无线飞鼠(二)

    基于STM32的无线飞鼠(二) 在前一篇博客中讲了下一些题外话,从本篇开始讲讲重点的知识,说说无线飞鼠过程用到的模块 细说MPU6050 一. MPU6050简介 二. 细节问题 三. 相关技术 四. ...

  5. 基于STM32的无线体感仿生机械手的设计与实现

    研究目标 设计一款基于STM32的仿生机械手: (1)基于STM32的仿生机械手实现无线控制和有线控制. (2)实现串口指令控制仿生机械手动作. (3)实现仿生机械手具有多种工作模式. (4)实现数据 ...

  6. 基于STM32的无线模拟病房呼叫系统

    一. 系统设计和框图 本系统主要功能为模拟病房的无线呼叫系统,呼叫端(病床)为从机,被呼叫端(护士站)为主机,系统采用一主多从的通信方式,主机和从机之间采用无线通信方式. 主机端包含OLED显示模块( ...

  7. 基于STM32的无线抄表系统

    目录 一.项目描述 二.原理图 三.实物 四.代码 六.论文 七.资料清单 资料下载地址:基于STM32无线抄表系统 一.项目描述 1.通过串口获取电表数据,并在OLED液晶上显示: 2. 通过ESP ...

  8. 基于433M频率无线通信模块在评委台的无线传输应用

    1.433M频段特点 在无线电领域中,我们可以把无线电的种类按照频段来划分,如170M,315M,433M和2.4G等,本文主要以433M来介绍. 433MHZ频段的无线传输特点是:433MHZ是我们 ...

  9. 基于STM32的无线飞鼠(一)

    无线飞鼠(一) 时间过得好快,大三已经过了一半了,这段时间忙的没有更新过博客,回顾下自己这段时间中的收获,感觉蛮多的.下边就一一分享下. 一个月前,接到一个朋友的求助,帮忙做一份毕设,其实本来自己也没 ...

最新文章

  1. mysql为什么要压测_mysql集群压测的详细介绍
  2. 成功之路该如何走--工作半年的思考
  3. iOS更改状态栏前景色背景色
  4. Scala数据类型按精度(容量)大小排序
  5. 超好的Git学习网站
  6. Windows配置Gtkmm开发环境(with codeblocks)
  7. Python——(Anaconda+PyCharm)Youki的Python环境配置笔记(Windows版本)(legacy)~
  8. 计算机技术培训承诺书,软件职业技术学院学生干部刻苦学习、文明诚信承诺书...
  9. JavaScript进阶高级
  10. 连续arq协议的利用率_Chrome底层原理和HTTP协议 - 石吴玉
  11. Fedora 9 vmware 上网问题
  12. 计算机无法安装网卡驱动,网卡驱动安装不了,详细教您解决网卡驱动安装不了...
  13. Godaddy域名与腾讯云服务器ip绑定,使用域名访问
  14. 微信小程序如何获取用户绑定手机号
  15. input type=“file“属性详解,利用capture调用手机摄像头
  16. Chrome Extension 介绍
  17. 干货|Stakeholder利益相关者讲解
  18. 涂鸦Zigbee SDK开发系列教程——4.烧录授权
  19. dhcp应该开启还是关闭(dhcp应该开启还是关闭)
  20. 大数据技术的应用现状与展望

热门文章

  1. ip伪装软件对游戏多开有什么用?
  2. sd和emmc如何进行tuning
  3. java判断是否文件夹_java中怎么判断是否文件夹
  4. comsol5.0 matlab2011b,comsol 5.0 with MATLAB运行的问题
  5. 用HTML中的列表标签做一个导航栏吧
  6. 余额宝好不好?余额宝利息是多少?
  7. UltraCompare 22:文本对比工具 Mac版
  8. 从装系统这件事来谈谈一些知名互联网公司所谓的“用户体验”,蓝瘦,香菇。。。。。
  9. [ZZ] GTX 280 GPU architecture
  10. 中国联通与用友签署合作框架协议 多领域展开全面合作