cc1101的详解及单片机程序

发布者:czc天天最新更新时间:2014-12-04 来源: 21ic关键字:cc1101  单片机  程序 手机看文章 扫描二维码
随时随地手机看文章

    1.初始化SPI,MCU各引脚。

    当有数据接收或发送状态声明时,有中断和查询两种方式。GDO0与GDO2引脚输出至MCU引脚,若要用中断则要接至MCU外部中断引脚,查询时则可用GPIO。
 
    2.复位CC1101。
 
    3.初始化CC1101。(写操作时可从SO中读出CC1101状态)
 
    初始化后CC1100为IDLE状态.
   
    4.状态机转换,写/读FIFO数据。
 
    每次写操作时SO返回的值为写操作前的CC1100状态值,具体值见Table20;读状态命令为当前CC1100状态值,具体值见寄存器0X35说明;注意两者区别。
 
快速认识Cc1100
 
    Cc1100可以工作在同步模式下,代价是:MCU自己控制前导码。本系统中,Cc1100将工作在异步模式下。
 
知识点
 
             Head Byte:在 引脚 Cc1100.Csn 有效后,通过SPI总线写入 Cc1100的第一个字节。
 
             Status Byte: 在写入 HeadByte 的同时,MCU 得到 Status Byte。
 
             Burst Bit:在 Head Byte 中的一个 Bit, 有效值=="1",无效值=="0"
 
GDO0:
             GDO0可用作FIFO状态输出,载波感应(CS),时钟输出,GDO0 脚也能用作集成于芯片的模拟温度传感器(未用).配置寄存器为IOCFG0(0X02),现在配置为RX模式下数据状态反应输出.
 
GDO1:
             GDO1与SPI的SO共用引脚,默认状态下为3态,当CSn为低电平时,此引脚SPI的SO功能生效。配置寄存器为IOCFG0(0X01),现在配置为空闲状态下3态,SPI模式下SO.
 
GDO2:
 
             GDO2可用作FIFO状态输出,载波感应(CS),时钟输出,配置寄存器为IOCFG0(0X00),现在配置为载波感应(CS)输出.
 
TXOFF_MODE/RXOFF_MODE:
 
             注意,此配置为在数据包被发送/接收后状态机状态决定位,仅是在发生发送或者接收后动作;当为IDLE时发SRX/STX后状态机不按此配置运行。TX/RX后要校准。
 
功率放大控制(PATABLE):
 
             0X3E为功率写入地址,0X22为为功率配置寄存器。PATABLE 是一个8字节表,定义了8个PA 功率值。这个表从最低位(0)到最高位(7)可读和写,一次一位。一个索引计数器用来控制对这个表的访问。
 
             每读出或写入表中的一个字节,计数器就加 1。当 CSn 为高时,计数值置为最小值。当达到最大值时,计数器由零重新开始计数。
   
             FREND0.PA_POWER(2:0)从8个功率值中选择1个,且振幅为相应数等级。
 
 
异步模式:
             在此模式下,CC1101中的MCU的若干支持机制会停用,包括数据包硬件处理,FIFO 缓冲,数据白化,交错(interleaver)和前向纠错(FEC) ,曼彻斯特编码(Manchester encoding);
 
             MSK不支持异步模式;
 
             PKTCTRL0.PKT_FORMAT == 3 使能异步模式,GDO0为input,GDO0, GDO1或GDO2为output 相应配置位为IOCFG0.GDO0_CFG, IOCFG1.GDO1_CFG IOCFG2.GDO2_CFG;
 
电磁波激活(WOR):
 
             在WOR滤波使用之前RC振荡器必须启用,RC振荡器是 WOR 定时器的时钟源.在WOR下,收到信号后会自动进入RX模式.
 
载波感应(CS)与RSSI:
 
             因此两配置相互有连系,所以一起论述.
 
             RSSI 只能在RX模式下才能有效,作用为对当前信号质量评估,信号质量可从RSSI寄存器读出.RSSI信号强度可从0X34取出.
 
             RSSI(信号强度)计算公式: 注:此为433M下,结果为负数,
 
                                            RSSI_dBm=(RSSI-256)/2-74 (RSSI>=128)
 
                                            RSSI_dBm= (RSSI/2)-74      (RSSI<128)
 
             CS 只在RX模式下才能有效,当信号质量高于设定门限值时,CS状态将会被声明。现在配置为GDO2输出感应状态.
 
             CS门限值由以下4个寄存器决定
 
             ?? AGCCTRL2.MAX_LNA_GAIN 
             ?? AGCCTRL2.MAX_DVGA_GAIN
             ?? AGCCTRL1.CARRIER_SENSE_ABS_THR
             ?? AGCCTRL2.MAGN_TARGET
            
             CS门限值计算公式:     表默认门限值 + (MAGN_TARGET-33) + CARRIER_SENSE_ABS_THR.
 
                                           表默认门限值见table29,table30. 由AGCCTRL2.MAX_LNA_GAIN   AGCCTRL2.MAX_DVGA_GAIN 决定.
 
                                          默认门限值表只给了两个数据速率下的值,其余由自己测.我们对此要求不是太高,可以参考用这个表.
 
                                           CARRIER_SENSE_ABS_THR为对应表中-7~7的值,最后单位为dBm.
 
                                           Example:
 
                                                         在250K下AGCCTRL2.MAX_LNA_GAIN = 00   AGCCTRL2.MAX_DVGA_GAIN = 00 得出表中为-90.5
 
                                                          MAGN_TARGET = 7(42), CARRIER_SENSE_ABS_THR = 1(1)
 
                                                         门限为-90.5 + (42-33) + 1= -82.5dBm           
 
清理信道访问(CCA):

             清理信道访问用来指示当前信号是空闲还是忙。当忙时是否丢弃当前数据,寄存器MCSM1.CCA_MODE决定是否丢弃.默认配置为保留当前寄存器中数据,丢弃下一步要处理数据.
 

数据FIFO:
         

 
             当TX操作时,由MCU控制,溢出时CC1101出错;当RX操作时,读空时CC1101出错
 
             RX FIFO 和 TX FIFO 中的字节数也能分别从状态寄存器 RXBYTES.NUM_RXBYTES和TXBYTES.NUM_TXBYTES 中读出
 
             4 位 FIFOTHR.FIFO_THR 设置用来控制FIFO 门限点
 
             读单字节时,,CSn继续保持低;。突发访问方式允许一地址字节,然后是连续的数据字节,直到通过设置 CSn 为高来断访问
           
             当写操作时,最后一个字节被传送至 SI 脚后, 被 SO脚接收的状态位会表明在 TX FIFO中只有一个字节是空闲,
 
寄存器分类
         
  Configration Registers 共47个,可读,可写

0x00~0x2E
    
  Status Registers 共14个,只读

0x30~0x3D
    
  Command Strobe 共14个,只写

寻址空间:0x30~0x3D

 

14个地址,对相应的地址进行写,

就相当于激活了对应的命令
 本系统是用到的Strobe:

CC1100_STROBE_RESET
CC1100_STROBE_ENTER_RX_MODE
CC1100_STROBE_ENTER_TX_MODE
CC1100_COMMAND_STROBE_SIDLE
CC1100_COMMAND_STROBE_SFRX
  
  TX FIFO 共64个,只写    
  RX FIFO 共64个,只读    
         

 
 
Status(Command)Registers操作:
 
     当地址为0X30~0X3D时
 
     burst为1:对Status Registers的操作
 
                   Status Registers只可读,且只能一次读一个字节,不可写                
     burst为0:对Command Registers操作
 
                 寄存器的访问和一个寄存器的操作一样,但没有数据被传输.写完毕后,CC1100便执行相应操作.
 
 
 
 
     读写FIFO,有两种模式:单字节读写;Burst读写。
         单字节读写时序:
             1 Cc1100.Csn有效。
             2 写入Head Byte。
              3 读、写一个1字节。
             4 Cc1100.Csn无效。
#include
#include
#define  INT8U  unsigned char
#define  INT16U  unsigned int
#define  WRITE_BURST      0x40      //连续写入
#define  READ_SINGLE      0x80      //读
#define  READ_BURST       0xC0      //连续读
#define  BYTES_IN_RXFIFO     0x7F        //接收缓冲区的有效字节数
#define  CRC_OK              0x80       //CRC校验通过位标志
//*******************************************************
sbit  GDO0 =P1^3;
sbit  GDO2 =P3^2;
sbit MISO =P1^6;
sbit MOSI =P1^5;
sbit SCK =P1^7;
sbit CSN =P1^2;
sbit    LED2    =P3^4;
sbit    LED1    =P3^5;
sbit    KEY1    =P3^6;
sbit    KEY2    =P3^7;
//*******************************************************
sbit led3=P2^3;
sbit led2=P2^2;
sbit led1=P2^1;
sbit led0=P2^0;
//**********************************************************
//INT8U PaTabel[8] = {0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60};
INT8U PaTabel[8] = {0xc0 ,0xc0 ,0xc0 ,0xc0 ,0xc0 ,0xc0 ,0xc0 ,0xc0};//修改发射功率
//******************************************************
void SpiInit(void);
void CpuInit(void);
void RESET_CC1100(void);
void POWER_UP_RESET_CC1100(void);
void halSpiWriteReg(INT8U addr, INT8U value);
void halSpiWriteBurstReg(INT8U addr, INT8U *buffer, INT8U count);
void halSpiStrobe(INT8U strobe);
INT8U halSpiReadReg(INT8U addr);
void halSpiReadBurstReg(INT8U addr, INT8U *buffer, INT8U count);
INT8U halSpiReadStatus(INT8U addr);
void halRfWriteRfSettings(void);
void halRfSendPacket(INT8U *txBuffer, INT8U size);
INT8U halRfReceivePacket(INT8U *rxBuffer, INT8U *length);
//******************************************************
// CC1100 STROBE, CONTROL AND STATUS REGSITER
#define CCxxx0_IOCFG2       0x00        // GDO2 output pin configuration
#define CCxxx0_IOCFG1       0x01        // GDO1 output pin configuration
#define CCxxx0_IOCFG0       0x02        // GDO0 output pin configuration
#define CCxxx0_FIFOTHR      0x03        // RX FIFO and TX FIFO thresholds
#define CCxxx0_SYNC1        0x04        // Sync word, high INT8U
#define CCxxx0_SYNC0        0x05        // Sync word, low INT8U
#define CCxxx0_PKTLEN       0x06        // Packet length
#define CCxxx0_PKTCTRL1     0x07        // Packet automation control
#define CCxxx0_PKTCTRL0     0x08        // Packet automation control
#define CCxxx0_ADDR         0x09        // Device address
#define CCxxx0_CHANNR       0x0A        // Channel number
#define CCxxx0_FSCTRL1      0x0B        // Frequency synthesizer control
#define CCxxx0_FSCTRL0      0x0C        // Frequency synthesizer control
#define CCxxx0_FREQ2        0x0D        // Frequency control word, high INT8U
#define CCxxx0_FREQ1        0x0E        // Frequency control word, middle INT8U
#define CCxxx0_FREQ0        0x0F        // Frequency control word, low INT8U
#define CCxxx0_MDMCFG4      0x10        // Modem configuration
#define CCxxx0_MDMCFG3      0x11        // Modem configuration
#define CCxxx0_MDMCFG2      0x12        // Modem configuration
#define CCxxx0_MDMCFG1      0x13        // Modem configuration
#define CCxxx0_MDMCFG0      0x14        // Modem configuration
#define CCxxx0_DEVIATN      0x15        // Modem deviation setting
#define CCxxx0_MCSM2        0x16        // Main Radio Control State Machine configuration
#define CCxxx0_MCSM1        0x17        // Main Radio Control State Machine configuration
#define CCxxx0_MCSM0        0x18        // Main Radio Control State Machine configuration
#define CCxxx0_FOCCFG       0x19        // Frequency Offset Compensation configuration
#define CCxxx0_BSCFG        0x1A        // Bit Synchronization configuration
#define CCxxx0_AGCCTRL2     0x1B        // AGC control
#define CCxxx0_AGCCTRL1     0x1C        // AGC control
#define CCxxx0_AGCCTRL0     0x1D        // AGC control
#define CCxxx0_WOREVT1      0x1E        // High INT8U Event 0 timeout
#define CCxxx0_WOREVT0      0x1F        // Low INT8U Event 0 timeout
#define CCxxx0_WORCTRL      0x20        // Wake On Radio control
#define CCxxx0_FREND1       0x21        // Front end RX configuration
#define CCxxx0_FREND0       0x22        // Front end TX configuration
#define CCxxx0_FSCAL3       0x23        // Frequency synthesizer calibration
#define CCxxx0_FSCAL2       0x24        // Frequency synthesizer calibration
#define CCxxx0_FSCAL1       0x25        // Frequency synthesizer calibration
#define CCxxx0_FSCAL0       0x26        // Frequency synthesizer calibration
#define CCxxx0_RCCTRL1      0x27        // RC oscillator configuration
#define CCxxx0_RCCTRL0      0x28        // RC oscillator configuration
#define CCxxx0_FSTEST       0x29        // Frequency synthesizer calibration control
#define CCxxx0_PTEST        0x2A        // Production test
#define CCxxx0_AGCTEST      0x2B        // AGC test
#define CCxxx0_TEST2        0x2C        // Various test settings
#define CCxxx0_TEST1        0x2D        // Various test settings
#define CCxxx0_TEST0        0x2E        // Various test settings
// Strobe commands
#define CCxxx0_SRES         0x30        // Reset chip.
#define CCxxx0_SFSTXON      0x31        // Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1).
                                        // If in RX/TX: Go to a wait state where only the synthesizer is
                                        // running (for quick RX / TX turnaround).
