CC1100的应用电路简单,仅需很少的外部元件即可工作。
如图2所示为315/433MHz频段的参考电路。
图中R1为偏置电阻,用以调整精确的偏置电流。
C8、C9、L1、L2构成一个非平衡变压器(Balun),将CC1100的差分输出变为单端射频信号,与LC网络一起进行阻抗变换以匹配50欧姆天线(或同轴电缆)。
在不同工作频率下各元件的值也有所不同,具体请参见CC1100的数据手册。
2、通用输出管脚CC1100具有3个通用数字输出管脚:GDO0、GDO1和GDO2,它们可以通过SPI接口被MCU配置成不同的功能,配置寄存器IOCFG【0,1,2】分别对应三个管脚的功能配置。
GDO1同时也是SPI接口的SO口,因此,只有在CSn=1时,所配置的输出功能才有效。
GDO1默认的配置为三态输出,在CSn为高时此管脚保持为高阻态,这样在总线连接多个器件时不会影响总线工作;GDO0默认配置为晶振频率的192分频输出(126KHz~146KHz)。
由于一上电复位Xosc就开始工作,因此此时钟输出可以用于给系统中其它器件提供振荡信号。
另外,CC1100片上集成有1个模拟温度传感器,当向IOCFG0.GDO0_CFG写入0x80时使能传感器,此时,GDO0脚的电压与温度成比例关系。
而GDO2的默认设置为CHIP_RDYn信号输出。
通过对IOCFG【0,1,2】寄存器的编程不仅可以改变GDO口线的功能,还可以改变其输出高低电平状态,寄存器构成如表3所示:表3 IOCFGx寄存器结构标志、三态输出、晶振频率分频输出等等,详见数据手册。
GDOx的配置在与MCU接口中非常重要,MCU可通过检测它们的输出来判断CC1100所处的状态。
四、CC1100的寄存器CC1100的内部寄存器包括五种:配置寄存器、命令滤波寄存器、状态寄存器、收/发FIFO以及功率配置表PATABLE。
1、配置寄存器:CC1100共有47个配置寄存器,如表4所示,包括GDO【0~2】配置、收发缓冲区门限、工作频率、调制模式等。
虽然寄存器较多,但是所有配置值可以很简便的由TI公司提供的SmartRF软件得到。
当然也可以手动计算,数据手册中给出了各寄存器详细的定义。
写入时,每一个头字节或数据字节发送时状态字节都会从SO发出。
读出时,每个头字节发送时,状态字节都会从SO发出。
连续地址的寄存器可以通过将头字节中的burst位B置1而实现连续写入,地址为A5~A0设置写入的内部地址寄存器初始地址,此寄存器每写入一字节数据时自动加1。
Burst访问可以是读也可以是写,但都必须由CSn置1来结束。
2、命令滤波寄存器命令滤波可以看做是CC1100的单字节指令。
通过对命令滤波寄存器的选址,内部时序被启动。
这些命令用来关闭晶体振荡器、使能接收/发送、清空FIFO等。
14个命令滤波如表5所示。
表5 CC1100指令集命令滤波寄存器的访问和配置寄存器的写操作一样,只是不传输数据。
访问命令滤波寄存器只发送一个头字节,其中 R/W位为0,突发访问位为0,六个地址位(0x30和0x3D之间)即为指令码。
当写命令滤波寄存器时,状态字节也从SO管教输出。
一个命令滤波操作可以在任何其他SPI访问之后发送,而不需要将CSn拉至高电平。
除了SPWD和SXOFF指令要在CSn变高时执行外,其余指令在写入后都会立即被执行。
3、状态寄存器CC1100的状态寄存器共有14个,如表6所示,均为只读。
由于命令滤波和状态寄存器地址相同,为了加以区分,CC1100规定,对于地址在0x30~0x3D范围内的寄存器操作,burst位用来选择是状态寄存器(=1)还是命令滤波(=0)。
因此,状态寄存器不能像配置寄存器一样使用burst访问方式,而只能一次访问1个寄存器,而且是只读的。
4、PATABLEPATABLE用于配置CC1100的功率放大器,可以通过地址0x3E访问。
PATABLE为一个8字节的表格,通过配置寄存器FREND0中的PA_POWER【2:0】的值来确定使用表中那一个值。
读/写PATABLE表时,总是最低字节在前,一次操作一字节,表中索引计数器自动加一,当到达最高字节后,自动变为0。
而且,每次CSn变高时,索引计数器复位,重新指向最低字节。
对PA TABLE的操作可以是单字节也可以是burst操作,这取决于Burst位的值。
值得注意的是,当芯片进入SLEEP状态时,除了最低字节(索引0)以外,表中其他内容都会丢失。
在不同频段、调制方式下,对应功率的设置值也有所不同,具体参见数据手册,也可以由SmartRF计算得出。
5、FIFO寄存器CC1100包含1个64字节的发送FIFO(只写)和一个64字节的接收FIFO(只读),可以通过0x3F地址访问。
在SPI接口发送的头字节中,当RW=0时访问发送FIFO,=1时访问接收FIFO。
Burst位决定是单字节操作(=0)还是burst操作(=1)。
因此,FIFO访问一共可有以下四种头字节:0x3F:单字节写发送FIFO;0x7F:burst写发送FIFO;0xBF:单字节读接收FIFO;0xFF:burst读接收FIFO。
在写发送FIFO时,状态字节在每个字节数据写入时从SO发送,此字节可以用于检测是否FIFO已满。
此外,可以使用SFRX、SFTX指令来清空接收、发送FIFO。
五、CC1100的包格式CC1100接收和发送的数据包格式如表7所示,其一包数据共包含6部分:前导码、同步字、长度、可选地址、数据、可选的CRC16校验码。
前导码:前导码是一个交替的1010序列,用于接收端进行信道检测。
其最小长度是可以编程的。
当使能TX时,调制器开始发送前导码序列。
发完前导码之后后,若发送FIFO中数据可用,调制器开始发送同步字和数据;如果发送FIFO为空,调制器会持续发送前导码,直到发送FIFO中写入第一个字节,之后开始发送同步码和数据。
前导码的长度由配置寄存器MDMCFG1中的NUM_PREAMBLE值决定。
同步字:是SYNC1和SYNC0寄存器中设置的2字节值,用于提供接收包的字节同步信息。
可以通过将SYNC1的值设置为前导码方式来实现单字节同步字。
也可以通过将MDMCFG2中SYNC_MODE的值设为3或7来实现32位的同步字,这时,SYNC0、1的值发送2次。
长度码:CC1100支持三种包长度:固定长度,可变长度和无限长度,由配置寄存器PKTCTRL0中LENGTH_CONFIG 项的值决定。
设置LENGTH_CONFIG=0时,采用固定长度数据包,包长度由PKTLEN寄存器设置,此时数据包内没有表7中的长度一项。
设置LENGTH_CONFIG=1时,采用可变长度数据包,包长度由同步字后面的第一个字节配置。
包长度是指纯数据的长度(表7中的地址+数据两项的字节数),不包含长度字节本身以及可选的CRC校验字节。
PKTLEN设置值为最大的包长度,任何接收到的长度字节值大于PKTLEN的包都将被丢弃。
设置LENGTH_CONFIG=2时,设置为无限包长度。
对于固定包长度和可变包长度,其长度值最大为255,要发送更长的数据包,就必须使用无限包长度。
地址码:地址码一项也是可选的,由配置寄存器PKTCTRL1中ADR_CHK的值决定。
当ADR_CHK=0时,接收端不检测地址,数据包中不含地址项;当ADR_CHK=1时,接收端检测地址,且没有广播地址;当ADR_CHK=2时,接收端检测地址,0x00为广播地址;当ADR_CHK=3时,接收端检测地址,0x00和0xFF为广播地址。
对于不为0的设置值,接收端每检测到一包数据,首先将包中的地址字节与本地地址(配置寄存器ADDR值)或者广播地址进行比较,如果地址匹配,则接收此包并将其写入接收FIFO,否则丢弃。
CRC码:CRC校验码也为可选项,在PKTCTRL0寄存器中,CRC_EN位若置1则使能CRC校验,否则无此项。
六、CC1100软件设计CC1100的软件设计主要包括三部分:初始化、发送数据包和接收数据包。
1、初始化在收发数据之前,必须对芯片进行初始化,即对各配置寄存器和PA TABLE进行设置。
这一步最简便的方法是从TI官方网站下载SmartRF软件,安装后,在其各项配置(如频率、调制方式、数据速率、功率、包长度等)中输入所需参数,如图3所示,然后将软件自动生成的各寄存器值在自己编写的程序中写入CC1100即可。
图3 SmartRF参数配置2、数据发送在发送数据前,待发数据必须先写入发送FIFO。
为可变包长度时,写入的第一个字节必须是长度值,此长度包含了目的地址和数据;若为固定包长度,则第一个字节应该是目的地址。
写完FIFO之后使用STX命令使能发送即可,前导码、同步字、CRC校验码均为芯片自动计算加入。
void CC1100_Tx_Packet(){CC1100_Strobe(CC1100_SIDLE); //进入空闲模式if( CC1100_WriteBurstReg(CC1100_TXFIFO, CC1100_BUF.TX, Len)==1 ){CC1100_Strobe(CC1100_STX); //进入发送模式发送数据while (!(CC1100_SYNC_END)); //等待同步字发送完while (CC1100_SYNC_END); //等待包发送结束CC1100_Strobe(CC1100_SFTX); //清空发送缓冲区CC1100_Strobe(CC1100_SRX); //使CC1100处于接收状态}}上面是一段发送子程序代码,这里用到了一个GDO管脚(程序中的CC1100_SYNC_END)来检测CC1100状态,在初始化时将其配置为0x06,在接收(或发送)完同步字时,GDO触发,当包接收(或发送)完毕后,GDO恢复。
3、数据接收MCU感知CC1100接收完一包数据,可以通过GDO管脚或SPI总线获取状态。
对于SPI总线方式,可以查询PKTSTATUS寄存器获取当前状态,查询RXBYTES和TXBYTES寄存器可以检测当前FIFO中的字节数等。
由于查询操作都需要进行SPI通信,相对来说要麻烦一点,因而如果口线资源够的话,最好还是采用端口查询或中断方式。
利用GDO管脚方式,在初始化时配置好后,只需定时查询口线电平,或者利用电平变化产生中断,相对要简单一些。
除了0x06配置外,还有两个设置(0x00,0x01)与接收FIFO相关联,以及两个设置(0x02,0x03)与发送FIFO 相关联,其他配置如0x07(正确接收一包数据且CRC校验正确触发,当接收FIFO中第一个字节被读出时恢复)等也可以用于接收检测,具体参见数据手册。
笔者在应用中仍然使用了0x06配置,由于在接收到同步字和接收完数据包之间端口会有一个变化过程,利用此变化产生中断,在终端中再读取数据,具体接收子程序如下:unsigned char CC1100_Rx_Packet(unsigned char *rxBuffer){unsigned char status[2];unsigned char pktLen;if ((CC1100_ReadStatus(CC1100_RXBYTES) & CC1100_NUM_RXBYTES)){pktLen = CC1100_ReadReg(CC1100_RXFIFO); // 读取长度字节if (pktLen <= PKT_MAX_LEN) // 长度是否在允许范围内{CC1100_ReadBurstReg(CC1100_RXFIFO, rxBuffer, pktLen); // 读取数据CC1100_ReadBurstReg(CC1100_RXFIFO, status, 2); // 读取两字节状态字if(status[1]&CC1100_CRC_OK ) //如果CRC校验正确,返回接收包长度{ return(pktLen); }}}CC1100_Strobe(CC1100_SFRX); // 清空接收FIFOCC1100_Strobe(CC1100_SRX); // 使CC1100处于接收状态return 0;}七、结束语CC1100支持频段多,接收灵敏度高,支持多种调制方式、数据速率,接口简单,占用MCU资源较少,而且功耗小、成本低,适用于多种应用场合。