A7139 无线通信驱动(STM32) 增加FIFO扩展模式,可以发送超大数据包_a7139 例程-程序员宅基地

技术标签: STM32  CortexM3(STM32)  A7109  A7139程序  A7139  A7129  

A7139 拥有电磁波唤醒以及10mW的发射功率,非常容易实现长距离通信,目前测试有障碍物可以轻松达到300m以上.

通过几天的调试,目前可以发送任意大小的数据包,大小为1-16KB,全部使用中断收发,效率极高。

增加波特率设置2Kbps-100Kbps任意设置

增加通信信道设置0-255

增加发送功率设置0-7


底层代码

/*************************************************************************************************************
 * 文件名:		A7139.c
 * 功能:		STM32 A7139驱动
 * 作者:		[email protected]
 * 创建时间:	2015-07-19
 * 最后修改时间:2015-12-30
 * 详细:		A7139驱动
*************************************************************************************************************/		
#include "SYSTEM.H"
#include "GPIO_INIT.H"
#include "a7139.H"
#include "LED.H"



//晶振寄存器,用于设置晶振以及PAGE地址
//用于缓存寄存器7的值
static u16 A7139_CRYSTAL_REG = 0x18;

//单包数据发送超时时间
#define A7139_SEND_TIME_OUT		5	//单位10ms

//基础频率,设置频率范围为420.500MHZ~452.375MHZ ,频道差为125KHZ
#define A7139_BASE_FRE			420.5f

//调试开关
#define A7193_DBUG	1
#if A7193_DBUG
	#include "system.h"
	#define A7193_debug(format,...)	uart_printf(format,##__VA_ARGS__)
#else
	#define A7193_debug(format,...)	/\
/
#endif	//A7193_DBUG

vu8 IntCnt = 0;

//寄存器配置
typedef struct
{
	u16 SCLOCK;		//系统时钟寄存器
	u16 PLL1;		//PLL1
	u16 PLL2;		//PLL2
	u16 PLL3;		//PLL3
	u16 PLL4;		//PLL4
	u16 PLL5;		//PLL5
	u16 PLL6;		//PLL6
	u16 CRYSTAL;	//晶振设置
	u16 PREG8S;		//寄存器组,由CRYSTAL控制切换
	u16 PREG9S;		//寄存器组,由CRYSTAL控制切换
	u16 RX1;		//接收设置1
	u16 RX2;		//接收设置2
	u16 ADC;		//ADC
	u16 PIN;		//PIN
	u16 CALIB;		//Calibration
	u16 MODE;		//模式控制
} A7139_CONFIG_YPTE;



const u16 A7139Config[]=		
{
		0x0021,		//SYSTEM CLOCK register,
		0x0A21,		//PLL1 register,
		0xDA05,		//PLL2 register,    433.301MHz
		0x0000,		//PLL3 register,
		0x0A20,		//PLL4 register,
		0x0024,		//PLL5 register,
		0x0000,		//PLL6 register,
		0x0001,		//CRYSTAL register,
		0x0000,		//PAGEA,
		0x0000,		//PAGEB,
		0x18D4,		//RX1 register,		IFBW=100KHz, ETH=1	
		0x7009,		//RX2 register,		by preamble
		0x4400,		//ADC register,
		0x0800,		//PIN CONTROL register,		Use Strobe CMD
		0x4845,		//CALIBRATION register,
		0x20C0		//MODE CONTROL register, 	Use FIFO mode
};

const u16 A7139Config_PageA[]=   
{
		0xF706,		//TX1 register, 	Fdev = 37.5kHz
		0x0000,		//WOR1 register,
		0xF800,		//WOR2 register,
		0x1107,		//RFI register, 	Enable Tx Ramp up/down
		0x0170,		//PM register,
		0x0201,		//RTH register,
		0x400F,		//AGC1 register,
		0x2AC0,		//AGC2 register,
	    0x0041,   	//GIO register      GIO1->WTR GIO2->WTR 
		0xD281,		//CKO register
		0x0004,		//VCB register,
		0x0A21,		//CHG1 register, 	430MHz
		0x0022,		//CHG2 register, 	435MHz
		0x003F,		//FIFO register, 	FEP=63+1=64bytes
		0x1507,		//CODE register, 	Preamble=4bytes, ID=4bytes
		0x0000		//WCAL register,
};

const u16 A7139Config_PageB[]=   
{
		0x0337,		//TX2 register, 	
		0x8400,		//IF1 register, 	Enable Auto-IF, IF=200KHz
		0x0000,		//IF2 register,		频率偏移为0
		0x0000,		//ACK register,
		0x0000		//ART register,
};


//GPIO1功能设置
#define A7139_SetGIO_WTR()		A7139_WritePageA(A7139_REG8_GPIO, 0x0041)	//WTR模式,单包收发提示
#define A7139_SetGIO_FPF()		A7139_WritePageA(A7139_REG8_GPIO, 0x0035)	//FPF模式,多包收发状态提示
#define A7139_SetGIO_NULL()		A7139_WritePageA(A7139_REG8_GPIO, 0x0000)	//关闭GPIO1指示

//发送数据结构
typedef struct
{
	u8 *pSendData;	//发送数据缓冲区指针
	u16 SendLen;	//需要发送数据长度
	u16 TranLen;	//已经发送数据长度
	bool isSendOK;	//发送完成
	bool isSendError;//发送失败
}A7139_SEND_TYPE;
volatile A7139_SEND_TYPE SendConfig;		//发送数据的信息


//接收数据结构
typedef struct
{
	u8 *pRevData;	//接收数据缓冲区指针
	u16 RevLen;		//需要接收数据长度
	u16 TranLen;	//已经接收数据长度
	u16 RevBuffSize;//接收缓冲区大小
	bool isRevOK;	//接收完成
	bool isRevError;//接收失败
}A7139_REV_TYPE;
volatile A7139_REV_TYPE RevConfig;		//发送数据的信息


//收发模式记录,用于中断处理发送或接收模式
static bool isSendMode = FALSE;	//默认为接收模式
#define A7139_SendMode(x)	(isSendMode=x)

/*命令选择
地址格式
BIT7 		BIT6-BIT4					BIT3-BIT0
R/W			Command						Address
0:写		000 读写控制寄存器
1:读		010	读写ID
			100	读写FIFO
			110	复位FIFO
			111	RF复位

*/

void A7139_SetBaseFreq(float RfFreq);	//基础频率设置
bool A7139_Cali(void);					//频率校准


/*************************************************************************************************************************
* 函数		:	void A7139_SetTrafficRate(u8 Rate)
* 功能		:	A7139设置通信速率,单位Kbps
* 参数		:	Rate:通信速率,单位Kbps
* 返回		:	无
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2016-01-02
* 最后修改	: 	2016-01-02
* 说明		: 	用于设置通信速率
				范围2-100Kbps
				设置系统时钟2分频,设置为12.8MHZ后如果IFBW设置过小会导致初始化时自动校准失败
				如果设置为50会出现校准失败
*************************************************************************************************************************/
void A7139_SetTrafficRate(u8 Rate)
{
	u16 SDR;
	
	if(Rate < 2) Rate = 2;
	if(Rate > 100) Rate = 100;
	//IFBW设置 DMOS=1 64分频  ETH=1	 CSC=0 FCSCK=12.8MHZ
	if(Rate <= 50)	//IFBW=100KHZ 
	{
		A7139_WriteReg(A7139_RX1, 0x18D0 | (1<<2));
	}
	else 	//IFBW=100KHZ
	{
		A7139_WriteReg(A7139_RX1, 0x18D0 | (1<<2));
	}
	SDR = 100/Rate;
	SDR -= 1;			//计算波特率分频值

	A7139_WriteReg(A7139_SCLOCK,0x0021|(SDR<<9)); //CSC=1 GRC=1	SDR
}



/*************************************************************************************************************************
* 函数		:	void A7139_SetChannel(u8 Channel)
* 功能		:	A7139设置通信信道
* 参数		:	Channel:通信信道0-255
* 返回		:	无
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2016-01-02
* 最后修改	: 	2016-01-02
* 说明		: 	用于设置通信频道
				Channel*0.125/0.0125,最小频率偏差为12.5KHZ,设置通道间隔为125KHZ(最少为100KHZ)
*************************************************************************************************************************/
void A7139_SetChannel(u8 Channel)
{
	A7139_WritePageB(A7139_REG9_IF2,Channel*10);
}



