CC1101接口与STM32

发布者:bemaii最新更新时间:2016-08-01 来源: eefocus关键字:CC1101接口  STM32 手机看文章 扫描二维码
随时随地手机看文章
【目的】

      移植原来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 - armplc - armplc的博客===工控人生===

  

CC1101接口与STM32 - armplc - armplc的博客===工控人生===

 

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


      图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 
      进入休眠状态时,所存储的内容会丢失,特别是第一个字节。 
       
      图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所示。
       
      图3 SPI内部框图

      图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
       
      图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读寄存器时的逻辑波形。
       
      6 启动CC1101时的逻辑波形
        
      图 写配置寄存器时的逻辑波形 
        
      图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
      }

关键字:CC1101接口  STM32 引用地址:CC1101接口与STM32

上一篇:mini2440简单的裸机led流水灯代码
下一篇:ARM7嵌入式系统中Bootloader分析与设计

推荐阅读最新更新时间:2024-03-16 15:02

STM32驱动AS5600磁性旋转位置传感器模块
简介 AS5600 是一款易于编程的磁性旋转位置传感器,具有高分辨率 12 位模拟或 PWM 输出。 这种非接触式系统测量径向磁化轴上磁铁的绝对角度。 该 AS5600 专为非接触式电位计应用而设计,其坚固的设计消除了任何同质外部杂散磁场的影响。 引脚定义 I2C接口 7位设备地址为0x36(二进制表示为0110110) 支持标准模式和快速模式和高速模式 写数据 读数据 从指定的地址开始读数据 驱动程序 注意: 这里首先搞清楚一件事情,AS5600数据手册中给的7位地址(0x36)指的是原始的7位设备地址,而STM32库中指的设备地址为原始7位设备地址左移一位后得到的设备地址. cubeMX配置 标准的I2C
[单片机]
<font color='red'>STM32</font>驱动AS5600磁性旋转位置传感器模块
STM32 DS18B20 代码详解 学习总结
DS18B20是最常用来学习某一个新的开发工具的,程序都是大同小异,主要是要注意时序中的延时要准确,指令要正确,这里记录一下! ------------------第一部分是--------ds18b20.h---------------------- #ifndef __DS18B20_H #define __DS18B20_H #include stm32f10x.h #include bsp_SysTick.h //精确延时函数头文件----参考http://blog.csdn.net/xuxuechen/article/details/40783209这个看一下 #define HIGH 1 #define LOW
[单片机]
<font color='red'>STM32</font> DS18B20 代码详解 学习总结
stm32 Usart 初始化
库文件中给出了初始化stm32 USART 的范例 /** * @brief Fills each USART_InitStruct member with its default value. * @param USART_InitStruct: pointer to a USART_InitTypeDef structure * which will be initialized. * @retval None */ void USART_StructInit(USART_InitTypeDef* USART_InitStruct) { /* USART_InitStruct members
[单片机]
STM32用STLINK烧写外置FLASH遇到的问题
由于项目需要大量的图片字库还有音频文件,所以外挂了NOR flash和NAND flash,需要用到烧写算法STLDR(就是包含几段在SRAM里面运行的代码),调试的时候遇到了几个问题,都是大意造成的,所以写出来记录一下 首先烧写用到PC端软件是STM32 STLINK Utility,在安装目录下附带了一些常用的flash的烧写算法,但没有我用到的那种,所以只能参考ST-LINK Utility UM手册在…\ST-LINK Utility\ExternalLoader目录下的工程模板上修改,修改需要用到对FLASH的初始化、读写、擦除函数,这个要提前调试好,填到对应的函数内就可以了,后面由上位机自己调用 问题来了,主要
[单片机]
stm32局部变量过大,导致栈溢出
在做一个以stm32为主控的项目时发现自己程序中一个机构体里面的数据总是一运行就被改变,刚开始以为是自己不小心在哪个地方用了extern扩展了变量的作用域,重新赋了值, 自己忘记了,后来查找了好久都没有其他地方使用这个结构体变量,于是开始单步调试,结果进入一个函数的时候(里面定义了一个200个数据float型的数组),发现只要定了一个这个数组,这时前文提到的那个结构的值就发生改变,通过在keil软件中的Memory窗口查看结构体的变量可以清楚看到结构体的地址里面的数据在这个时候发生改变, 然后修改,这个局部变量数组的大小,把它改小之后,就没有发生问题。因为局部变量是储存在栈中的,于是猜想,这种问题应该是stm32的栈的内存的溢出造
[单片机]
<font color='red'>stm32</font>局部变量过大,导致栈溢出
【STM库应用】stm32 之 中断按键初始化(注意事项)
之前做终端按键的时候都是只做了一个,没有做多个,昨天在把所有按键都设置成中断模式的时候遇到问题,于是乎还跟一个网上的哥们进行了热议,后来还是我发现了问题!最终把问题给解决了! 我的按键的GPIO连接有点奇葩,他不是连续的,这可能就是竞赛板故意设置的难度吧! 首先管脚初始化: GPIO_InitTypeDef key; RCC- APB2ENR |= ((1 0)|(1 2)|(1 3)); key.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_8; key.GPIO_Mode = GPIO_Mode_IPD; GPIO_Init(GPIOA, &key); key.GPIO
[单片机]
【STM库应用】<font color='red'>stm32</font> 之 中断按键初始化(注意事项)
STM32 USB设计--硬件篇
STM32芯片内部集成了USB外设,大大减轻了USB电路的设计负担,只需设计USB接口电路,就可以实现基于STM32芯片的电路板的USB通信设计。(本文将具体讲述基于STM32F103RBT6芯片的USB设计)本文为硬件篇。 首先,我们来认识一下STM32F103RBT6芯片。 其中USB相关引脚为PA11(D-),PA12(D+)引脚。就是通过这两个引脚实现STM32F103RBT6的USB通讯。 图1 STM32F103RBT6芯片引脚图 其次,我们简单来认识一下USB的构造(以A型公口、B型母口为例) 图2 USB A型公口 图3 USB B型母口 表1 USB接口引脚说明 1 VCC(+
[单片机]
<font color='red'>STM32</font> USB设计--硬件篇
STM32和CC2520的TinyOS移植与驱动分析
引言 无线传感器网络(Wireless Sensor Network,WSN)是一种应用相关的网络。需要对某些操作系统进行移植。本文采用TinyOS作为软件平台,成功移植了Radio、Timer、USART、SPI和General I/O等5个底层模块。测试结果表明,移植的5个底层模块能够正常工作。 1 MCU和无线模块介绍 STM32系列按性能分成两个系列:STM32F103“增强型”系列和STM32F101“基本型”系列,时钟频率达到72 MHz,是同类产品中性能最高的产品。本项目采用芯片STM32F103RBT6。CC2520选用第二代ZigBee/IEEE 802.15.4无线电频率(RF)收发器。 2 Tin
[单片机]
<font color='red'>STM32</font>和CC2520的TinyOS移植与驱动分析
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved