140M至1020mMHz无线通信方案(基于CMT2300A)

CMT2300A是一款国产的FSK、OOK射频收发器

它有专用的上位机便于生成寄存器参数,广泛运用与智能家居、无线控制方面

CMT2300A

CMT2300A 是一款超低功耗,高性能,适用于各种 140 至1020 MHz 无线应用的 OOK,(G)FSK 射频收发器。它是CMOSTEK NextGenRFTM 射频产品线的一部分,这条产品线包含完整的发射器,接收器和收发器。CMT2300A 的高集成度,简化了系统设计中所需的外围物料。高达+20 dBm 及-121dBm 的灵敏度优化了应用的链路性能。它支持多种数据包格式及编解码方式,使得它可以灵活的满足各种应用对不同数据包格式及编解码的需求。另外,CMT2300A 还支持 64-bytex/Rx FIFO, 丰富的 GPIO 及中断配置,Duty-Cycle 运行模式,信道侦听,高精度 RSSI,低电压检测,上电复位,低频时钟输出,手动快速跳频,静噪输出等功能,使得应用设计更加灵活,实现产品差异化设计。CMT2300A 工作于 1.8 V至 3.6 V。当达到-121 dBm 灵敏度的时候仅消耗 8.5 mA 电流,超低功耗接收模式可以进一步降低芯片的接收功耗;以13dBm 输出是仅消耗 23 mA 发射电流。

技术参数

● 频率范围:127至1020MHz
● 调制解调方式:OOK, (G)FSK 和(G)MSK
● 数据率: 0.5 至 300 kbps
● 灵敏度: -121 dBm 2.0kbps, F RF = 433.92 MHz;-111 dBm 50kbps, F RF = 433.92 MHz
● 电压范围:1.8 至 3.6 V
● 发射电流:23 mA @ 13 dBm, 433.92 MHz, FSK;72 mA @ 20 dBm, 433.92 MHz, FSK
● 接收电流:8.5 mA @ 433.92 MHz, FSK
● 支持超低功耗接收模式
● 睡眠电流
300 nA, DutyCycle = OFF 800 nA, DutyCycle = ON
● 3-wire SPI 接口
● 支持直通及包模式
● 可配置包处理机及 64-Byte FIFO
● 不归零,曼切斯特,数据白化编解码
● 支持前向纠错
● 16 管脚 QFN3x3 封装

应用电路

在这里插入图片描述

通信协议

MCU 和芯片之间的通讯是通过 4 线 SPI 接口进行的。低有效的 CSB 意味着 MCU 要访问芯片的寄存器。低有效的 FCSB 意 味着 MCU 要访问芯片的 FIFO。CSB 和 FCSB 不能同时为低。SCLK 是串口时钟。对于 MCU 和芯片,数据总是在 SCLK 的下降 沿发射,上升沿采样。SDIO 是一个双向的数据管脚。地址和数据总是从 MSB 开始发送。

读写寄存器时序在这里插入图片描述

如果要发送还是接收数据,数据都要从FIFO当中写入或者读取,所以要写读写FIFO的时序:
在这里插入图片描述
在这里插入图片描述

底层驱动代码

SPI操作寄存器代码:

/********************************************************************************
**名字: vSpi3WriteByte
**作用: 写入一个字节
*********************************************************************************/
void vSpi3WriteByte(byte dat,bool sda_in)
{
	byte bitcnt;
	SetFCSB();
	OutputSDIO();
	SetSDIO();
	ClrSDCK();
	ClrCSB();
	for(bitcnt = 8;bitcnt !=0;bitcnt--)
	{
		ClrSDCK();
		if(dat &0x80)
			SetSDIO();
		else
			ClrSDIO();
		#if(SPI3_SPEED !=0)
			DelayUs(SPI3_SPEED);
		#endif
		SetSDCK();
		dat <<= 1;
		#if(SPI3_SPEED !=0)
			DelayUs(SPI3_SPEED);
		#endif

	}
	if(sda_in)                               //转换到读
	{
		InputSDIO();
		ClrSDCK();
	}
	else
	{
		ClrSDCK();
		SetSDIO();
	}
}
/**********************************************************
**名字:  bSpi3ReadByte
**作用:  读一个字节
**********************************************************/
byte bSpi3ReadByte(void)
{
	byte RdPara = 0;
	byte bitcnt;
	ClrSDCK();
	InputSDIO();
	ClrCSB(); 
	DelayUs(SPI3_SPEED);
	DelayUs(SPI3_SPEED);
	for(bitcnt=8; bitcnt!=0; bitcnt--)
	{
		SetSDCK();
		RdPara <<= 1;
		#if (SPI3_SPEED!=0)
      			DelayUs(SPI3_SPEED);
  		#endif
  		if(SDIO_H())
    			RdPara |= 0x01;
   		else
   		 	RdPara |= 0x00;
   		ClrSDCK();
   		#if (SPI3_SPEED!=0)
      			DelayUs(SPI3_SPEED);
  		#endif
	}
	ClrSDCK();
	return(RdPara); 
}
/**********************************************************
**名字:   vSpi3Write
**作用:  写一个字
**输入:  Write word
**输出:  none
**********************************************************/
void vSpi3Write(word dat)
{
  	vSpi3WriteByte(((byte)(dat>>8)&0x7F), FALSE);
  	vSpi3WriteByte(((byte)dat), FALSE);
  	SetCSB();
}
/**********************************************************
**名字:  vSpi3WriteCmd
**作用:  写命令
**输入:  dat byte 
**输出:  none
**********************************************************/
void vSpi3WriteCmd(byte dat)
{
  	vSpi3WriteByte((dat&0x7F), FALSE);
  	SetCSB();
}
/**********************************************************
**名字:  vSpi3WriteTreable
**作用:  往寄存器写数据
**输入:  byte addr  word dat
**输出:  none
**********************************************************/
void vSpi3WriteTreable(byte addr, word dat)
{ 
 	vSpi3WriteByte((addr&0x7F), FALSE);
	vSpi3WriteByte(((byte)(dat>>8)), FALSE);
	vSpi3WriteByte(((byte)dat), FALSE);
	SetCSB();
}
/**********************************************************
**名字:  vSpi3BurstWriteCmd
**作用:  往寄存器连续数据
**输入:  byte addr  byte ptr[] byte length
**输出:  none
**********************************************************/
void vSpi3BurstWriteCmd(byte addr, byte ptr[], byte length)
{
	byte i;
	vSpi3WriteByte((addr&0x7F), FALSE);
	for(i=0; i<length; i++)
		vSpi3WriteByte(ptr[i], FALSE);
	SetCSB();
}
/**********************************************************
**名字:   bSpi3Read
**作用:  读一个字
**输入:  readout addresss
**输出:  readout byte
**********************************************************/
byte bSpi3Read(byte addr)
{
	byte dat;
	vSpi3WriteByte((addr|0x80), TRUE);
	dat = bSpi3ReadByte();
	OutputSDIO();
	SetSDIO();
	SetCSB();
	return(dat);
}
/**********************************************************
**名字:   wSpi3ReadTreable
**作用:  读寄存器中的一个字
**输入:  readout addresss
**输出:  readout word 
**********************************************************/
word wSpi3ReadTreable(byte addr)
{
	word dat;
	vSpi3WriteByte((addr|0x80), TRUE);
	dat   = bSpi3ReadByte();
	dat <<= 8;
	dat  |= bSpi3ReadByte();
	OutputSDIO();
	SetSDIO();
	SetCSB();
	return(dat);
}
/**********************************************************
**名字:   vSpi3BurstReadCmd
**作用:  连续读寄存器中的字
**********************************************************/
void vSpi3BurstReadCmd(byte addr, byte ptr[], byte length)
{
	byte i;
	vSpi3WriteByte((addr|0x80), TRUE);
	for(i=0; i<length; i++)
		ptr[i] = bSpi3ReadByte();
	OutputSDIO();
	SetSDIO();
	SetCSB();
}

SPI操作FIFO的代码

/**********************************************************
**Name:   vSpi3WriteFIFO
**Func:  SPI-3 send one byte to FIFO
**Input:  one byte buffer
**Output: none
**********************************************************/
void vSpi3WriteFIFO(byte dat)
{
	byte bitcnt;
	SetCSB();
	OutputSDIO();
	ClrSDCK();
	ClrFCSB();
	for(bitcnt=8; bitcnt!=0; bitcnt--)
	{
		ClrSDCK();
		if(dat&0x80)
			SetSDIO();
		else
			ClrSDIO();
		#if (SPI3_SPEED!=0)
			DelayUs(SPI3_SPEED);
		#endif
		SetSDCK();
		#if (SPI3_SPEED!=0)
			DelayUs(SPI3_SPEED);
		#endif
		dat <<= 1;
	}
	ClrSDCK();
	DelayUs(SPI3_SPEED);  //Time-Critical
	DelayUs(SPI3_SPEED);  //Time-Critical
	SetFCSB();
 	SetSDIO();
 	DelayUs(SPI3_SPEED);  //Time-Critical
 	DelayUs(SPI3_SPEED);  //Time-Critical
}
/**********************************************************
**Name:   bSpi3ReadFIFO
**Func:  SPI-3 read one byte to FIFO
**Input:  none
**Output: one byte buffer
**********************************************************/
byte bSpi3ReadFIFO(void)
{
	byte RdPara;
	byte bitcnt;
	SetCSB();
	InputSDIO();
	ClrSDCK();
	ClrFCSB();
	
	DelayUs(SPI3_SPEED);  //Time-Critical
	DelayUs(SPI3_SPEED);  //Time-Critical
	
	for(bitcnt=8; bitcnt!=0; bitcnt--)
	{
		SetSDCK();
		#if (SPI3_SPEED!=0)
      			DelayUs(SPI3_SPEED);
  		#endif
  		RdPara <<= 1;
   		if(SDIO_H())
   			RdPara |= 0x01;  //NRZ MSB
   		else
    		 	RdPara |= 0x00;  //NRZ MSB
    		 ClrSDCK();
    		 #if (SPI3_SPEED!=0)
      			DelayUs(SPI3_SPEED);
  		#endif
	}
	ClrSDCK();
  	SetFCSB();
 	OutputSDIO();
 	SetSDIO();
  	return(RdPara);
}
/**********************************************************
**Name:   vSpi3BurstWriteFIFO
**Func:  burst wirte N byte to FIFO
**Input:  array length & head pointer
**Output: none
**********************************************************/
void vSpi3BurstWriteFIFO(byte ptr[], byte length)
{
  	byte i;
  	if(length!=0x00)
   	{
   		for(i=0;i<length;i++)
    		vSpi3WriteFIFO(ptr[i]);
   	}
  	return;
}
/**********************************************************
**Name:   vSpiBurstRead
**Func:  burst wirte N byte to FIFO
**Input:  array length  & head pointer
**Output: none
**********************************************************/
void vSpi3BurstReadFIFO(byte ptr[], byte length)
{
 	byte i;
  	if(length!=0)
   	{
   		for(i=0;i<length;i++)
    		ptr[i] = bSpi3ReadFIFO();
   	} 
  	return;
}

上层配置

这里我利用了官方的HAL库和寄存器文件,CMT2300的寄存器比较多,这里使用官方的上位机直接生成初始化配置头文件

在这里插入图片描述
官方上位机:
在这里插入图片描述
配置好频段,调制方式导出即可。

顶层API程序使用

笔者已经对底层函数经行了封装,如果改变控制器型号,只需更改my_spi.h里的引脚定义即可。
CMT2300_Init();
Cmt2300_Rx_Init();两个函数初始化接收模式,再调用读取FIFO函数读取——
bGetMessageByFlag(a),a为接收的字符串数据,每次接收后清除一下接收FIFO——vClearFifo(),

CMT2300_Init();
Cmt2300_Tx_Init();两个函数初始化发射模式,再调用写FIFO函数——
bSendMessageByFlag(“Hello”,16),发送“Hello”

笔者不太想用它的中断模式,所以接收读取采用的访问寄存器标识位判断接收或者发送成功。
最后工程链接(在IAR环境下)
源代码地址

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值