#define CCxxx0_SXOFF        0x32        // Turn off crystal oscillator.
#define CCxxx0_SCAL         0x33        // Calibrate frequency synthesizer and turn it off
                                        // (enables quick start).
#define CCxxx0_SRX          0x34        // Enable RX. Perform calibration first if coming from IDLE and
                                        // MCSM0.FS_AUTOCAL=1.
#define CCxxx0_STX          0x35        // In IDLE state: Enable TX. Perform calibration first if
                                        // MCSM0.FS_AUTOCAL=1. If in RX state and CCA is enabled:
                                        // Only go to TX if channel is clear.
#define CCxxx0_SIDLE        0x36        // Exit RX / TX, turn off frequency synthesizer and exit
                                        // Wake-On-Radio mode if applicable.
#define CCxxx0_SAFC         0x37        // Perform AFC adjustment of the frequency synthesizer
#define CCxxx0_SWOR         0x38        // Start automatic RX polling sequence (Wake-on-Radio)
#define CCxxx0_SPWD         0x39        // Enter power down mode when CSn goes high.
#define CCxxx0_SFRX         0x3A        // Flush the RX FIFO buffer.
#define CCxxx0_SFTX         0x3B        // Flush the TX FIFO buffer.
#define CCxxx0_SWORRST      0x3C        // Reset real time clock.
#define CCxxx0_SNOP         0x3D        // No operation. May be used to pad strobe commands to two
                                        // INT8Us for simpler software.
