单片机
返回首页

CC1101接口库在STM32上的移植

2016-07-18 来源:eefocus

【目的】

移植原来TI对于CC1101与MSP430接口库到STM32平台,参考原TI库应用笔记“ MSP430 Interface to CC1100/2500 Code Library”,做到尽量保持所有函数名不改变,以方便以前基于MSP430的程序向STM32移植。

 【要求】

1.编程要求:改写原来基于MSP430的程序,使用于STM32,尽量保持所有函数名不改变,以方便以前基于MSP430的程序向STM32移植。

2.实现功能:STM32与CC1101通过SPI接口正常传输数据,不同节点的CC1101可以正常传输数据。

3.实验现象:STM32与CC1101连接后,可以与另一个节点通信,节点初始在随机时间发送一个数据,任一节点收到数据后LED闪一下,并把数据回传,如此循环,会看到LED不停闪烁。

【硬件电路】

测试时CC1101与STM32引脚连接表如表1所示。

 

表1  CC1101与STM32引脚连接表

CC1101部分

STM32部分

功能

引脚位号

名称

引脚位号

名称

1

VCC

18

VSS_1

电源

2

GND

19

VDD_1

3

SI

14

PA7/SPI1_MOSI

SPI接口MOSI

4

SCLK

12

PA5/SPI1_SCK

SPI接口时钟线

5

SO

13

PA6/SPI1_MISO

SPI接口MISO

6

GDO2

9

PA2

通用IO

7

GDO0

8

PA1

接收中断

8

CSN

10

PA3

芯片片选使能

 

 

【原理】

CC1101是TI公司一款高性价比的单片UHF收发器,为低功耗无线电应用而设计。它是CC1100器件的加强升级版,灵敏度更高,功耗更小,带宽更大。CC1101可满足多个领域中的低功耗无线应用要求,如警报与安全、自动抄表、工业监控以及家庭和楼宇自动化等。CC1101理想适用于工业、科学及医药设备(ISM)以及316、433、868及916MHz短距装置(SRD)频带。但是,该器件也可方便编程,以支持其它频率,如300-348MHz、387-467MHz及779-928MHz等。出色的频带与调制格式支持使其能与目前的RF终端设备相兼容。 

 

CC1101接口库在STM32上的移植 - armplc - armplc的博客===工控人生===

 

 图1  CC1101 的外引脚图(俯视)

CC1100通过4线SPI兼容接口 (SI,SO,SCLK和 CSn)配置。这个接口同时用作写和读缓存数据。SPI 接口上所有的处理都同一个包含一个读/写位,一个突发访问位和一个 6 位地址的头字节一起作用。在地址和数据转换期间, CSn 脚 (芯片选择,低电平有效)必须保持为低电平。如果在过程中 CSn 变为高电平,则转换取消。当 CSn 变低, 在开始转换头字节之前, MCU必须等待,直到 SO脚变低。这表明电压调制器已经稳定,晶体正在运作中。除非芯片处在 SLEEP 或 XOFF 状态,SO 脚在 CSn变低之后总会立即变低。关于CC1101对配置寄存器写和读操作如图2所示。

 芯片状态位

当头字节在 SPI 接口上被写入时,芯片状态字节在 SO 脚上被 CC1100 写入。状态字节包含关键状态信号,对MCU是有用的。第一位 s7,是CHIP_RDYn 信号。在 SCLK的在第一个正边缘之前,这个信号必须变低。CHIP_RDYn 信号表明晶体正处于工作中,调节数字供给电压是稳定的。6,5 和4 位由状态值组成。这个值反映了芯片的状态。 当使 XOSC 空闲并使数字中心的能量开启,所有其他模块处于低功耗状态时。只有芯片处于此状态时,频率和信道配置才能被更新。当芯片处于接收模式时, RX状态是活动的。同样地,当芯片处于发送模式时,TX状态是活动的。状态字节中的后四位( 3 :0)包含FIFO_BYTES_AVAILABLE。为了进行读操作,这个区域包含可从 RX FIFO 读取的字节数。为了进行写操作,这个区域包含可写入 TX FIFO 的 字节数。

寄存器访问