/*************************************************************************************************************************
* 函数		:	void A7139_SetTxPowerSupply(u8 PowerSupply)
* 功能		:	设置A7139发射功率
* 参数		:	PowerSupply:功率等级0-7
* 返回		:	无
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2016-01-02
* 最后修改	: 	2016-01-02
* 说明		: 	用于设置发射功率
				由于不同频率下TX驱动电流与PA驱动电流并不相同,因此按照文档设置
				目前只支持433频段设置,其它频段请按照文档进行设置。
*************************************************************************************************************************/
void A7139_SetTxPowerSupply(u8 PowerSupply)
{	
	if(PowerSupply>6)PowerSupply=6;	//最大功率为6
	if(PowerSupply == 0)
	{
		A7139_WritePageB(A7139_REG9_TX2, 0x0300);	//功率最小-34dBm,PAC=0,TDC=0,TBG=增益
	}
	else
	{
		A7139_WritePageB(A7139_REG9_TX2, 0x0300|(1<<5)|(1<<3)|PowerSupply);	//PAC=1,TDC=1,TBG=增益
	}
}



/*************************************************************************************************************************
* 函数		:	bool A7139_Init(u8 Channel, u16 RfID, u8 PowerSupply, u8 Rate)
* 功能		:	A7139初始化
* 参数		:	Channel:通信信道0-80,RfID:RF ID,PowerSupply:发射功率0-7;Rate:通信波特率2-100Kbps
* 返回		:	TRUE:成功;FALSE:失败
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2015-07-19
* 最后修改	: 	2016-01-02
* 说明		: 	RF_ID:用于区分网络
				2-100Kbps频率间隔至少为100KHZ,150~200KHZ频道间隔必须大于200KHZ
*************************************************************************************************************************/
bool A7139_Init(u8 Channel, u16 RfID, u8 PowerSupply, u8 Rate)
{
	u32 ID;
	u32 temp;
	
	if(Rate < 2) Rate = 2;
	if(Rate > 100) Rate = 100;
	
	A7139_DisableInt();		//关闭中断
	A7139_DisableNVIC();	//关闭总中断
	A7139_IO_INIT();		//初始化IO
	A7139_CS_H();
	A7139_CLK_L();
	A7139_DIO_H();
	
	ID = RfID;
	ID <<= 16;
	ID |= RfID;
	A7193_debug("[RF]频率:%dKHz, 通信速率:%dKbps, RFID:%X!\r\n",(u32)(A7139_BASE_FRE*1000+Channel*0.125*1000),Rate, ID);
	
	A7139_CRYSTAL_REG = 0x0001;
	A7139_SoftReset();	//软复位
	if(A7139_ReadID() != 0)
	{
		A7139_SoftReset();	//软复位
	}
	A7139_DelayMS(1);

	A7139_Config();							//初始化寄存器
	A7139_SetBaseFreq(A7139_BASE_FRE);		//设置基础频率
	A7139_SetChannel(Channel);				//设置信道
	A7139_SetTrafficRate(Rate);				//设置通信速率
	
	A7139_WriteID(ID);	//写入ID
	temp = A7139_ReadID();	//读取用户ID
	if(temp != ID)
	{
		A7193_debug("A7139 初始化失败,芯片检测错误!\r\n");
		return FALSE;
	}
	A7193_debug("A7139 用户ID:%X\t硬件ID:%X\r\n",ID, A7139_ReadDeverID());
	

	A7139_DelayMS(5);
	if(A7139_Cali()==FALSE)		//校准
	{
		A7193_debug("A7139 初始化失败,校准失败!\r\n");
		return FALSE;
	}
	A7193_debug("A7139 初始化成功!\r\n");

	
	A7139_SetTxPowerSupply(PowerSupply);		//设置发射功率
	A7139_EnableInt();							//开启上升沿触发中断

	return TRUE;
}


/*************************************************************************************************************************
* 函数		:	void A7139_WriteByte(u8 data)
* 功能		:	A7139写一字节
* 参数		:	data:需要写入的数据
* 返回		:	无
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2015-07-19
* 最后修改	: 	2015-07-19
* 说明		: 	不带片选,最底层写入1B
*************************************************************************************************************************/
void A7139_WriteByte(u8 data)
{
	u8 i;
	
	for(i = 0;i < 8;i ++)
	{
		if(data & 0x80)
		{
			A7139_DIO_H();
		}
		else
		{
			A7139_DIO_L();	
		}
		nop;nop;
		A7139_CLK_H();
		data <<= 1;
		nop;nop;
		A7139_CLK_L();
	}
}



/*************************************************************************************************************************
* 函数		:	u8 A7139_ReadByte(void)
* 功能		:	A7139读取一字节
* 参数		:	无
* 返回		:	读取的数据
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2015-07-19
* 最后修改	: 	2015-07-19
* 说明		: 	不带片选,最底层读取1B
*************************************************************************************************************************/
u8 A7139_ReadByte(void)
{
	u8 i;
	u8 data = 0;
	
	for(i = 0;i < 8;i ++)
	{
		A7139_CLK_H();
		data <<= 1;
		if(A7139_DIO_IN())
		{
			data |= 1;
		}
		nop;
		A7139_CLK_L();
		nop;nop;nop;
	}
	
	return data;
}



/*************************************************************************************************************************
* 函数		:	u16 A7139_ReadReg(A7139_CREG RegAddr)
* 功能		:	读取控制寄存器
* 参数		:	RegAddr:寄存器地址
* 返回		:	寄存器值
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2015-07-19
* 最后修改	: 	2015-07-19
* 说明		: 	
*************************************************************************************************************************/
u16 A7139_ReadReg(A7139_CREG RegAddr)
{
	u16 data;
	
	RegAddr &= 0x0f;						//地址限制为BIT0-BIT3
	RegAddr |= A7139_RCR_CMD;				//读命令
	A7139_CS_L();
	A7139_OutMode();
	A7139_WriteByte(RegAddr);
	A7139_InMode();	//输入
	data = A7139_ReadByte();
	data <<= 8;
	data |= A7139_ReadByte();
	A7139_CS_H();
	
	return data;
}



/*************************************************************************************************************************
* 函数		:	void A7139_WriteReg(u8 RegAddr, u16 data)
* 功能		:	写入控制寄存器
* 参数		:	RegAddr:寄存器地址,data:要写入的值
* 返回		:	无
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2015-07-19
* 最后修改	: 	2015-07-19
* 说明		: 	
*************************************************************************************************************************/
void A7139_WriteReg(A7139_CREG RegAddr, u16 data)
{
	RegAddr &= 0x0f;						//地址限制为BIT0-BIT3
	RegAddr |= A7139_WCR_CMD;				//写命令
	A7139_CS_L();
	A7139_OutMode();
	A7139_WriteByte(RegAddr);
	A7139_WriteByte(data>>8);
	A7139_WriteByte(data);
	A7139_CS_H();
}



/*************************************************************************************************************************
* 函数		:	u16 A7139_ReadPageA(A7139_PAGE_A RegAddr)
* 功能		:	读取控制寄存器组寄存器A
* 参数		:	RegAddr:寄存器组地址
* 返回		:	寄存器值
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2015-07-19
* 最后修改	: 	2015-07-19
* 说明		: 	寄存器组8
*************************************************************************************************************************/
u16 A7139_ReadPageA(A7139_PAGE_A RegAddr)
{
	u16 data;

	//先选择组
	A7139_CRYSTAL_REG &= ~(0xf << 12);		//清除寄存器组8地址
	A7139_CRYSTAL_REG |= (RegAddr << 12);	//存储寄存器组8地址
	A7139_WriteReg(A7139_CRYSTAL, A7139_CRYSTAL_REG);	//重新设置此存器组8地址
	data = A7139_ReadReg(A7139_PREG8S);		//读取寄存器组数据
	
	return data;
}



/*************************************************************************************************************************
* 函数		:	void A7139_WritePageA(A7139_PAGE_A RegAddr, u16 data)
* 功能		:	写入控制寄存器组寄存器
* 参数		:	RegAddr:寄存器组地址,data:寄存器值
* 返回		:	寄存器值
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2015-07-19
* 最后修改	: 	2015-07-19
* 说明		: 	寄存器组8
*************************************************************************************************************************/
void A7139_WritePageA(A7139_PAGE_A RegAddr, u16 data)
{
	//先选择组
	A7139_CRYSTAL_REG &= ~(0xf << 12);		//清除寄存器组8地址
	A7139_CRYSTAL_REG |= (RegAddr << 12);	//存储寄存器组8地址
	A7139_WriteReg(A7139_CRYSTAL, A7139_CRYSTAL_REG);	//重新设置此存器组8地址
	A7139_WriteReg(A7139_PREG8S, data);	//设置寄存器组数据
}



