yaojinghui 发表于 2011-12-12 17:55

CC1100不能同时发送与接收

我的CC1100能够单独发送,也能够单独接收,但是在同时发送和接收时,发送的数据到对方就错误了。主控是LM3S9B96+CC1101 SPI口的操作我可以确定没有错误
///////////////////////////////////////////////////////////////////////////////
//文件说明:CC1101操作文件
//
//
//2011.12.06
////////////////////////////////////////////////////////////////////////////////
#include "includes.h"
#include "CC1101.h"

#define CLEAR_SYNC_INT_FLAG()         GPIOPinIntClear(GPIO_PORTH_BASE,GPIO_PIN_7)
#define ENABLE_SYNC_INT()               GPIOPinIntEnable(GPIO_PORTH_BASE, GPIO_PIN_7)
#define DISABLE_SYNC_INT()            GPIOPinIntDisable(GPIO_PORTH_BASE, GPIO_PIN_7)
#define ENTER_CRITICAL_SECTION()      DISABLE_SYNC_INT()
#define EXIT_CRITICAL_SECTION()      ENABLE_SYNC_INT()

unsigned char ReadCC1101Reg(unsigned char addr);
unsigned char LedRcv = 0x00, LedTransmit = 0x00;

void TOGGLE_GLED(void)
{
      SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
      GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_0);
      GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_0, LedRcv);
      LedRcv ^= 0x01;
}
void TOGGLE_YLED(void)
{
      SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
      GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_1);
      GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_1, LedTransmit);
      LedTransmit ^= 0x02;
}
void delay()
{
      unsigned char i = 50, j = 100;

      while(i--)
         while(j--);
}
///////////////////////////////////////////////////////////////////////////////
//
//CC1101所在SPI端口初始化
//
//
///////////////////////////////////////////////////////////////////////////////
void CC1101PortInit(void)
{
      unsigned long ulTemp;
      SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);//使能GPIOA      
      SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);//使能SSI
      SSIDisable(SSI0_BASE);
      GPIOPinTypeSSI(GPIO_PORTA_BASE, (GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5));   
      GPIODirModeSet(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_DIR_MODE_OUT);//配置片选管脚为输出
      GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5, GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD_WPU);
      SSIConfig(SSI0_BASE,SSI_FRF_MOTO_MODE_3, SSI_MODE_MASTER, 400000, 8);//配置SSI
      SSIEnable(SSI0_BASE);//使能SSI      
      while(SSIDataGetNonBlocking(SSI0_BASE, &ulTemp));
}
///////////////////////////////////////////////////////////////////////////////
//CC1101发送允许
//
//
//
///////////////////////////////////////////////////////////////////////////////
void CC1101TE(void)
{
      SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
      GPIOPinTypeGPIOOutput(GPIO_PORTC_BASE, GPIO_PIN_5);
      GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_5, 0x20);
}
//////////////////////////////////////////////////////////////////////////////
//
//CC1101接收允许
//
//////////////////////////////////////////////////////////////////////////////
void CC1101RE(void)
{
      SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
      GPIOPinTypeGPIOOutput(GPIO_PORTC_BASE, GPIO_PIN_5);
      GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_5, 0x00);
}
/////////////////////////////////////////////////////////////////////////////
//
//
//CC1101使能
//
/////////////////////////////////////////////////////////////////////////////
void CC1101Enable(void)
{
      unsigned long ulTemp;
      SSIDisable(SSI0_BASE);                                    
      SSIConfig(SSI0_BASE, SSI_FRF_MOTO_MODE_3, SSI_MODE_MASTER,400000, 8);
      GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_3);
      GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD_WPU);
      GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3, ~GPIO_PIN_3);
      SSIEnable(SSI0_BASE);
      while(SSIDataGetNonBlocking(SSI0_BASE, &ulTemp) != 0)//清除FIFO
      {
      }
}
/////////////////////////////////////////////////////////////////////////////
//
//
//CC1101禁用
//
/////////////////////////////////////////////////////////////////////////////
void CC1101Disable(void)
{
      unsigned long ulTemp;
      while(SSIDataGetNonBlocking(SSI0_BASE, &ulTemp) != 0)//清除FIFO
      {
      }
      SSIDisable(SSI0_BASE);
      GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_3);
      GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_STRENGTH_8MA,GPIO_PIN_TYPE_STD_WPU);
      GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_PIN_3);
}
//////////////////////////////////////////////////////////////////////////////
//
//
//向CC1101所在端口发送一个字节
//
//////////////////////////////////////////////////////////////////////////////
void SendByteToCC1101(unsigned char data)
{
   unsigned long dummy;
   SSIDataPut(SSI0_BASE, data);
   SSIDataGet(SSI0_BASE, &dummy);
}

/////////////////////////////////////////////////////////////////////////////
//
//配置CC1101单个寄存器
//
//
/////////////////////////////////////////////////////////////////////////////
void CC1100_SPI_Write(unsigned char addr, unsigned char data)
{
       volatile unsigned char tmp;
      do
      {
                //delay();
                SendByteToCC1101(addr);
                SendByteToCC1101(data);
                tmp = ReadCC1101Reg(addr);
      }while(tmp != data);
}
////////////////////////////////////////////////////////////////////////////////
//
//向CC1101寄存器发送一个字节
//
//
///////////////////////////////////////////////////////////////////////////////
void WriteByteToCC1101Reg(unsigned char addr, unsigned char data)
{
      SendByteToCC1101(addr);
      SendByteToCC1101(data);
}
//////////////////////////////////////////////////////////////////////////////
//
//
//连续配置CC1101寄存器
//
//////////////////////////////////////////////////////////////////////////////
void WriteCC1101BurstReg(unsigned char addr, unsigned char *buffer, unsigned char count)
{
      SendByteToCC1101(addr | TI_CCxxx0_WRITE_BURST);
      
      for(unsigned char i = 0; i < count; i++)
          SendByteToCC1101(buffer);
}
//////////////////////////////////////////////////////////////////////////////
//
//
//读取CC1101单个寄存器
//
/////////////////////////////////////////////////////////////////////////////
unsigned char ReadCC1101Reg(unsigned char addr)
{
      unsigned long reg;
      
      SendByteToCC1101(addr | TI_CCxxx0_READ_SINGLE);
      SSIDataPut(SSI0_BASE, 0xff);
      
      SSIDataGet(SSI0_BASE, &reg);
      
      return (unsigned char)(reg & 0xff);
}
//////////////////////////////////////////////////////////////////////////////
//
//
//批量读取CC1101的寄存器
//
//////////////////////////////////////////////////////////////////////////////
void ReadCC1101BurstReg(char addr, char *buffer, char count)
{
      
      SendByteToCC1101(addr | TI_CCxxx0_READ_BURST);
       // SSIDataPut(SSI0_BASE, 0xff);
      
      for(unsigned char i = 0; i < count - 1; i++)
      {
            SSIDataPut(SSI0_BASE, 0xff);
            SSIDataGet(SSI0_BASE, (unsigned long *)(buffer + i));
      }
      
      
}
//////////////////////////////////////////////////////////////////////////////
//
//
//读取CC1101的状态寄存器
//
//////////////////////////////////////////////////////////////////////////////
char ReadCC1101Status(unsigned char addr)
{
      unsigned long tmp;
      SendByteToCC1101(addr | READ_BIT | BURST_BIT);
      SSIDataPut(SSI0_BASE, 0xff);
      SSIDataGet(SSI0_BASE, &tmp);
      return (char)(tmp&0xff);
}
//////////////////////////////////////////////////////////////////////////////
//
//复位CC1101
//
//
/////////////////////////////////////////////////////////////////////////////
void ResetCC1101(void)
{
      SendByteToCC1101(TI_CCxxx0_SRES);
      delay();
}
/////////////////////////////////////////////////////////////////////////////
//
//
//关闭CC1101射频接收
//
//
////////////////////////////////////////////////////////////////////////////
void CC1100RxOff(void)
{
      DISABLE_SYNC_INT();
SendByteToCC1101(TI_CCxxx0_SIDLE);
SendByteToCC1101(TI_CCxxx0_SFRX);
      CLEAR_SYNC_INT_FLAG();
}
/////////////////////////////////////////////////////////////////////////////
//
//
//开启CC1101射频接收
//
//
////////////////////////////////////////////////////////////////////////////
void CC1100RxOn(void)
{
      CLEAR_SYNC_INT_FLAG();
SendByteToCC1101(TI_CCxxx0_SRX);
      ENABLE_SYNC_INT();
}
/////////////////////////////////////////////////////////////////////////////
//
//
//配置CC1101的工作方式
//
//
////////////////////////////////////////////////////////////////////////////
void CC1101Config(void)
{
            
         ResetCC1101();
         // Write register settings
            CC1100_SPI_Write(TI_CCxxx0_IOCFG2,   0x04); //0x0b Clear channel assessment
            
            CC1100_SPI_Write(TI_CCxxx0_IOCFG0,   0x06);   // GDO0 output pin config.当同步词汇被送出/收到时声明,在数据包末端时反声明
         
            CC1100_SPI_Write(TI_CCxxx0_PKTLEN,   0x3C);   // Packet length. 60   最大长度255
            //网关不收广播包
            CC1100_SPI_Write(TI_CCxxx0_PKTCTRL1, 0x0F);    // Packet automation control. APPEND_STATUS enabled,RSSI,LQI,CRC,address check,0 and 255 broadcast.
            CC1100_SPI_Write(TI_CCxxx0_PKTCTRL0, 0x05);    // Packet automation control. use FIFO for RX and TX,CRC enabled,Variable length packets
            CC1100_SPI_Write(TI_CCxxx0_ADDR,0x01);    // Device address.    0x00~0xFF
            CC1100_SPI_Write(TI_CCxxx0_CHANNR,   0x14);   // Channel number.    ????
            CC1100_SPI_Write(TI_CCxxx0_FSCTRL1,0x0a);   // Freq synthesizer control. copy from smartrf
            CC1100_SPI_Write(TI_CCxxx0_FSCTRL0,0x00);   // Freq synthesizer control.
            CC1100_SPI_Write(TI_CCxxx0_FREQ2,    0x10);   // Freq control word, high byte???
            CC1100_SPI_Write(TI_CCxxx0_FREQ1,    0xA7);   // Freq control word, mid byte.????
            CC1100_SPI_Write(TI_CCxxx0_FREQ0,    0x62);   // Freq control word, low byte.???
            CC1100_SPI_Write(TI_CCxxx0_MDMCFG4,0x2d);    // 2d Modem configuration.
            CC1100_SPI_Write(TI_CCxxx0_MDMCFG3,0x3b);    // 3b Modem configuration.
            CC1100_SPI_Write(TI_CCxxx0_MDMCFG2,0x73);    // Modem configuration.
            CC1100_SPI_Write(TI_CCxxx0_MDMCFG1,0x22);    // Modem configuration.
            CC1100_SPI_Write(TI_CCxxx0_MDMCFG0,0xF8);    // Modem configuration.
            CC1100_SPI_Write(TI_CCxxx0_DEVIATN,0x00);   // Modem dev (when FSK mod en)
            CC1100_SPI_Write(TI_CCxxx0_MCSM1 ,   0x3C);   // CCA mode, RX after receive and IDLE after send
            CC1100_SPI_Write(TI_CCxxx0_MCSM0 ,   0x18);   //MainRadio Cntrl State Machine
            CC1100_SPI_Write(TI_CCxxx0_FOCCFG,   0x1D);   // Freq Offset Compens. Config
            CC1100_SPI_Write(TI_CCxxx0_BSCFG,    0x1C);   // Bit synchronization config.
            CC1100_SPI_Write(TI_CCxxx0_AGCCTRL2, 0xC7);    // AGC control.
            CC1100_SPI_Write(TI_CCxxx0_AGCCTRL1, 0x10);    // AGC control.
            CC1100_SPI_Write(TI_CCxxx0_AGCCTRL0, 0xB2);    // AGC control.
            CC1100_SPI_Write(TI_CCxxx0_FREND1,   0xB6);   // Front end RX configuration.
            CC1100_SPI_Write(TI_CCxxx0_FREND0,   0x10);   // Front end RX configuration.
            CC1100_SPI_Write(TI_CCxxx0_FSCAL3,   0xEA);   // Frequency synthesizer cal.
            CC1100_SPI_Write(TI_CCxxx0_FSCAL2,   0x0A);   // Frequency synthesizer cal.
            CC1100_SPI_Write(TI_CCxxx0_FSCAL1,   0x00);   // Frequency synthesizer cal.
            CC1100_SPI_Write(TI_CCxxx0_FSCAL0,   0x11);   // Frequency synthesizer cal.
            CC1100_SPI_Write(TI_CCxxx0_FSTEST,   0x59);   // Frequency synthesizer cal.
            CC1100_SPI_Write(TI_CCxxx0_TEST2,    0x88);      // Various test settings.
            CC1100_SPI_Write(TI_CCxxx0_TEST1,    0x31);      // Various test settings.
            CC1100_SPI_Write(TI_CCxxx0_TEST0,    0x0B);   // Various test settings.
                        
            
            SendByteToCC1101( TI_CCxxx0_SIDLE );
   SendByteToCC1101( TI_CCxxx0_SFRX );
   SendByteToCC1101( TI_CCxxx0_SRX );
            
            delay();
            
            ReadCC1101Status(TI_CCxxx0_MARCSTATE);
                        
}
///////////////////////////////////////////////////////////////////////////////
//
//
//CC1101所在GDO0的中断引脚初始化
//
//
///////////////////////////////////////////////////////////////////////////////
void CC1101IntInit(void)
{
       SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH);          // 使能端口
       GPIOPinTypeGPIOInput(GPIO_PORTH_BASE, GPIO_PIN_7);    // 指定pin名称
       GPIOIntTypeSet(GPIO_PORTH_BASE, GPIO_PIN_7, GPIO_FALLING_EDGE); // 低电平中断
       GPIOPinIntEnable(GPIO_PORTH_BASE, GPIO_PIN_7);               // pin中断使能
       IntEnable(INT_GPIOH);                                        // 端口中断使能   参数为端口号!!
       IntMasterEnable();                        
}
/////////////////////////////////////////////////////////////////////////////////
//
//
//计算RSSI码
//
////////////////////////////////////////////////////////////////////////////////
char calculateRssi(unsigned char rawValue)
{
short rssi;
/* The raw value is in 2's complement and in half db steps. Convert it to
* decimal taking into account the offset value.
*/
if(rawValue >= 128)
{
rssi = (short)(rawValue - 256)/2 - RSSI_OFFSET;
}
else
{
rssi = (rawValue/2) - RSSI_OFFSET;
}
/* Restrict this value to least value can be held in an 8 bit signed int */
if(rssi < -128)
{
rssi = -128;
}
return rssi;
}

////////////////////////////////////////////////////////////////////////////////
//
//CC1101收到数据后处理函数
//
////////////////////////////////////////////////////////////////////////////////
void dataIndication(void)
{
      
    char pktLen, bufflen, lenVerify, rxBuffer, status;
      char rssi,lqi,crc;
      
      
      
      bufflen = ReadCC1101Status(TI_CCxxx0_RXBYTES);
do
{
lenVerify = bufflen;
bufflen = ReadCC1101Status(TI_CCxxx0_RXBYTES);
} while (bufflen != lenVerify);
      
      if (bufflen == 0)    //如果接收错误,返回
return;
      
      pktLen = ReadCC1101Reg(TI_CCxxx0_RXFIFO); // Read length byte
      
      
bufflen = (bufflen-3);
      
      if(pktLen == bufflen)
      {
      
                ReadCC1101BurstReg(TI_CCxxx0_RXFIFO, rxBuffer, pktLen);
                ReadCC1101BurstReg(TI_CCxxx0_RXFIFO, status, 2);
               
                rssi = calculateRssi(status);
lqi = status&LQI_SELECT;
                crc = (char)(status&TI_CCxxx0_CRC_OK);
               
                BufferPool *p = (BufferPool *)getBuffer();
               
                for(unsigned char i = 0; i < pktLen; i++)
                {
                        p->data = rxBuffer;
                }
               
                (*p).isFull = 1;
                TOGGLE_YLED();
               
      }
      
      else
      {
                ENTER_CRITICAL_SECTION();
                SendByteToCC1101( TI_CCxxx0_SIDLE );
                SendByteToCC1101( TI_CCxxx0_SFRX );
                SendByteToCC1101( TI_CCxxx0_SRX );
EXIT_CRITICAL_SECTION();
      }
      
      
   
}
/////////////////////////////////////////////////////////////////////////////////
//
//
//CC1101中断服务程序
//
//////////////////////////////////////////////////////////////////////////////////
void CC1101ISR(void)
{
                  
       // dataIndication();
      GPIOPinIntClear(GPIO_PORTH_BASE,GPIO_PIN_7);
}
/////////////////////////////////////////////////////////////////////////////////
//
//
//CC1101发送程序
//
//////////////////////////////////////////////////////////////////////////////////
void SendToCC1101(unsigned char *txBuffer, unsigned char count, unsigned char txType)
{
      unsigned char rxlen;
      CC1100RxOff();
   
      WriteByteToCC1101Reg(TI_CCxxx0_TXFIFO,count);
WriteCC1101BurstReg(TI_CCxxx0_TXFIFO, txBuffer, count); // Write TX data
      
      if (txType == RF_TX_TYPE_FORCED)
{
SendByteToCC1101(TI_CCxxx0_STX);
               
                while(!SSIBusy(SSI0_BASE));
               
                CLEAR_SYNC_INT_FLAG();
}
      else
      {
            WriteByteToCC1101Reg(TI_CCxxx0_IOCFG0,   0x27);
                for(;;)
                {
                        SendByteToCC1101(TI_CCxxx0_SRX); //进入RX,使得CCA值有效
                        
                        delay();
                        
                        CLEAR_SYNC_INT_FLAG();
                        
                        SendByteToCC1101(TI_CCxxx0_STX); //发送
                        
                        delay();
                        
                     
                        
                        break;
                }   
      }
      
      TOGGLE_GLED();
      
      ENTER_CRITICAL_SECTION();
SendByteToCC1101( TI_CCxxx0_SIDLE );
SendByteToCC1101( TI_CCxxx0_SFTX );
EXIT_CRITICAL_SECTION();
      
      WriteByteToCC1101Reg(TI_CCxxx0_IOCFG0,   0x06);
      
      CC1100RxOn();
      
}

xyz769 发表于 2011-12-13 09:00

本来就不能同时发送与接收。你没理解正确。

xaq79 发表于 2011-12-13 09:40

楼上正解

yaojinghui 发表于 2011-12-14 07:51

我现在发现在接收到一包数据以后得至少发三次才能把我要发的数据包发给对方,现在不知道哪里出了问题,请各位高手支点招,谢谢!

chunyang 发表于 2011-12-14 21:50

所有半双工收发一体的RF信道都不可以同时收发,至于4楼的问题,先将收发靠近测试,看是否为信号场强问题,如非,先换晶体以确定是否为频偏问题,排除硬件问题后就说明是你的程序问题了。

yaojinghui 发表于 2011-12-15 07:44

谢谢chunyang,我使用的是深圳芯微的CC1100模块,公司的产品线一直使用的这种模块,只不过以前是用Mega128去控制收发,没有出现过问题,而且SPI总线上的时钟频率可以达到2M,现在产品升级,用了TI的LM3S9B96去控制收发,我是直接将CC1100接到9B96的SPI口的,我就发现一个问题:设置SPI总线的时钟频率在450Kbps以下的时候,CC1100就能够配置正确,当超过这个频率时,配置CC1100就配置不正确,我在配置CC1100控制字的时候,是先配置,然后再读出来,看配置正确了没有,如果配置正确就进行下一个配置字的配置,现在是上了450Kbps后,配置字好像就根本配置不到CC1100的寄存器中。
do
      {
                //delay();
                SendByteToCC1101(addr);
                SendByteToCC1101(data);
                tmp = ReadCC1101Reg(addr);
      }while(tmp != data);
弄了两天了,都不知道问题在哪。

forrest11 发表于 2011-12-15 08:07

用示波器看时序呗,这个很明显是在高频下时序不对嘛。

chunyang 发表于 2011-12-15 22:11

那说明是时序问题,只有正确的时序才能说速度,这个和器件的接口电路设计有关,务必仔细去看器件手册。

yaojinghui 发表于 2011-12-16 08:09

谢谢你,chunyang,我开始以为用硬件SPI做就不用管时序的问题,刚才我试了一下,只有400Kbps附近的速率才可以通信,我用逻辑分析仪看了一下,CS有时时序不太对,我今天再检查一下时序,谢谢你。

chunyang 发表于 2011-12-16 23:38

硬件SPI接口可能存在兼容性问题,必要时用软件模拟,时序可以完美的契合外设。

yaojinghui 发表于 2011-12-19 07:59

10# chunyang
我用的是TI的LM3S9B96,开始就是用的时序模拟,可是用TI的函数库时发现时钟线上只能达到140多K,不能再快了。GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_3, ~GPIO_PIN_3);它的这个函数能够把引脚置高置低,我在用它把时钟线置高置低间不用延时,时钟线的频率才140多K。

yjiamokuai 发表于 2011-12-19 14:04

这个是收发一体半双工的

yaojinghui 发表于 2011-12-22 09:26

谢谢大家,我用模拟时序调试好了。

LZJSH 发表于 2015-6-27 09:10

你好!我想把发送端的RSSI寄存器读出来然后发到接收端,但是从接收端观察的时候,每次都接收到发送端发的4096个值,并且都是一样的,我怎样才能读取一个值呢?还有你下面的这个RSSI函数为什么还加一个值小于128讨论呢?我看TI官方是没有的啊?
char calculateRssi(unsigned char rawValue)
{
short rssi;
/* The raw value is in 2's complement and in half db steps. Convert it to
* decimal taking into account the offset value.
*/
if(rawValue >= 128)
{
rssi = (short)(rawValue - 256)/2 - RSSI_OFFSET;
}
else
{
rssi = (rawValue/2) - RSSI_OFFSET;
}
/* Restrict this value to least value can be held in an 8 bit signed int */
if(rssi < -128)
{
rssi = -128;
}
return rssi;
}
页: [1]
查看完整版本: CC1100不能同时发送与接收