CC1100配置寄存器位于SPI地址从0x00到0x2F之间。所有的配置寄存器均能读和写。当对寄存器写时,每当一个待写入的数据字节传输到 SI脚时,状态字节将被送至 SO脚。 通过在地址头设置突发位,连续地址的寄存器能高效地被访问。这个地址在内部计数器内设置起始地址。每增加一个新的字节计数器值增加 1。 突发访问,不管是读访问还是写访问,必须通过设置CSn 为高来终止。对 0x30-0x3D间的地址来说, 突发位用以在状态寄存器和命令滤波之间选择。状态寄存器只读。突发读取对状态寄存器是不可取的,故它们每次只能被读一个。

命令滤波

命令滤波可被视为 CC1100 的单字节指令。通过命令滤波寄存器的选址,内部序列被启动。这些命令用来关闭晶体振荡器,开启传输模式和电磁波激活等。命令滤波寄存器的访问和一个寄存器的写操作一样,但没有数据被传输。就是说,只

有 R/W 位(置为 0) ,突发访问(置为 0)和六个地址位(0x30和0x3D之间)被写。一个命令滤波可能在任何其他 SPI 访问之后,而不需要将 CSn 拉至高电平。命令滤波立即被执行,当 CSn 高时 SPWD和 SXOFF滤波是例外。

FIFO访问

64 字节 TX FIFO 和 64 字节 RX FIFO 通过0x3F 被访问。当读/写位为 0 时,TX FIFO被访问,当读/写位为 1 时,RX FIFO 被访问。 TX FIFO是只写的,而 RX FIFO是只读的。突发位用来决定 FIFO 访问是单字节还是突发访问。单字节访问方式期望地址的突发位为 0 及1 数据字节。在数据字节之后等待一个新的地址,因此,CSn继续保持低。突发访问方式允许一地址字节,然后是连续的数据字节,直到通过设置 CSn 为高来关断访问。 当对 TX FIFO写时,状态字节对每个 SO脚上的新数据字节是输出量,如图 6 所示。这个状态位能用来侦测对 TX FIFO 写数据时的下溢。注意,状态字节包含在写入字节到 TX FIFO 的过程前空闲的字节数。当最后一个适合 TX FIFO的字节被传送至 SI 脚后, 被 SO脚接收的状态位会表明在 TX FIFO中只有一个字节是空闲的。  

传输 FIFO 可能会通过发布一个 SFTX 命令滤波而被淹没。相似地,一个 SFRX命令滤波会淹没接收 FIFO。当进入休眠状态时, 两个 FIFO都被清空。PATABLE 访问

0x3E 地址用来访问 PATABLE。PATABLE用来选择 PA 能量控制设置。在接收此地址之后,SPI 等待至少 8 个字节。通过控制PATABLE,能实现可控的 PA能量上升和下降,减少的带宽的 ASK 调制整型也如此PATABLE 是一个 8 字节表, 定义了 PA控制         设置, 为 8 个 PA 功率值(由FRENDO.PA_POWER 的 3 个位的值所选择)的每一个所使用。这个表从最低位到最高位可读和写,一此一位。一个索引计数器用来控制对这个表的访问。每读出或写入表中的一个字节,计数器就加 1。当 CSn 为高时,计数值置为最小值。当达到最大值时,计数器由零重新开始计数。  

PATABLE 访问

对 PATABLE 的访问是单字节或者突发访问,由突发位决定。当使用突发访问时,索引计数器的值增加;达到7时重新从0开始。读/写位控制访问是写访问(R/W=0)或者读访问(R/W=1)。 如果一字节被写入 PATABLE,且这个值将要被读出,那么,为了设置索引计数器的值重为 0,CSn必须在读访问之前置为高。  注意,当 PATABLE 进入休眠状态时,所存储的内容会丢失,特别是第一个字节。 

  

CC1101接口库在STM32上的移植 - armplc - armplc的博客===工控人生===

 

图2  配置寄存器写和读操作

 STM32的串行外设接口(SPI)

STM32的串行外设接口(SPI)有如下特性:

●  3线全双工同步传输

●  带或不带第三根双向数据线的双线单工同步传输

●  8或16位传输帧格式选择

●  主或从操作

●  支持多主模式

●  8个主模式波特率预分频系数(最大为fPCLK/2)