/*************************************************************************************************************************
* 函数		:	u16 A7139_ReadPageB(A7139_PAGE_B RegAddr)
* 功能		:	读取控制寄存器组寄存器
* 参数		:	RegAddr:寄存器组地址
* 返回		:	寄存器值
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2015-07-19
* 最后修改	: 	2015-07-19
* 说明		: 	寄存器组9
*************************************************************************************************************************/
u16 A7139_ReadPageB(A7139_PAGE_B RegAddr)
{
	u16 data;
	
	A7139_CRYSTAL_REG &= ~(0x7 << 7);					//清除寄存器组9地址
	A7139_CRYSTAL_REG |= ((RegAddr&0x7) << 7);			//存储寄存器组9地址
	A7139_WriteReg(A7139_CRYSTAL, A7139_CRYSTAL_REG);	//重新设置此存器组9地址
	data = A7139_ReadReg(A7139_PREG9S);					//读取寄存器组数据
	
	return data;
}



/*************************************************************************************************************************
* 函数		:	void A7139_WritePageB(A7139_PAGE_B RegAddr, u16 data)
* 功能		:	写入控制寄存器组寄存器
* 参数		:	RegAddr:寄存器组地址,data:寄存器值
* 返回		:	寄存器值
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2015-07-19
* 最后修改	: 	2015-07-19
* 说明		: 	寄存器组9
*************************************************************************************************************************/
void A7139_WritePageB(A7139_PAGE_B RegAddr, u16 data)
{
	//先选择组
	A7139_CRYSTAL_REG &= ~(0x7 << 7);					//清除寄存器组9地址
	A7139_CRYSTAL_REG |= ((RegAddr&0x7) << 7);			//存储寄存器组9地址
	A7139_WriteReg(A7139_CRYSTAL, A7139_CRYSTAL_REG);	//重新设置此存器组9地址
	A7139_WriteReg(A7139_PREG9S, data);					//设置寄存器组数据
}

/*************************************************************************************************************************
* 函数		:	u32 A7139_ReadID(void)
* 功能		:	读取A7139 ID
* 参数		:	无
* 返回		:	ID值
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2015-07-19
* 最后修改	: 	2015-07-19
* 说明		: 	读取ID
*************************************************************************************************************************/
u32 A7139_ReadID(void)
{
	u32 data;
	u8 i;
	
	A7139_CS_L();
	A7139_OutMode();
	A7139_WriteByte(A7139_RID_CMD);			//读ID命令
	A7139_InMode();	//输入
	data = 0;
	for(i = 0;i < 4;i ++)
	{
		data <<= 8;
		data |= A7139_ReadByte();
	}
	A7139_CS_H();
	
	return data;
}


/*************************************************************************************************************************
* 函数		:	void A7139_WriteID(u32 ID)
* 功能		:	设置A7139 ID
* 参数		:	无ID值
* 返回		:	无
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2015-07-19
* 最后修改	: 	2015-07-19
* 说明		: 	设置ID
*************************************************************************************************************************/
void A7139_WriteID(u32 ID)
{
	A7139_CS_L();
	A7139_OutMode();
	A7139_WriteByte(A7139_WID_CMD);			//写ID命令
	A7139_WriteByte(ID >> 24);
	A7139_WriteByte(ID >> 16);
	A7139_WriteByte(ID >> 8);
	A7139_WriteByte(ID >> 0);
	A7139_CS_H();
}



/*************************************************************************************************************************
* 函数		:	void A7139_StrobeCmd(A7139_STROBE_CMD StrobeCmd)
* 功能		:	A7139发送Strobe命令
* 参数		:	无
* 返回		:	无
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2015-07-19
* 最后修改	: 	2015-07-19
* 说明		: 	
*************************************************************************************************************************/
void A7139_StrobeCmd(A7139_STROBE_CMD StrobeCmd)
{
	A7139_CS_L();
	A7139_OutMode();
	A7139_WriteByte(StrobeCmd);
	A7139_CS_H();
}



/*************************************************************************************************************************
* 函数		:	void A7139_ReadFIFO(u8 *pData, u8 DataLen)
* 功能		:	A7139读取FIFO
* 参数		:	无
* 返回		:	无
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2015-07-19
* 最后修改	: 	2015-07-19
* 说明		: 	
*************************************************************************************************************************/
void A7139_ReadFIFO(u8 *pData, u8 DataLen)
{
	u8 i;
	
	A7139_CS_L();
	A7139_OutMode();
	A7139_WriteByte(A7139_RFIFO_CMD);
	A7139_InMode();
	//循环读取FIFO
	for(i = 0;i < DataLen;i ++)
	{
		pData[i] = A7139_ReadByte();
	}
	A7139_CS_H();
}


/*************************************************************************************************************************
* 函数		:	void A7139_WriteFIFO(u8 *pData, u8 DataLen)
* 功能		:	A7139写FIFO
* 参数		:	无
* 返回		:	无
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2015-07-19
* 最后修改	: 	2015-07-19
* 说明		: 	
*************************************************************************************************************************/
void A7139_WriteFIFO(u8 *pData, u8 DataLen)
{
	u8 i;
	
	A7139_CS_L();
	A7139_OutMode();
	A7139_WriteByte(A7139_WFIFO_CMD);
	//循环写入FIFO
	for(i = 0;i < DataLen;i ++)
	{
		A7139_WriteByte(pData[i]);
	}
	A7139_CS_H();
}





/*************************************************************************************************************************
* 函数		:	void A7139_Config(void)
* 功能		:	A7139 配置
* 参数		:	无
* 返回		:	无
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2015-07-19
* 最后修改	: 	2015-07-19
* 说明		: 	初始化配置
*************************************************************************************************************************/
void A7139_Config(void)
{
	u8 i;
	
	for(i=0; i<8; i++)
        A7139_WriteReg((A7139_CREG)i, A7139Config[i]);
	for(i=10; i<16; i++)
        A7139_WriteReg((A7139_CREG)i, A7139Config[i]);
     for(i=0; i<16; i++)
        A7139_WritePageA((A7139_PAGE_A)i, A7139Config_PageA[i]);
	for(i=0; i<5; i++)
        A7139_WritePageB((A7139_PAGE_B)i, A7139Config_PageB[i]);
}


/*************************************************************************************************************************
* 函数		:	void A7139_SetSendDataLen(u16 DataLen)
* 功能		:	A7139 设置发送数据长度(只针对FIFO外延模式有效)
* 参数		:	DataLen:数据长度,最大16KB
* 返回		:	无
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2015-12-29
* 最后修改	: 	2015-12-29
* 说明		: 	用于FIFO外延模式下设置发送数据长度
*************************************************************************************************************************/
void A7139_SetSendDataLen(u16 DataLen)
{
	if(DataLen > 16*1024) DataLen = 16*1024;						//限制最大长度为16KB
	
	//将要发送的数据长度写入到FEP[13:0]寄存器中
	A7139_WritePageA(A7139_REG8_VCO, (DataLen&0x3F00) | 0x04);		//FEP【13:8】
	A7139_WritePageA(A7139_REG8_FIFO, (3<<14) | (DataLen&0xFF));	//FPM=3;PSA=0,FEP【7:0】
}



/*************************************************************************************************************************
* 函数		:	u8 A7139_WriteFistPackToFIFO(u8 *pData, u16 SnedDataLen)
* 功能		:	FIFO外延模式发送首包数据
* 参数		:	pData:数据缓冲区;SnedDataLen:需要发送的数据总长度(不是当前包长度)
* 返回		:	发送的数据长度
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2015-12-30
* 最后修改	: 	2015-12-30
* 说明		: 	用于FIFO外延模式发送第一包,前面2个字节为总包长度,后面62B为数据包有效大小
				如果数据包小于62B后面补充无效数据0x00
				FIFO外延模式,64B...48B...48B...
*************************************************************************************************************************/
u8 A7139_WriteFistPackToFIFO(u8 *pData, u16 SnedDataLen)
{
	u16 i;
	u8 temp;
	
	A7139_CS_L();
	A7139_OutMode();
	A7139_WriteByte(A7139_WFIFO_CMD);
	//循环写入FIFO
	A7139_WriteByte(0xA5);					//数据包起始字节1
	A7139_WriteByte(0xB6);					//数据包起始字节2
	A7139_WriteByte(SnedDataLen>>8);		//数据包总长度,高位
	A7139_WriteByte(SnedDataLen);			//数据包总长度,低位
	if(SnedDataLen < 60)					//不足一包,需要填充
	{
		for(i = 0;i < SnedDataLen;i ++)			//发送数据包
		{
			A7139_WriteByte(pData[i]);
		}
		for(i = 0;i < (60-SnedDataLen);i ++)	//填充不足的字节数
		{
			A7139_WriteByte(0x00);		//填充
		}
	}
	else	//超出一包数据
	{
		for(i = 0;i < 60;i ++)			//发送数据包
		{
			A7139_WriteByte(pData[i]);
		}
		SnedDataLen = 60;				//返回发送的数据长度
	}
	
	A7139_CS_H();
	return SnedDataLen;				//返回发送的数据长度
}



