搜索
bottom↓
回复: 30

CC1101数据包发送函数

[复制链接]

出0入0汤圆

发表于 2012-7-18 14:29:56 | 显示全部楼层 |阅读模式
本帖最后由 物联小莫 于 2012-7-18 14:34 编辑

如题...
   cc1101用430单片机驱动的,cc1101这些驱动函数是从原来一个项目拷贝过来的。发送代码如下图。

后期测试的时候通过主机读取RSSI信号强度偶尔发现有个从机一直处于TX模式,后来用仿真器调试了半天终于触发了这个BUG,
程序一直卡在了绿色那条语句。P2IN&0X40对应GDO2引脚,我把它配置为0x06. 资料上是:
Asserts when sync word has been sent / received, and de-asserts at the end of the packet. In RX, the pin will de-assert
when the optional address check fails or the RX FIFO overflows. In TX the pin will de-assert if the TX FIFO underflows.  
我把全局中断都关掉了,但是还是有一定概率会卡在这条语句上。有没有人给一些解释呢?
另外,资料里面的assert是否一定代表是由低电平跳到高电平?而deassert代表由高电平跳到低电平?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。

出0入0汤圆

发表于 2014-7-22 15:11:30 | 显示全部楼层
mark下                          

出0入0汤圆

发表于 2014-3-21 16:44:31 | 显示全部楼层
发送和接收数据时被声明

出0入0汤圆

发表于 2013-2-18 13:10:43 | 显示全部楼层
好贴子  关注中。。。

出0入0汤圆

发表于 2013-1-5 10:37:06 | 显示全部楼层
zhouying3129 发表于 2012-12-25 12:29
你好,我的设备A在使用CC1101时从发送转到接收状态后不能收到数据,希望能得到你的一些指点,我的QQ:1851 ...

状态切换成功了吗?
中断转过去了么?

出0入0汤圆

发表于 2012-12-25 12:29:06 | 显示全部楼层
dzymushi 发表于 2012-7-25 21:51
这个得看你接收端数据包是怎么配置的,如果你设置了那两个字节附在数据包后面,应该还是会产生这两个字节 ...

你好,我的设备A在使用CC1101时从发送转到接收状态后不能收到数据,希望能得到你的一些指点,我的QQ:185166322.

出0入0汤圆

发表于 2012-10-12 21:46:03 | 显示全部楼层
MARK !!!!!!

出0入0汤圆

 楼主| 发表于 2012-7-27 20:01:22 | 显示全部楼层
本帖最后由 物联小莫 于 2012-7-27 20:04 编辑
mtbf 发表于 2012-7-27 17:45
1,发送加超时检测
2,不要查询 PIN 寄存器,改成查询 IFG 寄存器。事先设置好IES寄存器。查询之前发送之前 ...


发送现在已经加了超时检测, 我现在改由查询CC1101的状态寄存器了,你说的查询标志位也是一种比较好的办法。感谢你的建议

我现在似乎找到问题的所在了,是因为我关联GDO0脚的中断函数里面+了跳进入RX模式的语句,但是想不通为什么这条语句会导致错误

出0入0汤圆

发表于 2012-7-27 17:45:27 | 显示全部楼层
1,发送加超时检测
2,不要查询 PIN 寄存器,改成查询 IFG 寄存器。事先设置好IES寄存器。查询之前发送之前先清除IFG寄存器。

出0入0汤圆

发表于 2012-7-26 15:50:58 | 显示全部楼层
物联小莫 发表于 2012-7-26 15:30
嗯,是的。我目前速率是2400 比较慢了的,数据包时间间隔足够长的。实在不行,我只能定时用RES给芯片复位 ...

也是FLUSH FIFO,RES这办法

出0入0汤圆

 楼主| 发表于 2012-7-26 15:30:43 | 显示全部楼层
dzymushi 发表于 2012-7-26 14:25
死在发送一般有这么几个解决方法
1、降低速率
2、降低两包数据的时间间隔