●  从模式频率 (最大为fPCLK/2)

●  主模式和从模式的快速通信

●  主模式和从模式下均可以由软件或硬件进行NSS管理:主/从操作模式的动态改变

●  可编程的时钟极性和相位

●  可编程的数据顺序,MSB在前或LSB在前

●  可触发中断的专用发送和接收标志

●  SPI总线忙状态标志

●  支持可靠通信的硬件CRC

─  在发送模式下,CRC值可以被作为最后一个字节发送

─  在全双工模式中对接收到的最后一个字节自动进行CRC校验

●  可触发中断的主模式故障、过载以及CRC错误标志

●  支持DMA功能的1字节发送和接收缓冲器:产生发送和接受请求

 

通常SPI通过4个引脚与外部器件相连:  MISO:主设备输入/从设备输出引脚。该引脚在从模式下发送数据,在主模式下接收数据。 MOSI:主设备输出/从设备输入引脚。该引脚在主模式下发送数据,在从模式下接收数据。 SCK:串口时钟,作为主设备的输出,从设备的输入  NSS:从设备选择。这是一个可选的引脚,用来选择主/从设备。它的功能是用来作为“片

选引脚”,本实验中没有使用。SPI的方框图如图3所示。

  

CC1101接口库在STM32上的移植 - armplc - armplc的博客===工控人生===

 

图3  SPI内部框图

  

CC1101接口库在STM32上的移植 - armplc - armplc的博客===工控人生===

 

 图4  数据帧格式图

 【实验步骤】

1.学习STM32串行外设接口(SPI)相关知识,熟悉所调用的库函数,学习CC1101相关知识,熟悉CC1101的配置方法,研究TI关于CC1101与MSP430的接口程序库,熟悉库的实现方法。

2.连接电路。

3.编写程序,借助逻辑分析仪工具,调试程序。

【程序代码结构】

所有与CC1101相关的代码均放于CCxxxx文件夹,源文件用途分类说明如表2所示。对于应用分层框图如图5所示。因为程序较大,仅把与硬件相关、改动较大的TI_CC_spi.c放在附录中。

 

表2  源文件用途分类说明

类型

文件名

功能

硬件定义文件

TI_CC_CC1100-CC2500.h

对CC1101内部寄存器的定义

TI_CC_STM32.h

对使用的STM32相关SPI引脚进行定义

TI_CC_hardware_board.h

对使用的STM32通用数据引脚进行定义

SPI接口文件

TI_CC_spi.c

通过SPI访问CC1101寄存器的功能实现文件。

TI_CC_spi.h

对TI_CC_spi.c的函数进行声明

与应用层接口文件

CC1100-CC2500.c

对CC1101的使用的功能文件,包括初始化、发送数据包、接收数据包

CC1100-CC2500.h

对CC1100-CC2500.c的函数进行声明

include.h

高层包含文件,包含所有.h文件

 

 


应用层


CC1100-CC2500.c

 

 


TI_CC_spi.c


TI_CC_hardware_board.h

 


TI_CC_STM32.h


TI_CC_CC1100-CC2500.h


TI_CC_STM32.h


SPI应用


硬件定义

 

 

 

 

                                                         main.c

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

CC1101接口库在STM32上的移植 - armplc - armplc的博客===工控人生===

 

图5 库文件程序分层框图

【实验总结】

CC1101是在上升沿读入数据,即上升沿有效,一般时钟线默认是高电平,配置此功能的寄存器时CPOL(时钟极性 )和CPHA(时钟相位)当CPOL=0时,空闲状态时,SCK保持低电平,CPOL=1时,空闲状态时,SCK保持高电平。CPHA =0时数据采样从第一个时钟边沿开始,CPHA =1时数据采样从第二个时钟边沿开始。在CC1101的配置中,这两个控制配置为CPOL=1,CPHA =1。

在改写原来TI的程序时,为了保持好的移植性,因此对所有的函数名均未做改变,文件名也尽量不改变,仅将TI_CC_MSP430.h改为TI_CC_STM32.h,当然因为是应用于两种截然不同的MCU,所以与硬件相关的宏定义有较大改变。

STM32与CC1101的通信的逻辑分析仪截图如图6-图8所示,其中图6是启动CC1101时的逻辑波形,图7是写配置寄存器时的逻辑波形,图8读寄存器时的逻辑波形。

 

 

CC1101接口库在STM32上的移植 - armplc - armplc的博客===工控人生===

 

 6 启动CC1101时的逻辑波形

 

CC1101接口库在STM32上的移植 - armplc - armplc的博客===工控人生===

   

图  写配置寄存器时的逻辑波形 

 

CC1101接口库在STM32上的移植 - armplc - armplc的博客===工控人生===

  

图8 读寄存器时的逻辑波形 

附录:

////////////////////////////////////////////////////////////////////////////////

// 文件名:   TI_CC_spi.c

// 工作环境: IAR for ARM 5.41 Kickstart,基于STM32F103ZE-EK

// 作者:     程家阳

// 生成日期: 2010.03.15

// 功能:     STM32与CCxxxx进行通信的SPI底层函数,完成初始化STM32的SPI口用于连接    

//           CCxxxx,读写CCxxxx寄存器。

//注意: 

//

//

// 相关文件:

// 修改日志:

////////////////////////////////////////////////////////////////////////////////

 

 

#include 'include.h'

#include 'TI_CC_spi.h'

 

////////////////////////////////////////////////////////////////////////////////

// 程序名 : void TI_CC_Wait(unsigned int cycles)                                                  

// 作用 :   延时                     

// 输入参数:无                                     

// 输出参数:无                                     

// 说明:    uS级延时

//

////////////////////////////////////////////////////////////////////////////////

void TI_CC_Wait(unsigned int cycles)

{

  while(cycles>15)                          // 15 cycles consumed by overhead

    cycles = cycles - 6;                    // 6 cycles consumed each iteration

}

 

////////////////////////////////////////////////////////////////////////////////

// 程序名 : void TI_CC_SPISetup(void)                                                

// 作用 :   初始化配置SPI                      

// 输入参数:无                                     

// 输出参数:无                                    

// 说明:   

//

////////////////////////////////////////////////////////////////////////////////

void TI_CC_SPISetup(void)

{

  SPI_InitTypeDef SPI_SST_Init_Structure;//定义SPI配置结构体

 

  GPIO_WriteBit(TI_CC_CSn_GPIO, TI_CC_CSn_PIN, Bit_SET);//CS disable

  RCC_APB2PeriphClockCmd( RCC_APB2Periph_SPI1 ,ENABLE);//时钟使能

 

  //配置为双线双工模式 

  SPI_SST_Init_Structure.SPI_Direction=SPI_Direction_2Lines_FullDuplex;

  //主器件

  SPI_SST_Init_Structure.SPI_Mode=SPI_Mode_Master;

  //8bit数据帧

  SPI_SST_Init_Structure.SPI_DataSize=SPI_DataSize_8b;

  //时钟线默认高

  SPI_SST_Init_Structure.SPI_CPOL=SPI_CPOL_High ;

  //数据捕获于第二个时钟沿,这两个其实配置了时钟极性和相位

  SPI_SST_Init_Structure.SPI_CPHA=SPI_CPHA_2Edge;

  //NSS模式选择

  SPI_SST_Init_Structure.SPI_NSS=SPI_NSS_Soft;

  //波特率预分频值为 64

  SPI_SST_Init_Structure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_64;

  //数据传输从 MSB 位开始

  SPI_SST_Init_Structure.SPI_FirstBit=SPI_FirstBit_MSB;

 

  SPI_Init(SPI1, &SPI_SST_Init_Structure);  //操作

 

  SPI_Cmd(SPI1,ENABLE);                     //使能 

  //下面的几句,具体作用不太清楚,需了解

  //TI_CC_SPI_USCIA0_PxSEL |= TI_CC_SPI_USCIA0_SIMO | TI_CC_SPI_USCIA0_SOMI | TI_CC_SPI_USCIA0_UCLK;

                                            // SPI option select

  //TI_CC_SPI_USCIA0_PxDIR |= TI_CC_SPI_USCIA0_SIMO | TI_CC_SPI_USCIA0_UCLK;

                                            // SPI TXD out direction

}

 

 

////////////////////////////////////////////////////////////////////////////////

// 程序名 : void TI_CC_SPIWriteReg(char addr, char value)                                             