#define CCxxx0_PARTNUM      0x30
#define CCxxx0_VERSION      0x31
#define CCxxx0_FREQEST      0x32
#define CCxxx0_LQI          0x33
#define CCxxx0_RSSI         0x34
#define CCxxx0_MARCSTATE    0x35
#define CCxxx0_WORTIME1     0x36
#define CCxxx0_WORTIME0     0x37
#define CCxxx0_PKTSTATUS    0x38
#define CCxxx0_VCO_VC_DAC   0x39
#define CCxxx0_TXBYTES      0x3A
#define CCxxx0_RXBYTES      0x3B
#define CCxxx0_PATABLE      0x3E
#define CCxxx0_TXFIFO       0x3F
#define CCxxx0_RXFIFO       0x3F
// RF_SETTINGS is a data structure which contains all relevant CCxxx0 registers
typedef struct S_RF_SETTINGS
{
    INT8U FSCTRL2;   //自已加的
    INT8U FSCTRL1;   // Frequency synthesizer control.
    INT8U FSCTRL0;   // Frequency synthesizer control.
    INT8U FREQ2;     // Frequency control word, high INT8U.
    INT8U FREQ1;     // Frequency control word, middle INT8U.
    INT8U FREQ0;     // Frequency control word, low INT8U.
    INT8U MDMCFG4;   // Modem configuration.
    INT8U MDMCFG3;   // Modem configuration.
    INT8U MDMCFG2;   // Modem configuration.
    INT8U MDMCFG1;   // Modem configuration.
    INT8U MDMCFG0;   // Modem configuration.
    INT8U CHANNR;    // Channel number.
    INT8U DEVIATN;   // Modem deviation setting (when FSK modulation is enabled).
    INT8U FREND1;    // Front end RX configuration.
    INT8U FREND0;    // Front end RX configuration.
    INT8U MCSM0;     // Main Radio Control State Machine configuration.
    INT8U FOCCFG;    // Frequency Offset Compensation Configuration.
    INT8U BSCFG;     // Bit synchronization Configuration.
    INT8U AGCCTRL2;  // AGC control.
    INT8U AGCCTRL1;  // AGC control.
    INT8U AGCCTRL0;  // AGC control.
    INT8U FSCAL3;    // Frequency synthesizer calibration.
    INT8U FSCAL2;    // Frequency synthesizer calibration.
    INT8U FSCAL1;    // Frequency synthesizer calibration.
    INT8U FSCAL0;    // Frequency synthesizer calibration.
    INT8U FSTEST;    // Frequency synthesizer calibration control
    INT8U TEST2;     // Various test settings.
    INT8U TEST1;     // Various test settings.
    INT8U TEST0;     // Various test settings.
    INT8U IOCFG2;    // GDO2 output pin configuration
    INT8U IOCFG0;    // GDO0 output pin configuration
    INT8U PKTCTRL1;  // Packet automation control.
    INT8U PKTCTRL0;  // Packet automation control.
    INT8U ADDR;      // Device address.
    INT8U PKTLEN;    // Packet length.
} RF_SETTINGS;
/////////////////////////////////////////////////////////////////
const RF_SETTINGS rfSettings =
{
 0x00,
    0x08,   // FSCTRL1   Frequency synthesizer control.
    0x00,   // FSCTRL0   Frequency synthesizer control.
    0x10,   // FREQ2     Frequency control word, high byte.
    0xA7,   // FREQ1     Frequency control word, middle byte.
    0x62,   // FREQ0     Frequency control word, low byte.
  
 0x5B,   // MDMCFG4   Modem configuration.
 //0xf6, // MDMCFG4 chang by allen
    0xF8,   // MDMCFG3   Modem configuration.
 //0x83, // MDMCFG3 chang by allen   data rate = 2.398K
    0x03,   // MDMCFG2   Modem configuration.
    0x22,   // MDMCFG1   Modem configuration.
    0xF8,   // MDMCFG0   Modem configuration.
    0x00,   // CHANNR    Channel number.
    0x47,   // DEVIATN   Modem deviation setting (when FSK modulation is enabled).
    0xB6,   // FREND1    Front end RX configuration.
    0x10,   // FREND0    Front end RX configuration.
    0x18,   // MCSM0     Main Radio Control State Machine configuration.
    0x1D,   // FOCCFG    Frequency Offset Compensation Configuration.
    0x1C,   // BSCFG     Bit synchronization Configuration.
    0xC7,   // AGCCTRL2  AGC control.
    0x00,   // AGCCTRL1  AGC control.
    0xB2,   // AGCCTRL0  AGC control.
    0xEA,   // FSCAL3    Frequency synthesizer calibration.
    0x2A,   // FSCAL2    Frequency synthesizer calibration.
    0x00,   // FSCAL1    Frequency synthesizer calibration.
    0x11,   // FSCAL0    Frequency synthesizer calibration.
    0x59,   // FSTEST    Frequency synthesizer calibration.
    0x81,   // TEST2     Various test settings.
    0x35,   // TEST1     Various test settings.
    0x09,   // TEST0     Various test settings.
    0x0B,   // IOCFG2    GDO2 output pin configuration.
    0x06,   // IOCFG0D   GDO0 output pin configuration. Refer to SmartRF?Studio User Manual for detailed pseudo register explanation.
    0x04,   // PKTCTRL1  Packet automation control.
    //0x05,   // PKTCTRL0  Packet automation control.
 0x01, //PKTCTRL0  crc disable chang by allen at 09.12.24
    0x00,   // ADDR      Device address.
    0x0c    // PKTLEN    Packet length.
}
//********************************************************
//函数名:delay(unsigned int s)
//输入:时间
//输出:无
//功能描述:普通廷时,内部用
//*********************************************************** 
static void delay(unsigned int s)
{
 unsigned int i;
 for(i=0; i for(i=0; i}

void halWait(INT16U timeout) {
    do {
        _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
    } while (--timeout);
}

void SpiInit(void)
{
 CSN=0;
 SCK=0;
 CSN=1;
}
/**********************************************
//函数名:CpuInit()
//输入:无
//输出:无
//功能描述:SPI初始化程
/****************************************************/
void CpuInit(void)
{
 SpiInit();
 delay(5000);
}
 
//*****************************************************
//函数名:SpisendByte(INT8U dat)
//输入:发送的数据
//输出:无
//功能描述:SPI发送一个字
//******************************************************
INT8U SpiTxRxByte(INT8U dat)
{
 INT8U i,temp;
 temp = 0;
 
 SCK = 0;
 for(i=0; i<8; i++)
 {
  if(dat & 0x80)
  {
   MOSI = 1;
  }
  else MOSI = 0;
  dat <<= 1;
  SCK = 1;
  _nop_();
  _nop_();
  temp <<= 1;
  if(MISO)temp++;
  SCK = 0;
  _nop_();
  _nop_();
 }
 return temp;

//********************************************************
//函数名:void RESET_CC1100(void)
//输入:无
//输出:无
//功能描述:复位CC1100
//*******************************************************
void RESET_CC1100(void)
{
 CSN = 0;
 while (MISO);
    SpiTxRxByte(CCxxx0_SRES);   //写入复位命令
 while (MISO);
    CSN = 1;
}
//********************************************************
//函数名:void POWER_UP_RESET_CC1100(void)
//输入:无
//输出:无
//功能描述:上电复位CC1100
//*****************************************************
void POWER_UP_RESET_CC1100(void)
{
 CSN = 1;
 halWait(1);
 CSN = 0;
 halWait(1);
 CSN = 1;
 halWait(41);
 RESET_CC1100();     //复位CC1100
}
//******************************************************
//函数名:void halSpiWriteReg(INT8U addr, INT8U value)
//输入:地址和配置字
//输出:无
//功能描述:SPI写寄存器
//***************************************************
void halSpiWriteReg(INT8U addr, INT8U value)
{
    CSN = 0;
    while (MISO);
    SpiTxRxByte(addr);  //写地址
    SpiTxRxByte(value);  //写入配置
    CSN = 1;
}
//*******************************************************
//函数名:void halSpiWriteBurstReg(INT8U addr, INT8U *buffer, INT8U count)
//输入:地址,写入缓冲区,写入个数
//输出:无
//功能描述:SPI连续写配置寄存器
//*****************************************************
void halSpiWriteBurstReg(INT8U addr, INT8U *buffer, INT8U count)
{
    INT8U i, temp;
 temp = addr | WRITE_BURST;
    CSN = 0;
    while (MISO);
    SpiTxRxByte(temp);
    for (i = 0; i < count; i++)
  {
        SpiTxRxByte(buffer[i]);
    }
    CSN = 1;
}
//*******************************************************
//函数名:void halSpiStrobe(INT8U strobe)
//输入:命令
//输出:无
//功能描述:SPI写命令
//********************************************************
void halSpiStrobe(INT8U strobe)
{
    CSN = 0;
    while (MISO);
    SpiTxRxByte(strobe);  //写入命令
    CSN = 1;
}
 
 
//*******************************************************
//函数名:INT8U halSpiReadReg(INT8U addr)
//输入:地址
//输出:该寄存器的配置字
//功能描述:SPI读寄存器
//*******************************************************
INT8U halSpiReadReg(INT8U addr)
{
 INT8U temp, value;
    temp = addr|READ_SINGLE;//读寄存器命令
 CSN = 0;
 while (MISO);
 SpiTxRxByte(temp);
 value = SpiTxRxByte(0);
 CSN = 1;
 return value;
}

//******************************************************
//函数名:void halSpiReadBurstReg(INT8U addr, INT8U *buffer, INT8U count)
//输入:地址,读出数据后暂存的缓冲区,读出配置个数
//输出:无
//功能描述:SPI连续写配置寄存器
//********************************************************
void halSpiReadBurstReg(INT8U addr, INT8U *buffer, INT8U count)
{
    INT8U i,temp;
 temp = addr | READ_BURST;  //写入要读的配置寄存器地址和读命令
    CSN = 0;
    while (MISO);
 SpiTxRxByte(temp); 
    for (i = 0; i < count; i++)
 {
        buffer[i] = SpiTxRxByte(0);
    }
    CSN = 1;
}

//*******************************************************
//函数名:INT8U halSpiReadReg(INT8U addr)
//输入:地址
//输出:该状态寄存器当前值
//功能描述:SPI读状态寄存器
//*****************************************************
INT8U halSpiReadStatus(INT8U addr)
{
    INT8U value,temp;
 temp = addr | READ_BURST;  //写入要读的状态寄存器的地址同时写入读命令
    CSN = 0;
    while (MISO);
    SpiTxRxByte(temp);
 value = SpiTxRxByte(0);
 CSN = 1;
 return value;
}
//*********************************************************
//函数名:void halRfWriteRfSettings(RF_SETTINGS *pRfSettings)
//输入:无
//输出:无
//功能描述:配置CC1100的寄存器
//********************************************************
void halRfWriteRfSettings(void)
{
 halSpiWriteReg(CCxxx0_FSCTRL0,  rfSettings.FSCTRL2);//自已加的
    // Write register settings
    halSpiWriteReg(CCxxx0_FSCTRL1,  rfSettings.FSCTRL1);
    halSpiWriteReg(CCxxx0_FSCTRL0,  rfSettings.FSCTRL0);
    halSpiWriteReg(CCxxx0_FREQ2,    rfSettings.FREQ2);
    halSpiWriteReg(CCxxx0_FREQ1,    rfSettings.FREQ1);
    halSpiWriteReg(CCxxx0_FREQ0,    rfSettings.FREQ0);
    halSpiWriteReg(CCxxx0_MDMCFG4,  rfSettings.MDMCFG4);
    halSpiWriteReg(CCxxx0_MDMCFG3,  rfSettings.MDMCFG3);
    halSpiWriteReg(CCxxx0_MDMCFG2,  rfSettings.MDMCFG2);
    halSpiWriteReg(CCxxx0_MDMCFG1,  rfSettings.MDMCFG1);
    halSpiWriteReg(CCxxx0_MDMCFG0,  rfSettings.MDMCFG0);
    halSpiWriteReg(CCxxx0_CHANNR,   rfSettings.CHANNR);
    halSpiWriteReg(CCxxx0_DEVIATN,  rfSettings.DEVIATN);
    halSpiWriteReg(CCxxx0_FREND1,   rfSettings.FREND1);
    halSpiWriteReg(CCxxx0_FREND0,   rfSettings.FREND0);
    halSpiWriteReg(CCxxx0_MCSM0 ,   rfSettings.MCSM0 );
    halSpiWriteReg(CCxxx0_FOCCFG,   rfSettings.FOCCFG);
    halSpiWriteReg(CCxxx0_BSCFG,    rfSettings.BSCFG);
    halSpiWriteReg(CCxxx0_AGCCTRL2, rfSettings.AGCCTRL2);
 halSpiWriteReg(CCxxx0_AGCCTRL1, rfSettings.AGCCTRL1);
    halSpiWriteReg(CCxxx0_AGCCTRL0, rfSettings.AGCCTRL0);
    halSpiWriteReg(CCxxx0_FSCAL3,   rfSettings.FSCAL3);
 halSpiWriteReg(CCxxx0_FSCAL2,   rfSettings.FSCAL2);
 halSpiWriteReg(CCxxx0_FSCAL1,   rfSettings.FSCAL1);
    halSpiWriteReg(CCxxx0_FSCAL0,   rfSettings.FSCAL0);
    halSpiWriteReg(CCxxx0_FSTEST,   rfSettings.FSTEST);
    halSpiWriteReg(CCxxx0_TEST2,    rfSettings.TEST2);
    halSpiWriteReg(CCxxx0_TEST1,    rfSettings.TEST1);
    halSpiWriteReg(CCxxx0_TEST0,    rfSettings.TEST0);
    halSpiWriteReg(CCxxx0_IOCFG2,   rfSettings.IOCFG2);
    halSpiWriteReg(CCxxx0_IOCFG0,   rfSettings.IOCFG0);  
    halSpiWriteReg(CCxxx0_PKTCTRL1, rfSettings.PKTCTRL1);
    halSpiWriteReg(CCxxx0_PKTCTRL0, rfSettings.PKTCTRL0);
    halSpiWriteReg(CCxxx0_ADDR,     rfSettings.ADDR);
    halSpiWriteReg(CCxxx0_PKTLEN,   rfSettings.PKTLEN);
}
//*********************************************************
//函数名:void halRfSendPacket(INT8U *txBuffer, INT8U size)
//输入:发送的缓冲区,发送数据个数
//输出:无
//功能描述:CC1100发送一组数据
//********************************************************
void halRfSendPacket(INT8U *txBuffer, INT8U size)
{
 halSpiWriteReg(CCxxx0_TXFIFO, size);
    halSpiWriteBurstReg(CCxxx0_TXFIFO, txBuffer, size); //写入要发送的数据
    halSpiStrobe(CCxxx0_STX);  //进入发送模式发送数据
    // Wait for GDO0 to be set -> sync transmitted
    while (!GDO0);
    // Wait for GDO0 to be cleared -> end of packet
    while (GDO0);
 halSpiStrobe(CCxxx0_SFTX);
 delay(20);
}

void setRxMode(void)
{
    halSpiStrobe(CCxxx0_SRX);  //进入接收状态
}
/*
// Bit masks corresponding to STATE[2:0] in the status byte returned on MISO
#define CCxx00_STATE_BM                 0x70
#define CCxx00_FIFO_BYTES_AVAILABLE_BM  0x0F
#define CCxx00_STATE_TX_BM              0x20
#define CCxx00_STATE_TX_UNDERFLOW_BM    0x70
#define CCxx00_STATE_RX_BM              0x10
#define CCxx00_STATE_RX_OVERFLOW_BM     0x60
#define CCxx00_STATE_IDLE_BM            0x00
static INT8U RfGetRxStatus(void)
{
 INT8U temp, spiRxStatus1,spiRxStatus2;
 INT8U i=4;// 循环测试次数
    temp = CCxxx0_SNOP|READ_SINGLE;//读寄存器命令
 CSN = 0;
 while (MISO);
 SpiTxRxByte(temp);
 spiRxStatus1 = SpiTxRxByte(0);
 do
 {
  SpiTxRxByte(temp);
  spiRxStatus2 = SpiTxRxByte(0);
  if(spiRxStatus1 == spiRxStatus2)
  {
   if( (spiRxStatus1 & CCxx00_STATE_BM) == CCxx00_STATE_RX_OVERFLOW_BM)
   {
               halSpiStrobe(CCxxx0_SFRX);
      return 0;
   }
      return 1;
  }
   spiRxStatus1=spiRxStatus2;
 }
 while(i--);
 CSN = 1;
    return 0;
}
 */
INT8U halRfReceivePacket(INT8U *rxBuffer, INT8U *length)
{
    INT8U status[2];
    INT8U packetLength;
 INT8U i=(*length)*4;  // 具体多少要根据datarate和length来决定
    halSpiStrobe(CCxxx0_SRX);  //进入接收状态
 //delay(5);
    //while (!GDO1);
    //while (GDO1);
 delay(2);
 while (GDO0)
 {
  delay(2);
  --i;
  if(i<1)
     return 0;    
 }
    if ((halSpiReadStatus(CCxxx0_RXBYTES) & BYTES_IN_RXFIFO)) //如果接的字节数不为0
 {
        //LED2 = 0;
  packetLength = halSpiReadReg(CCxxx0_RXFIFO);//读出第一个字节,此字节为该帧数据长度
        //if (packetLength <= *length)   //如果所要的有效数据长度小于等于接收到的数据包的长度
  if(packetLength == 0x08)
  {
            //halSpiReadBurstReg(CCxxx0_RXFIFO, rxBuffer, packetLength); //读出所有接收到的数据
   halSpiReadBurstReg(CCxxx0_RXFIFO, rxBuffer, 8); //读出所有接收到的数据
            *length = packetLength;    //把接收数据长度的修改为当前数据的长度
      
            // Read the 2 appended status bytes (status[0] = RSSI, status[1] = LQI)
            //halSpiReadBurstReg(CCxxx0_RXFIFO, status, 2);  //读出CRC校验位
   halSpiStrobe(CCxxx0_SFRX);  //清洗接收缓冲区
  // delay(2);
  // halSpiStrobe(CCxxx0_SRX);  //进入接收状态
  // delay(20);
   //delay(200);
   return 1;
            //return (status[1] & CRC_OK);   //如果校验成功返回接收成功
        }
   else
  {
            *length = packetLength;
            halSpiStrobe(CCxxx0_SFRX);  //清洗接收缓冲区
  // delay(2);
  // halSpiStrobe(CCxxx0_SRX);  //进入接收状态
  // delay(20);
  // LED2 = 1;
            return 0;
        }
    }
  return 0;
}

void main(void)
{
 unsigned char key1_flag = 0;
 bit key2_flag = 0;
 unsigned int key1_scan_cnt = 400;
 unsigned int key2_scan_cnt = 300;
 INT8U i = 0;
 INT8U leng =0;
 INT8U tf =0;
 INT8U TxBuf[8]={1,2,3,4,5,6,7,8};  // 8字节, 如果需要更长的数据包,请正确设置
 INT8U RxBuf[8]={0};
 CpuInit();
 POWER_UP_RESET_CC1100();
 halRfWriteRfSettings();
 halSpiWriteBurstReg(CCxxx0_PATABLE, PaTabel, 8);
 //halSpiStrobe(CCxxx0_SRX);  //进入接收状态
 //setRxMode();
 while(1)
 {
     //setRxMode();
  delay(10);
     if(KEY1 == 0)
    {
   key1_scan_cnt--;
   if(!key1_scan_cnt)
   {  
    key1_scan_cnt = 300;
    if(key1_flag == 0)//判断按键是否第1次按下
    {
     key1_flag = 1;//按键第1次按下标志位
    }
   }
     }
  else
  {
   key1_scan_cnt = 300;
   if(key1_flag == 1)//判断是否第一次按键动作松开
   {
    led1 = 0;
    led0 = 0;
    key1_flag = 2;
    key1_scan_cnt = 3;
    TxBuf[0] = 0x77;//第1个字节为0x77的数据帧,接收方收到后不需要返回应答
    while(1)
    {       
     halRfSendPacket(TxBuf,8); // Transmit Tx buffer data
     delay(100);   
     if(KEY1 == 0)//检测按键是否第2次按下
     {
      key1_scan_cnt--;
      if(!key1_scan_cnt)
      {
       key1_flag = 3;//按键第2次按下
       key1_scan_cnt = 300;
       led1 = 1;
       led0 = 1;
       break;//当按键再次按下时退出长发状态
      }
     }
     else//没有第2次的按键动作
     {
      key1_scan_cnt = 3;
     }
    }
   }
   else if(key1_flag == 3)//是否为第2次的按键动作松开
   {
    key1_flag = 0;
   }
  }
 
     if(KEY2 == 0)
    {
   key2_scan_cnt--;
   if(!key2_scan_cnt)//确认按键正常按下
   {  
    key2_scan_cnt = 300;   
    key2_flag = 1;//按键第1次按下标志位  
   }
     }
  else
  {
   key2_scan_cnt = 300;
   if(key2_flag)//按键弹起
   {
    LED1 = 0;
    key2_flag = 0;
    delay(1000);
    TxBuf[0] = 0x88;       
    halRfSendPacket(TxBuf,8);// Transmit Tx buffer data   
    LED1 = 1;  
   }
    }
  leng =8; // 预计接受8 bytes
     if(halRfReceivePacket(RxBuf,&leng))
 // if(!GDO0)
  {     
  // leng =8; // 预计接受8 bytes
  // if(halRfReceivePacket(RxBuf,&leng))
   {
    if(RxBuf[0] == 0x77)//接收到的数据不需要返回应答
    {
     LED2 = ~LED2;
    }
    else if(RxBuf[0] == 0x88)//判断接收到的数据是否需要返回应答
    {
     LED2 = 0;//接收数据正确,开接收指示灯
     LED1 = 0;//准备发送应答,开发送指示灯
     delay(1000);
     TxBuf[0] = 0x99;
     halRfSendPacket(TxBuf,8); // Transmit Tx buffer data  返回应答
     LED2 = 1;
     LED1 = 1;
    }
    else if(RxBuf[0] == 0x99)//应答数据
    {
     LED2 = 0;
     delay(1000);
     LED2 = 1;
    }
   }
  }
 }
}

关键字:cc1101  单片机  程序 引用地址:cc1101的详解及单片机程序

上一篇:条形码编码之Code128、EAN128
下一篇:一个故事看懂单片机中的堆栈

推荐阅读最新更新时间:2024-03-16 13:47

单片机端USB接口数据上传程序说明
  将c8051f320单片机内的flash程序区内的数据块:通过usb接口上传到pc端。通过pc端的应用接收软件,将数据块存成hex数据文件。并存放到pc的硬盘中。一次最大的数据块存储量;是4kb.具体的例程演示和操做,可查看320usb单片机开发板使用说明。   1)运行上位机软件、上下位机USB接口连接好,USB初始化后。上位机软件得到下位机的状态回应(设备已准备好),此时,上位机软件对话框(SELECT)中显示1 2 3 4,表示上下位机USB接口初始化完成,握手成功。   此时,单片机端的程序为:调用USB-API函数:USB_cLOCk_start();USB时钟初始化,内部时钟12MHz,USBq全速时钟48MH
[单片机]
可按照脚本分别控制8路PWM函数波形输出程序
详细制作过程: http://www.51hei.com/bbs/dpj-25725-1.html 下面是源代码: #include //#include #define ONE_CYCLE_STEP 255 #ifdef AT89C2051_HEADER_FILE #define PORT P1 //如果使用STC12C2052的话使用P1口作为输出口 #else #define PORT P0 //否则使用P0口输出 #endif #define LED_CNT 4 //定义输出口的端口数1-8 4代表使用0-3口输出 #define SCRIPT_
[单片机]
可按照脚本分别控制8路PWM函数波形输出<font color='red'>程序</font>
基于AVR单片机的负荷缸多路遥控开关编解码实现
负荷缸是船舶电力核心发电机性能的负荷试验必备的重要工装设备,通过负荷试验,可以检验发电机长期工作的性能稳定的情况(静态特性)和对突加突卸负荷的应变能力(动态特性)。 AVR 单片机 " 单片机 具有高性能低价格的优点,在本文中利用 AVR 单片机 " 单片机 对发电机负荷缸的多路远程遥控开关量进行采集监控并进行数字信号编解码,用2芯的电缆取代原来40芯的粗电缆传输控制信号,有效地解决了工作中遇到的问题。    1 问题的提出   我们通过把由发电机供电的通电极板放到负荷缸水电阻中,用充气升降极板和补给水调节水电阻大小的方法控制试验发电机所带负荷的大小,对发电机的性能进行试验。体积庞大的负荷缸一般放置在码头,在船
[单片机]
基于AVR<font color='red'>单片机</font>的负荷缸多路遥控开关编解码实现
DIY 6位数显频率计
1.实验任务   利用AT89S51单片机的T0、T1的定时计数器功能,来完成对输入的信号进行频率计数,计数的频率结果通过8位动态数码管显示出来。要求能够对0-250KHz的信号频率进行准确计数,计数误差不超过±1HZ。 2.电路原理图               图4.31.1 3.系统板上硬件连线 (1).把“单片机系统”区域中的P0.0-P0.7与“动态数码显示”区域中的ABCDEFGH端口用8芯排线连接。 (2).把“单片机系统”区域中的P2.0-P2.7与“动态数码显示”区域中的S1S2S3S4S5S6S7S8端口用8芯排线连接。 (3).把“单片机系统”区域中的P3.4(T0)端子用导线连接到“频率产生器”区域中的W
[单片机]
DIY 6位数显频率计
基于51单片机的温控电机proteus仿真及源程序
温控电机项目特别提醒: 用Proteus软件进行电路仿真时,TLC549和AT89C51的电源引脚均隐藏了,在制作电路板时一定要给TLC549的Pin8接+5V,Pin4接地;AT89C51的的Pin40接+5V,Pin20接地。 单片机温控电机源程序如下: //产生频率为100Hz的PWM #include reg51.h #define uchar unsigned char #define uint unsigned int sbit TLC549_SCLK=P1^5; //定义P1.5引脚位名称为TLC549_SCLK sbit TLC549_SDO=P1^3; //定义P1.3引脚位名称为TLC549_S
[单片机]
基于51<font color='red'>单片机</font>的温控电机proteus仿真及源<font color='red'>程序</font>
单片机典型案例开发(二)
一、宿舍智能报警系统设计方案   摘要:该系统以凌阳公司的16位单片机SPCE061A作为主控制器,通过烟雾传感器与人体热释电红外传感器分别感应烟雾与人体红外信号,通过单片机做出报警动作。本系统设计主要是满足宿舍自动报警的需要,设计的目标是要实现语音报警、时间设定和显示、灯光报警并实现网络报警等功能。   1 设计方案   1.1 主控制器的选择   采用凌阳公司的16位单片机SPCE061A作为主控制器。由于SPCE061A内置有2 KB的SRAM和32 KB的内存FLASH,能满足本系统存储密码及各类数据的要求,且CPU时钟频率高达49.152 MHz,能保证响应的快速性,内置的语音模块更提高了系统人机界面的友好性。
[模拟电子]
<font color='red'>单片机</font>典型案例开发(二)
80C51单片机里的程序是如何运行的
前言 我们想要理解单片机是如何运行程序的,我们首先需要了解单片机的组成,我们这里以80C51单片机为例来理解程序在单片机中是如何运行的。 单片机的组成 8051单片机的内部硬件结构包括: 中央处理器CPU:它是单片机内部的核心部件,决定了单片机的主要功能特性,由运算器和控制器两大部分组成。 存储器:8051单片机在系统结构上采用了哈佛型,将程序和数据分别存放在两个存储器内,一个称为程序存储器,另一个为数据存储器在物理结构上分程序存储器和数据存储器,有四个物理上相互独立的存储空间,即片内ROM和片外ROM,片内RAM和片外RAM。 定时器/计数器(T/C):8051单片机内有两个16位的定时器/计数器,每个T/C既可以设置成计数
[单片机]
80C51<font color='red'>单片机</font>里的<font color='red'>程序</font>是如何运行的
详解80C51单片机的复位电路和时钟电路
复位电路 在80C51中,最常见的复位电路就是下图的上电复位电路。 它能有效地实现上电复位和手动复位。RST引脚高电平有效。 其有效时间应持续24个振荡周期以上才能完成复位操作。若使用6MHz晶振,则需持续4us以上才能完成复位操作。 在通电瞬间,由于RC电路的充电过程,在RST端出现一定宽度的正脉冲,只要正脉冲保持10mS以上,就能使单片机自动复位。 CPU在第二个及其周期内执行内部复位操作,以后每个机器周期重复一次,直至RST端电平变低。 在单片机复位器件,ALE和~PSEN信号都不产生。复位操作将对部分专用寄存器产生影响,复位后,这些内部寄存器的状态发生变化,如下表。 时钟电路 在80C51单片机内有一个高增益的反
[单片机]
详解80C51<font color='red'>单片机</font>的复位电路和时钟电路
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

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