/*************************************************************************************************************************
* 函数		:	u8 A7139_WritePackToFIFO(u8 *pData, u16 ResidueDataLen)
* 功能		:	FIFO外延模式发送后续数据包(不能是第一包)
* 参数		:	pData:数据缓冲区;ResidueDataLen:剩余需要发送的数长度(不是当前包长度)
* 返回		:	发送的数据长度
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2015-12-30
* 最后修改	: 	2015-12-30
* 说明		: 	如果剩余数据小于48B后面补充无效数据0x00
				FIFO外延模式,64B...48B...48B...
				BUG:如果外延模式下,写数据中断触发后立即写数据则会再次产生一次写数据中断
*************************************************************************************************************************/
u8 A7139_WritePackToFIFO(u8 *pData, u16 ResidueDataLen)
{
	u8 i;
	
	if(ResidueDataLen == 0) return 0;
	

	A7139_CS_L();
	A7139_OutMode();
	A7139_WriteByte(A7139_WFIFO_CMD);

	//循环写入FIFO
	if(ResidueDataLen < 48)							//不足一包,需要填充
	{
		for(i = 0;i < ResidueDataLen;i ++)			//发送数据包
		{
			A7139_WriteByte(pData[i]);
		}
		for(i = 0;i < (48-ResidueDataLen);i ++)		//填充不足的字节数
		{
			A7139_WriteByte(0x00);					//填充
		}
	}
	else	//超出一包数据
	{
		for(i = 0;i < 48;i ++)						//发送数据包
		{
			A7139_WriteByte(pData[i]);
		}
		ResidueDataLen = 48;									//返回发送的数据长度
	}
	
	A7139_CS_H();
	return ResidueDataLen;						//返回发送的数据长度
}



/*************************************************************************************************************************
* 函数		:	u8 A7139_ReadFistPackToFIFO(u8 *pDataBuff, u16 *pRevDataLen, u16 ResidueBuffSize)
* 功能		:	FIFO外延模式读取首包数据
* 参数		:	pDataBuff:接收数据缓冲区;pRevDataLen:需要接收的数据总长度(不是当前包长度);ResidueBuffSize:剩余接收数据缓冲区大小
* 返回		:	接收到的数据长度(当前接收的)
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2015-12-30
* 最后修改	: 	2015-12-30
* 说明		: 	用于FIFO外延模式接收第一包,前面2个字节为总包长度,后面48-2B为数据包有效大小
				如果数据包小于48-2B后面数据将丢弃
				FIFO外延模式,48B...48B...48B...
*************************************************************************************************************************/
vu8 A7139_ReadFistPackToFIFO(vu8 *pDataBuff, vu16 *pRevDataLen, vu16 ResidueBuffSize)
{
	u8 i;
	u16 len;
	
	A7139_CS_L();
	A7139_OutMode();
	A7139_WriteByte(A7139_RFIFO_CMD);
	A7139_InMode();
	//循环读取FIFO
	if((A7139_ReadByte()!=0xA5) || ((A7139_ReadByte()!=0xB6)))
	{
		uart_printf("帧头错误\r\n");
		*pRevDataLen = 0;			//获取需要接收的总长度
		return 0;
	}
	len = A7139_ReadByte();		//高位
	len <<= 8;
	len |= A7139_ReadByte();	//低位
	*pRevDataLen = len;			//获取需要接收的总长度
	if(len == 0) 
	{
		uart_printf("长度错误\r\n");
		return 0;		//长度错误
	}
	if(len < ResidueBuffSize)	//数据缓冲区足够大
	{
		if(len < 44)	//不足一包
		{
			for(i = 0;i < len;i ++)	
			{
				pDataBuff[i] = A7139_ReadByte();	//读取有效数据
			}
			for(i = 0;i < (44-len);i ++)			//丢弃
			{
				A7139_ReadByte();	
			}
		}
		else	//超过一包
		{
			for(i = 0;i < 44;i ++)	
			{
				pDataBuff[i] = A7139_ReadByte();	//读取有效数据
			}
			len = 44;
		}
	}
	else	//缓冲区不够
	{
		if(ResidueBuffSize < 44)	//不足一包
		{
			for(i = 0;i < ResidueBuffSize;i ++)	
			{
				pDataBuff[i] = A7139_ReadByte();	//读取有效数据
			}
			for(i = 0;i < (44-ResidueBuffSize);i ++)			//丢弃
			{
				A7139_ReadByte();	
			}
			len = ResidueBuffSize;
		}
		else	//超过一包
		{
			for(i = 0;i < 44;i ++)	
			{
				pDataBuff[i] = A7139_ReadByte();	//读取有效数据
			}
			len = 44;
		}
	}
	
	A7139_CS_H();
	return len;				//返回发送的数据长度
}



/*************************************************************************************************************************
* 函数		:	u8 A7139_ReadPackToFIFO(u8 *pDataBuff, u16 ResidueDataLen, u16 ResidueBuffSize)
* 功能		:	FIFO外延模式读取后续数据(非首包)
* 参数		:	pDataBuff:接收数据缓冲区;ResidueDataLen:未接受的数据长度;ResidueBuffSize:剩余接收数据缓冲区大小
* 返回		:	接收到的数据长度(当前接收的)
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2015-12-30
* 最后修改	: 	2015-12-30
* 说明		: 	如果数据包小于48后面数据将丢弃
				FIFO外延模式,48B...48B...48B...
*************************************************************************************************************************/
vu8 A7139_ReadPackToFIFO(vu8 *pDataBuff, vu16 ResidueDataLen, vu16 ResidueBuffSize)
{
	u8 i;
	
	A7139_CS_L();
	A7139_OutMode();
	A7139_WriteByte(A7139_RFIFO_CMD);
	A7139_InMode();
	//循环读取FIFO
	if(ResidueDataLen < ResidueBuffSize)	//数据缓冲区足够大
	{
		if(ResidueDataLen < 48)	//不足一包
		{
			for(i = 0;i < ResidueDataLen;i ++)	
			{
				pDataBuff[i] = A7139_ReadByte();	//读取有效数据
			}
			for(i = 0;i < (48-ResidueDataLen);i ++)			//丢弃
			{
				A7139_ReadByte();	
			}
		}
		else	//超过一包
		{
			for(i = 0;i < 48;i ++)	
			{
				pDataBuff[i] = A7139_ReadByte();	//读取有效数据
			}
			ResidueDataLen = 48;
		}
	}
	else	//缓冲区不够
	{
		if(ResidueBuffSize < 48)	//不足一包
		{
			for(i = 0;i < ResidueBuffSize;i ++)	
			{
				pDataBuff[i] = A7139_ReadByte();	//读取有效数据
			}
			for(i = 0;i < (48-ResidueBuffSize);i ++)			//丢弃
			{
				A7139_ReadByte();	
			}
			ResidueDataLen = ResidueBuffSize;
		}
		else	//超过一包
		{
			for(i = 0;i < 48;i ++)	
			{
				pDataBuff[i] = A7139_ReadByte();	//读取有效数据
			}
			ResidueDataLen = 48;
		}
	}
	
	A7139_CS_H();
	return ResidueDataLen;				//返回发送的数据长度
}