// 作用 :   向一个'addr'指向的寄存器中写入值'value'                   

// 输入参数:char addr :指向的地址

//          char value :要写入的值

// 输出参数:无                                    

// 说明:   

//

////////////////////////////////////////////////////////////////////////////////

void TI_CC_SPIWriteReg(char addr, char value)

{

    GPIO_WriteBit(TI_CC_CSn_GPIO, TI_CC_CSn_PIN, Bit_RESET);     //CS enable

    // Wait for CCxxxx ready

    while(GPIO_ReadInputDataBit(TI_CC_SPI_USCIA0_GPIO, TI_CC_SPI_USCIA0_SOMI)!= RESET)

    {

      ;

    }

 

    SPI_I2S_SendData(SPI1, (uint16_t)addr);// Send address 

    // Wait for TX to finish$$

    while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY  )!= RESET)//线路忙则等待

    {

      ;

    }

    SPI_I2S_SendData(SPI1, (uint16_t)value);//发送数据通过SPI1    

    // Wait for TX to finish

    while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY  )!= RESET)//线路忙则等待

    {

      ;

    }

    GPIO_WriteBit(TI_CC_CSn_GPIO, TI_CC_CSn_PIN, Bit_SET);     // CS disable

}

 

////////////////////////////////////////////////////////////////////////////////

// 程序名 : void TI_CC_SPIWriteBurstReg(char addr, char *buffer, char count)                                         

// 作用 :   向一个'addr'指向的寄存器中写入值'value'                   

// 输入参数:char addr :指向的地址

//          char value :要写入的值

// 输出参数:无                                    

// 说明:   

//

////////////////////////////////////////////////////////////////////////////////

void TI_CC_SPIWriteBurstReg(char addr, char *buffer, char count)

{

    unsigned int i;

 

    GPIO_WriteBit(TI_CC_CSn_GPIO, TI_CC_CSn_PIN, Bit_RESET);     // /CS enable

    // Wait for CCxxxx ready

    while(GPIO_ReadInputDataBit(TI_CC_SPI_USCIA0_GPIO, TI_CC_SPI_USCIA0_SOMI)!= RESET)

    {

      ;

    }

   

    // Send address

    SPI_I2S_SendData(SPI1, (uint16_t)(addr | TI_CCxxx0_WRITE_BURST));

    while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY  )!= RESET)//线路忙则等待

    {

      ;

    }

    for (i = 0; i < count; i++)

    {

      // Send data

      SPI_I2S_SendData(SPI1, (uint16_t)buffer[i]);//发送数据通过SPI1   

      while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY  )!= RESET)//线路忙则等待

      {

        ;

      }

    }

 

    GPIO_WriteBit(TI_CC_CSn_GPIO, TI_CC_CSn_PIN, Bit_SET);     //CS disable

}

 

////////////////////////////////////////////////////////////////////////////////

// 程序名 : char TI_CC_SPIReadReg(char addr)                                         

// 作用 :   从一个单一的配置寄存器中读数,寄存器地址:'addr'                   

// 输入参数:char addr :指向的地址

// 输出参数:char       :返回的寄存器值                             

// 说明:   

//

////////////////////////////////////////////////////////////////////////////////

char TI_CC_SPIReadReg(char addr)

{

  char x;

 

  GPIO_WriteBit(TI_CC_CSn_GPIO, TI_CC_CSn_PIN, Bit_RESET);     // /CS enable

  // Wait for TX to finish

  while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY  )!= RESET)//线路忙则等待

  {

    ;

  }

  // Send address

  SPI_I2S_SendData(SPI1, (uint16_t)(addr | TI_CCxxx0_READ_SINGLE));

  // Wait for TX to finish

  while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY  )!= RESET)//线路忙则等待

  {

    ;

  }

  //虚拟的接收数据,用来清空接收寄存器

   x = SPI_I2S_ReceiveData(SPI1);//接收数据通过SPI1

  // Dummy write so we can read data

  SPI_I2S_SendData(SPI1, (uint16_t)0xff);

  // Address is now being TX'ed, with dummy byte waiting in TXBUF...

  while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY  )!= RESET)//线路忙则等待$$$$

  {

    ;

  }

 

  // Dummy byte RX'ed during addr TX now in RXBUF

  // Clear flag//这个在stm32中是硬件清除

  while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY  )!= RESET)//线路忙则等待

  {

    ;

  }

  // Data byte RX'ed during dummy byte write is now in RXBUF

  x = SPI_I2S_ReceiveData(SPI1);//接收数据通过SPI1

  GPIO_WriteBit(TI_CC_CSn_GPIO, TI_CC_CSn_PIN, Bit_SET);     // /CS disable

 

  return x;

}

 