嗯,是的。我目前速率是2400 比较慢了的,数据包时间间隔足够长的。实在不行,我只能定时用RES给芯片复位一下了。
那么如果死在RX中呢?该如何解决呢?

出0入0汤圆

发表于 2012-7-26 14:25:31 | 显示全部楼层
物联小莫 发表于 2012-7-26 13:09
死在发送里面了。 我知道它只能复位单片机。从机刚启动的时候,会发一个上电信息包的,我通过while(1)故 ...

死在发送一般有这么几个解决方法
1、降低速率
2、降低两包数据的时间间隔
3、开启TXFIFO溢出中断,如果产生中断,FLUSH一下FIFO.或者干脆一下用RES那个指令复位一下1101,记得校准

出0入0汤圆

 楼主| 发表于 2012-7-26 13:09:04 | 显示全部楼层
dzymushi 发表于 2012-7-26 10:09
你这个发送死了还是接收死了?
WTD是不能复位RF死机的,他只能复位单片机
我是自己读取RSSI的

死在发送里面了。 我知道它只能复位单片机。从机刚启动的时候,会发一个上电信息包的,我通过while(1)故意使单片机复位,每次复位都能收到上电包,说明cc1101是被重新初始化了的。

出0入0汤圆

发表于 2012-7-26 10:09:14 | 显示全部楼层
物联小莫 发表于 2012-7-26 09:21
昨天按照你的建议修改过程序后,今天发现还是不行,心跳包发了一个晚上就死掉,估计还是死在里面了,程序 ...

你这个发送死了还是接收死了?
WTD是不能复位RF死机的,他只能复位单片机
我是自己读取RSSI的
这种做法是可以的。

出0入0汤圆

 楼主| 发表于 2012-7-26 09:21:15 | 显示全部楼层
dzymushi 发表于 2012-7-25 21:51
这个得看你接收端数据包是怎么配置的,如果你设置了那两个字节附在数据包后面,应该还是会产生这两个字节 ...

昨天按照你的建议修改过程序后,今天发现还是不行,心跳包发了一个晚上就死掉,估计还是死在里面了,程序跑不出来,然后看门狗也不会复位,我刚刚试过,故意在txModeOn函数里面加了个while(1),单片机是会重启的。底层驱动我改为下面的函数。同时,在发送心跳包之前,读取RSSI信号强度来作为判断信道是否占用的参考,过程如下:

低功耗下唤醒->进入RX模式->等待1ms->读取RSSI值->然后回到低功耗。  如果判断信道被占用,则在低功耗状态下随机延时一段时间,再重复上述过程。 你觉得这样行吗? 还是用CS CCA比较好?我觉得直接读RSSI比设置CS CCA来得直观



void sendMsg(lockMSG *msg, uint8_t msgType)
{
   _DINT();
   startWDT();
      
   if(msg == NULL)
   {
           return;
   }
   if(msgType == WSN_MSG)
   {
        halRfSendPacket((INT8U *)msg, msg->pktLen);
   }
   
   P2IFG &= ~BIT6;
   _EINT();
}


void halRfSendPacket(INT8U *txBuffer, INT8U size)
{   
    idleModeOn();   
    clearTxFifo();   
    TI_CC_SPIWriteReg(TI_CCxxx0_TXFIFO, size);
    writeBurstReg(TI_CCxxx0_TXFIFO, txBuffer, size);        //写入要发送的数据     
    txModeOn();
    clearTxFifo();
}

void idleModeOn(void)
{
  halSpiStrobe(TI_CCxxx0_SIDLE);
  while(readCCstatus()!= STATE_IDLE);
}

INT8U readCCstatus(void)
{
     INT8U state;
     state=halSpiReadStatus(TI_CCxxx0_MARCSTATE);
     return state;
}

void clearTxFifo(void)
{
  halSpiStrobe(TI_CCxxx0_SFTX);
  while(readCCstatus() != STATE_IDLE);
}