/*************************************************************************************************************************
* 函数		:	bool A7139_SendData(u8 *pData, u16 DataLen)
* 功能		:	A7139 发送数据(FIFO外延模式最大16KB-4)
* 参数		:	pData:发送数据缓冲区,最大16KB-4;DataLen:发送数据长度
* 返回		:	TRUE:发送成功;FALSE:发送失败
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2015-12-29
* 最后修改	: 	2015-12-29
* 说明		: 	用于FIFO外延模式下发送数据
				FIFO外延模式,64B...48B...48B...
				至少需要发送64B以上的数据
*************************************************************************************************************************/
bool A7139_SendData(u8 *pData, u16 DataLen)
{
	u8 retry = 0;
	u16 len = 0;
	
	A7139_DisableNVIC();		//总中断关闭
	if(DataLen > (16*1024-4)) DataLen = (16*1024-4);	//限制最大长度为(16KB-4)
	
	if(DataLen <= 60) 
	{
		A7139_SetSendDataLen(64-1);		//设置发送数据长度
	}
	else
	{
		len = ((DataLen-60)%48)?((DataLen-60)/48*48+48):((DataLen-60)/48*48);
		A7139_SetSendDataLen(64+len-1);		//设置发送数据长度
	}
	A7139_StrobeCmd(A7139_STBY_CMD);
	A7139_DelayMS(1);
	A7139_StrobeCmd(A7139_RESTFIFO_CMD);
	A7139_DelayMS(1);
	A7139_SetGIO_FPF();					//FPF模式
	A7139_SendMode(TRUE);				//发送模式
	SendConfig.isSendError = FALSE;		//清除发送错误状态
	SendConfig.isSendOK = FALSE;		//清除发送成功状态
	SendConfig.pSendData = pData;		//设置发送数据缓冲区
	SendConfig.SendLen = DataLen;		//设置发送数据长度
	SendConfig.TranLen = A7139_WriteFistPackToFIFO(&SendConfig.pSendData[0], SendConfig.SendLen);	//发送首包数据
	A7139_StrobeCmd(A7139_TX_CMD); 		//发送命令牌,使A7139进入“发送”状态,其后A7139会将数据打包后自动发送
//	//定时器主要用来进行调试,可以计算进入中断的时间,进而查出问题所在
//	DeviceClockEnable(DEV_TIM6, ENABLE);	//使能定时器6时钟
//	TIM6->CNT = 0;
//	TIM6->ARR=60000;  						//设定计数器自动重装值
//	TIM6->PSC=SYSTEM_GetClkSpeed()/1000000-1;  //预分频器
//	TIM6->SR = 0;		//清除中断标志位						
//	TIM6->CR1|=0x01;    //使能定时器6
//	IntCnt = 0;
	
	if(SendConfig.TranLen >= SendConfig.SendLen)
	{
		SendConfig.isSendOK = TRUE;		//发送完成
	}
	else
	{
		A7139_ClearRxInt();
		A7139_EnableNVIC();				//总中断开启
		while(SendConfig.isSendOK != TRUE)
		{
			A7139_DelayMS(10);
			retry ++;
			if(retry > 200) 
			{
				A7139_DisableNVIC();//总中断关闭
				return FALSE;
			}
		}
		A7139_DisableNVIC();//总中断关闭
	}
	

	//需要等待最后一包数据发送完毕,一般需要等待至少3ms以上
	A7139_DelayMS(1);

	return TRUE;
}




/*************************************************************************************************************************
* 函数		:	bool A7139_SetRevListen(u8 *pRevBuff, u16 RevBuffSize)
* 功能		:	A7139 进入数据监听状态(FIFO外延模式最大16KB)
* 参数		:	pRevBuff:接收数据缓冲区,最大16KB;RevBuffSize:接收数据缓冲区大小
* 返回		:	无
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2015-12-29
* 最后修改	: 	2015-12-29
* 说明		: 	用于FIFO外延模式下接收数据
				FIFO外延模式,48B...48B...48B...
*************************************************************************************************************************/
bool A7139_SetRevListen(u8 *pRevBuff, u16 RevBuffSize)
{
	A7139_SetGIO_FPF();					//FPF模式,FPF信号空闲为低电平
	A7139_DisableNVIC();				//总中断关闭
	A7139_SetSendDataLen(0x3fff);		//设置发送数据长度
	A7139_StrobeCmd(A7139_IDLE_CMD);
	A7139_DelayMS(1);
	A7139_StrobeCmd(A7139_RESRFIFO_CMD);
	A7139_DelayMS(1);
	A7139_StrobeCmd(A7139_RX_CMD);

	RevConfig.pRevData = pRevBuff;		//接收数据缓冲区指针
	RevConfig.TranLen = 0;				//已经接收数据长度
	RevConfig.RevLen = 0;				//需接收数据长度为0
	RevConfig.RevBuffSize = RevBuffSize;//接收缓冲区大小
	RevConfig.isRevOK = FALSE;			//接收完成无效
	RevConfig.isRevError = FALSE;		//接收失败无效
	A7139_SendMode(FALSE);				//接收模式

	A7139_ClearRxInt();
	A7139_EnableNVIC();					//总中断开启
	
	uart_printf("接收监控模式!\r\n");
	return TRUE;
}






/*************************************************************************************************************************
* 函数		:	int A7139_GetRxLen(void)
* 功能		:	获取接收数据长度
* 参数		:	无
* 返回		:	-1:接收错误,>0接收到的数据长度
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2016-01-02
* 最后修改	: 	2016-01-02
* 说明		: 	A7139 进入接收模式后,使用中断进行接收
*************************************************************************************************************************/
int A7139_GetRxLen(void)
{
	if(RevConfig.isRevError == TRUE) return -1;
	else if(RevConfig.isRevOK == TRUE) return RevConfig.TranLen;
	else return 0;
	
}




/*************************************************************************************************************************
* 函数		:	void A7139_SetBaseFreq(float RfFreq)
* 功能		:	A7139 配置RF基础频率
* 参数		:	rfFreq:RF频率,单位MHz
* 返回		:	无
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2015-07-19
* 最后修改	: 	2015-07-19
* 说明		: 	初始化配置
*************************************************************************************************************************/
void A7139_SetBaseFreq(float RfFreq)
{
	 float  divFreq = RfFreq / 12.800f;  
	 u8  intFreq = (u8)(divFreq); //integer part
	 float  fltFreq = divFreq - intFreq * 1.000f; //fraction part
	 u16 fpFreg	= (u16)(fltFreq * 65536);  //FP register val
	 u16 orgVal;
	
	 A7139_StrobeCmd(A7139_STBY_CMD); //enter stand-by mode
			 //AFC[15:15] = 0
	 orgVal = A7139Config[A7139_PLL3] & 0x7FFF;
	 A7139_WriteReg(A7139_PLL3,orgVal);
	 		//RFC[15:12] = 0000
	 orgVal = A7139Config[A7139_PLL6] & 0x0FFF;
	 A7139_WriteReg(A7139_PLL6,orgVal);
	 	//MD1[12:12]=0,1
	 if(RfFreq < 860)	//433-510
		orgVal = A7139Config[A7139_PLL4] & 0xEFFF;
	 else	 //868-915
		orgVal = A7139Config[A7139_PLL4] | 0x1000;
	 A7139_WriteReg(A7139_PLL4,orgVal);
	 		//IP[8:0] = intg
	 orgVal = A7139Config[A7139_PLL1] & 0xFF00;
	 A7139_WriteReg(A7139_PLL1,orgVal|intFreq);
	 		//FP[15:0] =  fpFreg
	 A7139_WriteReg(A7139_PLL2,fpFreg); 
	//FPA[15:0] = 0x0000,
	 A7139_WritePageB(A7139_REG9_IF2,0x0000);	//偏移为0
}