////////////////////////////////////////////////////////////////////////////////

// 程序名 :  void TI_CC_SPIReadBurstReg(char addr, char *buffer, char count)                                        

// 作用 :   从多个寄存器中读数,第一个寄存器地址:'addr',读出的数据存放于'buffer'

//          为起始地址的存储空间,总共读'count'个寄存器。

// 输入参数:char addr :指向的地址

//          char *buffer:存放的存储空间的起始地址

//          char count:要读的寄存器的数量

// 输出参数:无                    

// 说明:   

//

////////////////////////////////////////////////////////////////////////////////

void TI_CC_SPIReadBurstReg(char addr, char *buffer, char count)

{

  char i;

  char x;

 

  GPIO_WriteBit(TI_CC_CSn_GPIO, TI_CC_CSn_PIN, Bit_RESET);     // /CS enable

  // Wait for CCxxxx ready

  while(GPIO_ReadInputDataBit(TI_CC_SPI_USCIA0_GPIO, TI_CC_SPI_USCIA0_SOMI)!= RESET)

    {

      ;

    }

  // Send address

  SPI_I2S_SendData(SPI1, (uint16_t)(addr | TI_CCxxx0_READ_BURST)); 

  // Wait for TXBUF ready

  while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY  )!= RESET)//线路忙则等待

  {

    ;

  }

  //虚拟的接收数据,用来清空接收寄存器

  x = SPI_I2S_ReceiveData(SPI1);//接收数据通过SPI1

 // Dummy write to read 1st data byte

  SPI_I2S_SendData(SPI1, (uint16_t)0xff);//发送数据通过SPI1 

  // Addr byte is now being TX'ed, with dummy byte to follow immediately after

  while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY  )!= RESET)//线路忙则等待

  {

    ;

  }

  x = SPI_I2S_ReceiveData(SPI1);//接收数据通过SPI1

   while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY  )!= RESET)//线路忙则等待

  {

    ;

  }

  // First data byte now in RXBUF

  for (i = 0; i < (count-1); i++)

  {

    //UCA0TXBUF = 0;                          //Initiate next data RX, meanwhile.&$$$$$.

    SPI_I2S_SendData(SPI1, (uint16_t)0);//发送数据通过SPI1 

    // Store data from last data RX

    buffer[i] = SPI_I2S_ReceiveData(SPI1);//接收数据通过SPI1

    while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY  )!= RESET)//线路忙则等待

    {

      ;

    }

     

  }

  // Store last RX byte in buffer

  buffer[count-1]= SPI_I2S_ReceiveData(SPI1);//接收数据通过SPI1

  GPIO_WriteBit(TI_CC_CSn_GPIO, TI_CC_CSn_PIN, Bit_SET);     // CS disable

}

 

////////////////////////////////////////////////////////////////////////////////

// 程序名 :  char TI_CC_SPIReadStatus(char addr)                                        

// 作用 :   从状态寄存器中读数,寄存器地址:'addr'

// 输入参数:char addr :指向的状态寄存器地址        

// 输出参数:char       :状态寄存器的值                  

// 说明:   

//

////////////////////////////////////////////////////////////////////////////////

char TI_CC_SPIReadStatus(char addr)