void txModeOn(void)
{
    halSpiStrobe(TI_CCxxx0_STX);  //进入发送模式发送数据
    while(1);
   
    while(readCCstatus() != STATE_IDLE)
    {
        extern INT8U test;
        test=0xbe;
        if(readCCstatus() == STATE_TX_UNDERFLOW)
        {
            halSpiStrobe(TI_CCxxx0_SFTX);            
        }
    }   
   
}


void clearTxFifo(void)
{
  halSpiStrobe(TI_CCxxx0_SFTX);
  while(readCCstatus() != STATE_IDLE);
}

出0入0汤圆

发表于 2012-7-25 21:51:33 | 显示全部楼层
物联小莫 发表于 2012-7-25 16:21
还有一个问题哦!
我接收端开启了APPEND_STATUS,  发送端关闭了CRC校验。 这个时候接收到数据后额外的两 ...

这个得看你接收端数据包是怎么配置的,如果你设置了那两个字节附在数据包后面,应该还是会产生这两个字节的,具体我没试过,去掉CRC不好的,毕竟接受到一包错误的数据,会占用你不少时间处理这个数据包的

出0入0汤圆

 楼主| 发表于 2012-7-25 16:21:42 | 显示全部楼层
dzymushi 发表于 2012-7-25 15:46
不是,重新配置频率,偏偏,误差这些寄存器的时候

还有一个问题哦!
我接收端开启了APPEND_STATUS,  发送端关闭了CRC校验。 这个时候接收到数据后额外的两个字节中的最后一个的CRC位应该是无效的吧?那这个时候它是否是一个固定的值0或者1?

出0入0汤圆

发表于 2012-7-25 15:46:16 | 显示全部楼层
物联小莫 发表于 2012-7-25 15:34
你所说的重新设置radio是不是指idle状态下就该一些配置寄存器?

不是,重新配置频率,偏偏,误差这些寄存器的时候

出0入0汤圆

 楼主| 发表于 2012-7-25 15:34:38 | 显示全部楼层
dzymushi 发表于 2012-7-25 14:52
死机一般的表现是无法产生packetEND这个中断,或者发送不出数据。
我感觉还是由于FIFO溢出或者误操作引起 ...

你所说的重新设置radio是不是指idle状态下就该一些配置寄存器?

出0入0汤圆

 楼主| 发表于 2012-7-25 15:04:32 | 显示全部楼层
dzymushi 发表于 2012-7-25 14:54
低功耗后可以不校准

对了,其实我是有那个检测PKTLEN的语句的,就是这句: if ((halSpiReadStatus(TI_CCxxx0_RXBYTES) & BYTES_IN_RXFIFO))  //如果接的字节数不为0,BYTES_IN_RXFIFO为0x7f

昨晚上测试5台,到今天只有2台正常工作,3台估计是cc1101死机了吧


出0入0汤圆

发表于 2012-7-25 14:54:01 | 显示全部楼层
物联小莫 发表于 2012-7-25 13:47
好的,我马上修改测试下......感谢你的建议,其实程序原来是有这个判断的,我经验不足,觉得没什么用,就 ...

低功耗后可以不校准

出0入0汤圆

发表于 2012-7-25 14:52:30 | 显示全部楼层
物联小莫 发表于 2012-7-25 13:47
好的,我马上修改测试下......感谢你的建议,其实程序原来是有这个判断的,我经验不足,觉得没什么用,就 ...

死机一般的表现是无法产生packetEND这个中断,或者发送不出数据。
我感觉还是由于FIFO溢出或者误操作引起的
你仔细看下这个GDO的含义,是不是有说这个中断也可能是由溢出或者地址检测(ADDR)错误触发?不一定是数据包接收或者发完成
频率校准可以使用默认的4次一校准那个,没有必要每次都校准
校准一般在这几个情况下,最好校准一次,1切换载波频率,2是换通道的时候,3重新设置radio的shi的时候

出0入0汤圆

 楼主| 发表于 2012-7-25 13:47:32 | 显示全部楼层