/*************************************************************************************************************************
* 函数		:	bool A7139_Cali(void)
* 功能		:	A7139 校准
* 参数		:	无
* 返回		:	TRUE:校准成功;FALSE:校准失败
* 依赖		:	底层宏定义
* 作者		:	[email protected]
* 时间		:	2015-07-19
* 最后修改	: 	2015-01-02
* 说明		: 	A7139 频率校准
*************************************************************************************************************************/
bool A7139_Cali(void)
{
	u16  fbcf;	//IF Filter
	u16  vbcf;	//VCO Current
	u16  vccf;	//VCO Band
	u16 tmp;
	
    //IF calibration procedure @STB state
	A7139_WriteReg(A7139_MODE, A7139Config[A7139_MODE] | 0x0802);			//IF Filter & VCO Current Calibration
     do{
		tmp = A7139_ReadReg(A7139_MODE);
     }while(tmp & 0x0802);
    //for check(IF Filter)
     tmp = A7139_ReadReg(A7139_CALIB);
     //fb = tmp & 0x0F;
     //fcd = (tmp>>11) & 0x1F;
     fbcf = (tmp>>4) & 0x01;
     if(fbcf)
     {
		 //FBCF:IF 滤波器自动校准标志(只读)
		return FALSE;
     }
	//for check(VCO Current)
     tmp = A7139_ReadPageA(A7139_REG8_VCO);
	//vcb = tmp & 0x0F;
	vccf = (tmp>>4) & 0x01;
	if(vccf)
	{
        return FALSE;
     }
    //RSSI Calibration procedure @STB state
	A7139_WriteReg(A7139_ADC, 0x4C00);									//set ADC average=64
     A7139_WritePageA(A7139_REG8_WOR2, 0xF800);								//set RSSC_D=40us and RS_DLY=80us
	A7139_WritePageA(A7139_REG8_TX1, A7139Config_PageA[A7139_REG8_TX1] | 0xE000);	//set RC_DLY=1.5ms
     A7139_WriteReg(A7139_MODE, A7139Config[A7139_MODE] | 0x1000);			//RSSI Calibration
     do{
		tmp = A7139_ReadReg(A7139_MODE);
     }while(tmp & 0x1000);
	A7139_WriteReg(A7139_ADC, A7139Config[A7139_ADC]);
     A7139_WritePageA(A7139_REG8_WOR2, A7139Config_PageA[A7139_REG8_WOR2]);
	A7139_WritePageA(A7139_REG8_TX1, A7139Config_PageA[A7139_REG8_TX1]);
    //VCO calibration procedure @STB state
	A7139_WriteReg(A7139_MODE, A7139Config[A7139_MODE] | 0x0004);		//VCO Band Calibration
	do{
		tmp = A7139_ReadReg(A7139_MODE);
	}while(tmp & 0x0004);
		//for check(VCO Band)
	tmp = A7139_ReadReg(A7139_CALIB);
	//vb = (tmp >>5) & 0x07;
	vbcf = (tmp >>8) & 0x01;
	if(vbcf)
	{
		return FALSE;
	}
	
	return TRUE;
}





//PB1接收中断程序
//警告:如果缓冲区大小设置错误将产生意想不到的混乱,造成溢出后程序将不受控
//接收完毕后一定要退出接收模式,否则会一直受到FPF信号,原因是在不知道数据包大小的情况下将数据包设置为无限大小
void EXTI1_IRQHandler(void)
{
	A7139_DisableNVIC();	//关闭总中断
	A7139_ClearRxInt();		//清除中断
	LED1_ON();
	
	//uart_printf("%d时间:%duS\r\n",IntCnt,TIM6->CNT);
	
	if(isSendMode == TRUE)	//发送模式
	{
		if(SendConfig.TranLen < SendConfig.SendLen)	//没发送完才发送
		{
			SendConfig.TranLen += A7139_WritePackToFIFO(&SendConfig.pSendData[SendConfig.TranLen], SendConfig.SendLen-SendConfig.TranLen);		//发送剩下数据包
			if(SendConfig.TranLen >= SendConfig.SendLen)
			{
				LED1_OFF();
				SendConfig.isSendOK = TRUE;		//发送完成
				A7139_DisableNVIC();			//总中断关闭
				A7139_ClearRxInt();				//清除中断
				return;
			}
		}
		else	//正常情况下不会执行到此
		{
			LED1_OFF();
			//uart_printf("发送有错误\r\n");
			SendConfig.isSendError = TRUE;		//发送完成
			A7139_DisableNVIC();				//总中断关闭
			A7139_ClearRxInt();					//清除中断
			return;
		}
		
	}
	else
	{
		if(RevConfig.RevLen == 0)		//还没获取到需要接收数据长度
		{
			RevConfig.TranLen = A7139_ReadFistPackToFIFO(&RevConfig.pRevData[0], &RevConfig.RevLen, RevConfig.RevBuffSize);
			if(RevConfig.RevLen == 0)	//接收数据长度为0,无效,退出接收
			{
				LED1_OFF();
				A7139_StrobeCmd(A7139_IDLE_CMD);
				RevConfig.isRevError = TRUE;	//接收有误,结束接收
				A7139_DisableNVIC();				//总中断关闭
				A7139_ClearRxInt();					//清除中断
				return;

			}
		}
		else
		{
			RevConfig.TranLen += A7139_ReadPackToFIFO(&RevConfig.pRevData[RevConfig.TranLen], RevConfig.RevLen-RevConfig.TranLen, RevConfig.RevBuffSize-RevConfig.TranLen);
		}
		
		if(RevConfig.TranLen >= RevConfig.RevBuffSize)	//缓冲区满了
		{
			LED1_OFF();
			A7139_StrobeCmd(A7139_IDLE_CMD);
			RevConfig.isRevOK = TRUE;		//接收完成了,结束接收
			A7139_DisableNVIC();			//总中断关闭
			A7139_ClearRxInt();				//清除中断
			return;
		}
		else if((RevConfig.TranLen >= RevConfig.RevLen)&&(RevConfig.RevLen!=0))	//接收完成了
		{
			LED1_OFF();
			A7139_StrobeCmd(A7139_IDLE_CMD);
			RevConfig.isRevOK = TRUE;		//接收完成了,结束接收
			A7139_DisableNVIC();				//总中断关闭
			A7139_ClearRxInt();					//清除中断
			return;
		}
		
	}

	LED1_OFF();
	A7139_ClearRxInt();		//清除中断
	A7139_EnableNVIC();		//总中断开启
}

头文件

/*************************************************************************************************************
 * 文件名:		A7139.h
 * 功能:		STM32 A7139驱动
 * 作者:		[email protected]
 * 创建时间:	2015-07-19
 * 最后修改时间:2015-07-19
 * 详细:		A7139驱动
*************************************************************************************************************/		
#ifndef __A7139_H__
#define __A7139_H__
#include "system.h"


#if(BOARD_SUPPORT)	//需要板级支持

#include "board.h" 

#else				//默认支持

//三线spi
#define A7139_DIO_OUT		PBout(10)
#define A7139_DIO_IN()		PBin(10)
#define A7139_CS			PBout(0)
#define A7139_CLK			PBout(11)
#define A7139_OutMode()		GPIOx_OneInit(GPIOB,10,OUT_PP,SPEED_50M)
#define A7139_InMode()		GPIOx_OneInit(GPIOB,10,IN_IPU,IN_IN)
#define A7139_GIO1			PBin(1)	


#define A7139_IO_INIT()	\
	DeviceClockEnable(DEV_GPIOB,ENABLE);/*使能GPIOA时钟*/\
	GPIOx_Init(GPIOB,BIT0|BIT10|BIT11, OUT_PP, SPEED_50M);\
	GPIOx_Init(GPIOB,BIT1, IN_IPT, IN_IN);\
	
#define A7139_IO_POWER_DOWN()	\
	DeviceClockEnable(DEV_GPIOB,ENABLE);/*使能GPIOA时钟*/\
	GPIOx_Init(GPIOB,BIT0|BIT10|BIT11,  IN_IPT, IN_IN);\

	


//接口
//DIO
#define A7139_DIO_H() 			(A7139_DIO_OUT=1)	//输出1
#define A7139_DIO_L() 			(A7139_DIO_OUT=0)	//输出0
#define A7139_CS_H()			(A7139_CS=1)
#define A7139_CS_L()			(A7139_CS=0)
#define A7139_CLK_H()			(A7139_CLK=1)
#define A7139_CLK_L()			(A7139_CLK=0)
#define A7139_GIO1_IN()			(A7139_GIO1)
//中断
#define A7139_EnableNVIC()		NVIC_IntEnable(IRQ_EXTI1,ENABLE)			//总中断开启
#define A7139_DisableNVIC()		NVIC_IntEnable(IRQ_EXTI1,DISABLE)			//总中断关闭
#define A7139_EnableInt()		EXTI_IntConfig(GPIO_B,1,PosEdge)			//上升沿触发中断
#define A7139_DisableInt()		EXTI_IntConfig(GPIO_B,1,OFF_INT)			//关闭接收中断

//清除接收中断
#define A7139_ClearRxInt()		EXTI_ClearInt(1)						//清除中断

#endif