{

  char x;

 

  GPIO_WriteBit(TI_CC_CSn_GPIO, TI_CC_CSn_PIN, Bit_RESET);     // /CS enable

  //Wait for CCxxxx ready

  while(GPIO_ReadInputDataBit(TI_CC_SPI_USCIA0_GPIO, TI_CC_SPI_USCIA0_SOMI)!= RESET)

  {

    ;

  }

 

  // Send address

  SPI_I2S_SendData(SPI1, (uint16_t)(addr | TI_CCxxx0_READ_BURST));//发送数据通过SPI1 

  while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY  )!= RESET)//线路忙则等待

  {

    ;

  }

  // Dummy write so we can read data 

  x = SPI_I2S_ReceiveData(SPI1);//接收数据通过SPI1

  SPI_I2S_SendData(SPI1, (uint16_t)0xff);//发送数据通过SPI1 

  while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY  )!= RESET)//线路忙则等待

  {

    ;

  }

  // Read data

  x = SPI_I2S_ReceiveData(SPI1);//接收数据通过SPI1

  GPIO_WriteBit(TI_CC_CSn_GPIO, TI_CC_CSn_PIN, Bit_SET);     // CS disable

 

  return x;

}

 

////////////////////////////////////////////////////////////////////////////////

// 程序名 :  void TI_CC_SPIStrobe(char strobe)                                       

// 作用 :  向命令寄存器写数,写入的值'strobe'

// 输入参数:char strobe :要写入的值        

// 输出参数:无

// 说明:   

//

////////////////////////////////////////////////////////////////////////////////

void TI_CC_SPIStrobe(char strobe)

{

  GPIO_WriteBit(TI_CC_CSn_GPIO, TI_CC_CSn_PIN, Bit_RESET);     //CS enable

  // Wait for CCxxxx ready

  while(GPIO_ReadInputDataBit(TI_CC_SPI_USCIA0_GPIO, TI_CC_SPI_USCIA0_SOMI)!= RESET)

    {

      ;

    }

  // Send strobe

  SPI_I2S_SendData(SPI1, (uint16_t)strobe);//发送数据通过SPI1 

  // Strobe addr is now being TX'ed

  while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY  )!= RESET)//线路忙则等待

  {

    ;

  }

  GPIO_WriteBit(TI_CC_CSn_GPIO, TI_CC_CSn_PIN, Bit_SET);     //CS disable

}

 

////////////////////////////////////////////////////////////////////////////////

// 程序名 :  void TI_CC_PowerupResetCCxxxx(void)                                 

// 作用 :  硬复位CC芯片

// 输入参数:无  

// 输出参数:无

// 说明:   

//

////////////////////////////////////////////////////////////////////////////////

void TI_CC_PowerupResetCCxxxx(void)

{

  GPIO_WriteBit(TI_CC_CSn_GPIO, TI_CC_CSn_PIN, Bit_SET);     // CS disable

  TI_CC_Wait(30);

  GPIO_WriteBit(TI_CC_CSn_GPIO, TI_CC_CSn_PIN, Bit_RESET);   //CS enable

  TI_CC_Wait(30);

  GPIO_WriteBit(TI_CC_CSn_GPIO, TI_CC_CSn_PIN, Bit_SET);     //CS disable

  TI_CC_Wait(45);

 

  GPIO_WriteBit(TI_CC_CSn_GPIO, TI_CC_CSn_PIN, Bit_RESET);    //CS enable

  // Wait for CCxxxx ready

  while(GPIO_ReadInputDataBit(TI_CC_SPI_USCIA0_GPIO, TI_CC_SPI_USCIA0_SOMI)!= RESET)

  {

    ;

  }

  // Send strobe

  SPI_I2S_SendData(SPI1, (uint16_t)TI_CCxxx0_SRES);//发送数据通过SPI1 

  // Strobe addr is now being TX'ed

  while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY  )!= RESET)//线路忙则等待

  {

    ;

  }

  // Wait for CCxxxx ready

  while(GPIO_ReadInputDataBit(TI_CC_SPI_USCIA0_GPIO, TI_CC_SPI_USCIA0_SOMI)!= RESET)

  {

    ;

  }

  GPIO_WriteBit(TI_CC_CSn_GPIO, TI_CC_CSn_PIN, Bit_SET);     //CS disable

}

进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

最新器件
精选电路图
  • CCD图像传感器在微光电视系统中的应用

  • 如何利用ESP8266制作一个简单的四轴飞行器

  • 离子检测器电路分析

  • 优化电路板布局的简单方法

  • 一个简单的立体声平衡指示器电路

  • 使用NE555和磁簧开关的橱柜照明电路

    相关电子头条文章