dzymushi 发表于 2012-7-25 11:12
else
              {
                  //当前处于非wor模式

好的,我马上修改测试下......感谢你的建议,其实程序原来是有这个判断的,我经验不足,觉得没什么用,就删掉了,呵呵。
另外,能不能解释下,cc1101死机的时候是个什么现象?另外,我看资料的时候,关于手动校准频率(滤波命令SCAL),资料上面说:
  This calibration should be done regularly, and must be performed after turning on power and before using a new frequency (or channel).
  turning on power是指cc1101重新上电?是否建议每次从低功耗唤醒以后都使用SCAL命令校准一次频率?还有就是如果packetLength读出来的是0,容易出错,这个是什么原因呢?

出0入0汤圆

发表于 2012-7-25 11:12:52 | 显示全部楼层
物联小莫 发表于 2012-7-25 10:42
首先,非常感谢你的回答,根据你提出的两种可能情况,我进行如下说明。
  你考虑的第一种情况:(我不知 ...

            else
              {
                  //当前处于非wor模式
                  packetLength = halSpiReadReg(TI_CCxxx0_RXFIFO);  //读出第一个字节,此字节为该帧数据长度      
                  halSpiReadBurstReg(TI_CCxxx0_RXFIFO, wsnRxBuf, packetLength);  //读出所有接收到的数据
                  clearRxFifo();
                  prcWsnMsg(wsnRxBuf);
                  rxModeOn();
              }

你在这个位置用断点观察一下packetLength是不是0,如果是0的话,这个时候读取FIFO是可能出错的,我之前也碰到过。
我说的司机是指1101死机。

出0入0汤圆

 楼主| 发表于 2012-7-25 10:42:54 | 显示全部楼层
dzymushi 发表于 2012-7-24 20:19
原因可能是这样的,
1、地址过滤失败产生的这个中断,这时候读取一下RX-BYTE,读出来的应该是0.这个时候你 ...

  首先,非常感谢你的回答,根据你提出的两种可能情况,我进行如下说明。
  你考虑的第一种情况:(我不知道我这么理解对不对,请前辈指正)进入到这个发射函数以后,我关掉了全局中断,并且进入到TX模式,我认为地址滤波只在接收的时候起作用,因此地址滤波失败在非RX模式下是不会发生的,因此GDO0脚也不会有相应的电平。另外你说之后操作RXFIFO会死机,一般是什么原因?是MCU死机还是说CC1101进入到RX_OVERFLOW状态(这时候只能用滤波命令SFRX才能恢复到IDLE模式)或者说是CC1101死机?我认为RXFIFO是队列,队列中如果没有数据读出来的就是0,应该对整个FIFO没有太大影响吧。
  你考虑的第二种情况:RXOFF操作是什么意思?关闭RX模式,回到IDLE模式?另外,触发进入数据处理的中断并不和GDO0脚相联系,我程序里面是与GDO2脚联系(配置为0x01),并且在处理数据的时候,就是你所建议的把RXFIFO里的数据拷贝出来,之后紧接着就执行了SFRX命令。
  GDO0脚与MCU的P26脚相连,在重新开启全局中断前,我刻意清除了中断标志位。另附上我的中断处理函数:


  //PORT2引脚中断
#pragma vector=PORT2_VECTOR
__interrupt void WSNIsr(void)
{
    INT8U packetLength;
    startWDT();
   
    if(P2IFG&BIT7)  //CC1101接收到数据——GDO2引脚
    {        
          //读取WSN数据   
          if ((halSpiReadStatus(TI_CCxxx0_RXBYTES) & BYTES_IN_RXFIFO))  //如果接的字节数不为0,BYTES_IN_RXFIFO为0x7f
          {
              if(SLAVE_WOR == nowAction)
              {
                  //当前cc1101处于wor模式
                  halSpiReadBurstReg(TI_CCxxx0_RXFIFO, wsnRxBuf, PKT_LEN);  //读出所有接收到的数据
                  clearRxFifo();
                  prcWsnMsg(wsnRxBuf);
                  if(SLAVE_WOR == nowAction)
                  {
                      worModeOn();
                  }
                  else
                  {
                      __bic_SR_register_on_exit(LPM3_bits);  //退出低功耗模式
                  }
              }
              else
              {
                  //当前处于非wor模式
                  packetLength = halSpiReadReg(TI_CCxxx0_RXFIFO);  //读出第一个字节,此字节为该帧数据长度      
                  halSpiReadBurstReg(TI_CCxxx0_RXFIFO, wsnRxBuf, packetLength);  //读出所有接收到的数据
                  clearRxFifo();
                  prcWsnMsg(wsnRxBuf);
                  rxModeOn();
              }
          }
      }

      else if(P2IFG&BIT6)  //下降沿触发引起的中断,关联引脚:GDO0  
      {
          if(nowAction == SLAVE_WOR)
          {
             worModeOn();
          }
          else
          {            
             rxModeOn();
          }  
      }
    //P27上升沿触发,当CC1101的RXFIFO >= RXFIFO 阀值时或者 接收状态下数据包末端到达时P27出现上升沿;
    //P26下降沿触发,CC1101发送或接收状态下到达数据包末端时 或 接收状态下地址检测失败或者RXFIFO上溢 或 发送状态下TXFIFO下溢时P26出现下降沿  
    //综上,接收到数据包时P27 和P26同时产生中断请求,因此需要屏蔽掉P26中断;地址检测失败时只有P26产生中断请求,
    //而此程序对CC1101的配置和处理机制是不会使TX/RX FIFO产生溢出。所以加入以下语句防止重复进入中断
    //此外,在发送数据包时要注意把P26中断使能关掉
    P2IFG = 0x00;
    stopWDT();
}

出0入0汤圆

发表于 2012-7-24 20:19:32 | 显示全部楼层
原因可能是这样的,
1、地址过滤失败产生的这个中断,这时候读取一下RX-BYTE,读出来的应该是0.这个时候你操作RXFIFO,是可能死机的,
2、在中断里面做了RXOFF的操作,这样你可能FIFO的最后一字节没有及时更新进来,造成FIFO错乱,
    这个情况的可能比较大,你可以在接受中断里面先把RXFIFO的数据拷出来。退出中断之前将这个FIFO FLUSH掉

出0入0汤圆

 楼主| 发表于 2012-7-22 09:35:23 | 显示全部楼层
eliachen 发表于 2012-7-20 20:27
单片机主频有点低啊,你是用外部晶振还是内部的?

主频使用DCO 1M的,但是我觉得应该够了的。 你觉得1M会对这个有影响吗?用1M主要是为了降低功耗

出0入0汤圆

发表于 2012-7-20 20:27:20 | 显示全部楼层
单片机主频有点低啊,你是用外部晶振还是内部的?

出0入0汤圆

发表于 2012-7-20 10:26:00 | 显示全部楼层
物联小莫 发表于 2012-7-20 08:54
单步试过了,就是这样的。单片机主频是1M的,cc是2400波特率,发一个包是毫秒级别的,我想不通....应该跟得 ...

加个QQ 690185122 交流下 我也有点问题 想不通?690185122

出0入0汤圆

 楼主| 发表于 2012-7-20 08:54:49 | 显示全部楼层
单步试过了,就是这样的。单片机主频是1M的,cc是2400波特率,发一个包是毫秒级别的,我想不通....应该跟得上的。
另外,我后来又式了下,在卡死的那个while语句里面读取cc的状态寄存器,发现它居然处于RX模式,但是实际读取RSSI信号显示它应该处于TX模式的,好奇怪....
后来我驱动改了一下,测了一个晚上了没有发现问题,再测一段时间看看

出0入0汤圆

发表于 2012-7-19 23:38:21 | 显示全部楼层
跟单片机的运行速度有关 你单步试试 我也是这样的 然后加入延时 就可以了
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-10-3 00:46

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表