//控制寄存器
typedef enum 
{
	A7139_SCLOCK	=	0x00,		//系统时钟寄存器
	A7139_PLL1		=	0x01,		//PLL1
	A7139_PLL2		=	0x02,		//PLL2
	A7139_PLL3		=	0x03,		//PLL3
	A7139_PLL4		=	0x04,		//PLL4
	A7139_PLL5		=	0x05,		//PLL5
	A7139_PLL6		=	0x06,		//PLL6
	A7139_CRYSTAL	=	0x07,		//晶振设置
	A7139_PREG8S	=	0x08,		//寄存器组,由CRYSTAL控制切换
	A7139_PREG9S	=	0x09,		//寄存器组,由CRYSTAL控制切换
	A7139_RX1		=	0x0A,		//接收设置1
	A7139_RX2		=	0x0B,		//接收设置2
	A7139_ADC		=	0x0C,		//ADC
	A7139_PIN		=	0x0D,		//PIN
	A7139_CALIB		=	0x0E,		//Calibration
	A7139_MODE		=	0x0F,		//模式控制
}A7139_CREG;

//控制寄存器组A
typedef enum
{
	//寄存器8
	A7139_REG8_TX1		=	0,			//addr8 page0, 
	A7139_REG8_WOR1		=	1,			//addr8 page1, 
	A7139_REG8_WOR2		=	2,			//addr8 page2, 
	A7139_REG8_RF		=	3,			//addr8 page3, 
	A7139_REG8_POWER	=	4,			//addr8 page4, 
	A7139_REG8_AGCRC	=	5,			//addr8 page5, 
	A7139_REG8_AGCCON1	=	6,			//addr8 page6, 
	A7139_REG8_AGCCON2	=	7,			//addr8 page7, 
	A7139_REG8_GPIO		=	8,			//addr8 page8, 
	A7139_REG8_CKO		=	9,			//addr8 page9, 
	A7139_REG8_VCO		=	10,			//addr8 page10,
	A7139_REG8_CHG1		=	11,			//addr8 page11,
	A7139_REG8_CHG2		=	12,			//addr8 page12,
	A7139_REG8_FIFO		=	13,			//addr8 page13,
	A7139_REG8_CODE		=	14,			//addr8 page14,
	A7139_REG8_WCAL		=	15,			//addr8 page15,
}A7139_PAGE_A;


//控制寄存器组B
typedef enum
{
	//寄存器9
	A7139_REG9_TX2		=	0,		//addr9 page0, 
	A7139_REG9_IF1		=	1,		//addr9 page1,
	A7139_REG9_IF2		=	2,		//addr9 page2,
	A7139_REG9_ACK		=	3,		//addr9 page3,
	A7139_REG9_ART		=	4,		//addr9 page4,
}A7139_PAGE_B;


//Strobe命令
typedef enum
{
	A7139_WCR_CMD		=	0x00,	//写控制寄存器
	A7139_RCR_CMD		=	0x80,	//读控制寄存器
	A7139_WID_CMD		=	0x20,	//写ID
	A7139_RID_CMD		=	0xA0,	//读ID
	A7139_WFIFO_CMD		=	0x40,	//写FIFO
	A7139_RFIFO_CMD		=	0xC0,	//读FIFO	
	A7139_RESRF_CMD		=	0x70,	//复位RF
	A7139_RESTFIFO_CMD	=	0x60,	//复位发送FIFO
	A7139_RESRFIFO_CMD	=	0xE0,	//复位接收FIFO
	A7139_SLEEP_CMD		=	0x10,	//SLEEP模式
	A7139_IDLE_CMD		=	0x12,	//IDLE模式
	A7139_STBY_CMD		=	0x14,	//Standby模式
	A7139_PLL_CMD		=	0x16,	//PLL模式
	A7139_RX_CMD		=	0x18,	//RX模式
	A7139_TX_CMD		=	0x1A,	//TX模式
	A7139_TSLEEP_CMD	=	0x1C,	//Deep sleep 模式 三态
	A7139_PSLEEP_CMD	=	0x1F,	//Deep sleep 模式 上拉
}A7139_STROBE_CMD;




//宏定义接口
#ifdef _UCOS_II_
#include "ucos_ii.h"
#define A7139_DelayMS(x)		OSTimeDlyHMSM(0,0,0,x)	//ms延时,最大999ms
#else
#include "delay.h"
#define A7139_DelayMS(x)		Delay_MS(x)
#endif


//相关函数
void A7139_SoftReset(void);								//A7139软复位
bool A7139_Init(u8 Channel, u16 RfID, u8 PowerSupply, u8 Rate);					//A7139 初始化
void A7139_WriteReg(A7139_CREG RegAddr, u16 data);	//写入控制寄存器
u16 A7139_ReadReg(A7139_CREG RegAddr);	//读取控制寄存器
u32 A7139_ReadID(void);					//读取A7139 ID
void A7139_WriteID(u32 ID);				//设置A7139 ID
u16 A7139_ReadPageA(A7139_PAGE_A RegAddr);	//读取控制寄存器组寄存器A
void A7139_WritePageA(A7139_PAGE_A RegAddr, u16 data);//写入控制寄存器组寄存器A
u16 A7139_ReadPageB(A7139_PAGE_B RegAddr);	//读取控制寄存器组寄存器B
void A7139_WritePageB(A7139_PAGE_B RegAddr, u16 data);//写入控制寄存器组寄存器B
void A7139_RestRxFIFO(void);		//A7139复位接收FIFO指针
void A7139_RestTxFIFO(void);		//A7139复位发送FIFO指针
void A7139_ReadFIFO(u8 *pData, u8 DataLen);		//A7139读取FIFO
void A7139_WriteFIFO(u8 *pData, u8 DataLen);	//A7139写FIFO
void A7139_StrobeCmd(A7139_STROBE_CMD StrobeCmd);	//A7139发送Strobe命令
void A7139_Config(void);		//配置A7139
void A7139_SetFreq(float RfFreq);	//A7139 配置RF频率
bool A7139_WaitRxData(u8 pData[64], u16 TimeOut);	//等待接收数据
int A7139_GetRxLen(void);
bool A7139_SetRev(u8 *pRevBuff, u16 RevBuffSize);
bool A7139_SendData(u8 *pData, u16 DataLen);		//A7139发送数据
void A7139_SetTxPowerSupply(u8 PowerSupply);	//发射功率设置


#define A7139_ReadDeverID()		(A7139_ReadPageB(A7139_REG9_TX2))	//读取设备硬件ID,只读
#define A7139_RestRxFIFO()		A7139_StrobeCmd(A7139_RESRFIFO_CMD)	//A7139复位接收FIFO指针
#define A7139_RestTxFIFO()		A7139_StrobeCmd(A7139_RESTFIFO_CMD)	//A7139复位发送FIFO指针
#define A7139_SoftReset()		A7139_StrobeCmd(A7139_RESRF_CMD)	//A7139软复位




#endif //A7139

//发送方测试

/任务1:
//系统任务
u8 TempBuff[2048];
void TaskSystem(void *pdata)
{
	u16 crc16;
	u16 i;
	
	//初始化相关线程
	//uart_printf("新建线程:TaskLED(%d)\r\n",OSTaskCreate(TaskLED, (void *)0,&TASK_LED_STK[LED_STK_SIZE-1], LED_TASK_Prio));//通信
	//uart_printf("新建线程:TaskPAIR(%d)\r\n",OSTaskCreate(TaskPAIR, (void *)0,&TASK_PAIR_STK[PAIR_STK_SIZE-1], PAIR_TASK_Prio));//配对
	OSTimeDlyHMSM(0,0,0,10);	

	for(i = 0;i < 2048;i ++)
	{
		TempBuff[i] = i&0xff;
	}
	i = 320;
	//初始化A7139
	if(A7139_Init(101, 0x0123, 0, 80) == TRUE)
	{
		while(1)
		{
			LED2_ON();
			crc16 = CRC16(TempBuff, i);
			uart_printf("发送数据%dB,最后1B:0x%02X 校验:0x%04X\r\n",i, TempBuff[i-1], crc16);
			if(A7139_SendData(TempBuff,i) == TRUE)
			{
				uart_printf("发送成功\r\n");
			}
			else
			{
				uart_printf("发送超时\r\n");
			}
			LED2_OFF();
			OSTimeDlyHMSM(0,0,2,0);
			IWDG_Feed();
		}
	}
	else	//初始化失败
	{
		LED2_ON();
		uart_printf("通信初始化失!\r\n");
		OSTimeDlyHMSM(0,0,1,500);
		LED2_OFF();
	}
	while(1)
	{
		LED2_OFF();
		OSTimeDlyHMSM(0,0,0,100);
		IWDG_Feed();
	}
}

接收方测试

//初始化A7139
	if(A7139_Init(101, 0x0123, 0, 80) == TRUE)
	{
		for(i = 0;i < 10;i ++)
		{
			LED_FLASH();
			OSTimeDlyHMSM(0,0,0,10);
		}
		LED_OFF();
		
		if(A7139_SetRevListen(A433Buff, 6000) == FALSE)	//重新初始化
		{
			uart_printf("接收初始化失败\r\n");
		}
		i = 0;
		while(1)
		{
			len = A7139_GetRxLen();
			if(len < 0)	//接收错误
			{
				uart_printf("接收错误\r\n");
				if(A7139_SetRevListen(A433Buff, 6000) == FALSE)	//重新初始化
				{
					uart_printf("接收初始化失败\r\n");
				}
				i= 0;
			}
			else if(len)
			{
				//LED_ON();
				crc16 = CRC16(A433Buff, len);
				uart_printf("接收数据%dB,校验:0x%04X\r\n",len,  crc16);
				for(i = 0;i < len;i ++)
				{
					uart_printf("%02X ", A433Buff[i]);
				}
				uart_printf("\r\n");
				//uart_printf("接收成:%dB\r\n", len);
				OSTimeDlyHMSM(0,0,0,100);
				//LED_OFF();
				if(A7139_SetRevListen(A433Buff, 6000) == FALSE)	//重新初始化
				{
					uart_printf("接收初始化失败\r\n");
				}
				i = 0;
			}
			else 
			{
				i ++;
				if(i >  50)
				{
					 i = 0;
					uart_printf("接收超时\r\n");
					if(A7139_SetRevListen(A433Buff, 6000) == FALSE)	//重新初始化
					{
						uart_printf("接收初始化失败\r\n");
					}
				}
			}
			OSTimeDlyHMSM(0,0,0,100);
			IWDG_Feed();								//喂狗
		}
		
	}
	else	//初始化失败
	{
		LED_FLASH();
		OSTimeDlyHMSM(0,0,0,100);
	}

发送调试信息


接收方调试信息



版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/cp1300/article/details/47704255

智能推荐

QT设置QLabel中字体的颜色_qolable 字体颜色-程序员宅基地

文章浏览阅读8k次,点赞2次,收藏6次。QT设置QLabel中字体的颜色其实,这是一个比较常见的问题。大致有几种做法:一是使用setPalette()方法;二是使用样式表;三是可以使用QStyle;四是可以在其中使用一些简单的HTML样式。下面就具体说一下,也算是个总结吧。第一种,使用setPalette()方法如下:QLabel *label = new QLabel(tr("Hello Qt!"));QP_qolable 字体颜色

【C#】: Import “google/protobuf/timestamp.proto“ was not found or had errors.问题彻底被解决!_import "google/protobuf/timestamp.proto" was not f-程序员宅基地

文章浏览阅读3.7k次。使用C# 作为开发语言,将pb文件转换为cs文件的时候相信很多人都会遇到一个很棘手的问题,那就是protoc3环境下,import Timestamp的问题,在头部 import “google/protobuf/timestamp.proto”;的时候会抛异常:google/protobuf/timestamp.proto" was not found or had errors;解决办法【博主「pamxy」的原创文章的分享】:(注:之后才发现,不需要添加这个目录也可以,因为timestamp.p_import "google/protobuf/timestamp.proto" was not found or had errors.

安卓抓取JD wskey + 添加脚本自动转换JD cookie_jd_wsck-程序员宅基地

文章浏览阅读4.1w次,点赞9次,收藏98次。一、准备工具: 1. app:VNET(抓包用)、京东; 安卓手机需要下载VNET软件。下载官网:https://www.vnet-tech.com/zh/ 2. 已安装部署好的青龙面板;二、抓包wskey: 1. 打开已下载的VNET软件,第一步先安装CA证书; 点击右下角三角形按钮(开始抓包按钮),会提示安装证书,点击确定即可,app就会将CA证书下载至手机里,随后在手机设置里进行安装,这里不同手机可能安装位置不同,具体..._jd_wsck

Mybatis-Plus自动填充失效问题:当字段不为空时无法插入_mybatisplus插入不放为空的字段-程序员宅基地

文章浏览阅读2.9k次,点赞7次,收藏3次。本文针对mybatis-plus自动填充第一次更新能正常填充,第二次更新无法自动填充问题。????mybatis-plus自动填充:当要填充的字段不为空时,填充无效问题的解决????先上一副官方的图:取自官方:https://mp.baomidou.com/guide/auto-fill-metainfo.html第三条注意事项为自动填充失效原因:MetaObjectHandler提供的默认方法的策略均为:如果属性有值则不覆盖,如果填充值为null则不填充以官方案例为例:```java_mybatisplus插入不放为空的字段

Matlab 生成exe执行文件_matlab exe-程序员宅基地

文章浏览阅读1w次,点赞25次,收藏94次。利用 Application Complier 完成MATLAB转exe文件_matlab exe

Android下集成Paypal支付-程序员宅基地

文章浏览阅读137次。近期项目需要研究paypal支付,官网上的指导写的过于复杂,可能是老外的思维和中国人不一样吧。难得是发现下面这篇文章:http://www.androidhive.info/2015/02/Android-integrating-paypal-using-PHP-MySQL-part-1/在这篇文章的基础上,查看SDK简化了代码,给出下面这个例子,..._paypal支付集成到anroid应用中

随便推点

MIT-BEVFusion系列五--Nuscenes数据集详细介绍,有下载好的图片_nuscense数据集-程序员宅基地

文章浏览阅读2.3k次,点赞29次,收藏52次。nuScenes 数据集 (pronounced /nu:ːsiː:nz/) 是由 Motional (以前称为 nuTonomy) 团队开发的自动驾驶公共大型数据集。nuScenes 数据集的灵感来自于开创性的 KITTI 数据集。nuScenes 是第一个提供自动驾驶车辆整个传感器套件 (6 个摄像头、1 个 LIDAR、5 个 RADAR、GPS、IMU) 数据的大型数据集。与 KITTI 相比,nuScenes 包含的对象注释多了 7 倍。_nuscense数据集

python mqtt publish_Python Paho MQTT:无法立即在函数中发布-程序员宅基地

文章浏览阅读535次。我正在实现一个程序,该程序可以侦听特定主题,并在ESP8266发布新消息时对此做出反应.从ESP8266收到新消息时,我的程序将触发回调并执行一系列任务.我在回调函数中发布了两条消息,回到了Arduino正在侦听的主题.但是,仅在函数退出后才发布消息.谢谢您的所有宝贵时间.我试图在回调函数中使用loop(1),超时为1秒.该程序将立即发布该消息,但似乎陷入了循环.有人可以给我一些指针如何在我的回调..._python 函数里面 mqtt调用publish方法 没有效果

win11怎么装回win10系统_安装win10后卸载win11-程序员宅基地

文章浏览阅读3.4w次,点赞16次,收藏81次。微软出来了win11预览版系统,很多网友给自己的电脑下载安装尝鲜,不过因为是测试版可能会有比较多bug,又只有英文,有些网友使用起来并不顺畅,因此想要将win11退回win10系统。那么win11怎么装回win10系统呢?今天小编就教下大家win11退回win10系统的方法。方法一:1、首先点击开始菜单,在其中找到“设置”2、在设置面板中,我们可以找到“更新和安全”3、在更新和安全中,找到点击左边栏的“恢复”4、恢复的右侧我们就可以看到“回退到上版本的win10”了。方法二:_安装win10后卸载win11

SQL Server菜鸟入门_sql server菜鸟教程-程序员宅基地

文章浏览阅读3.3k次,点赞2次,收藏3次。数据定义_sql server菜鸟教程

Leetcode 数组(简单题)[1-1000题]_给定一个浮点数数组nums(逗号分隔)和一个浮点数目标值target(与数组空格分隔),请-程序员宅基地

文章浏览阅读1.9k次。1. 两数之和给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。示例:给定 nums = [2, 7, 11, 15], target = 9因为 nums[0] + nums[1] = 2 + 7 = 9所以返回 [0, 1]方法一..._给定一个浮点数数组nums(逗号分隔)和一个浮点数目标值target(与数组空格分隔),请

python性能优化方案_python 性能优化方法小结-程序员宅基地

文章浏览阅读152次。提高性能有如下方法1、Cython,用于合并python和c语言静态编译泛型2、IPython.parallel,用于在本地或者集群上并行执行代码3、numexpr,用于快速数值运算4、multiprocessing,python内建的并行处理模块5、Numba,用于为cpu动态编译python代码6、NumbaPro,用于为多核cpu和gpu动态编译python代码为了验证相同算法在上面不同实现..._np.array 测试gpu性能

推荐文章

热门文章

相关标签