930电子网

 找回密码
 立即注册
艾克姆科技推出最新产品STC32G12K128开发板
查看: 10498|回复: 7

24LE1用通道0、通道1 点对点发送6个字节数据,无线配置参数的代码实现 ,还不能调通

[复制链接]

5

主题

14

帖子

95

积分

注册会员

Rank: 2

积分
95
发表于 2018-9-3 12:03:10 | 显示全部楼层 |阅读模式
本帖最后由 机灵的兔子 于 2018-9-4 09:25 编辑

Tag1: xdata uint8_t  RX_ADDRESS[5]  = {0xE7,0xE7,0xE7,0xE7,0xE7}; // RX address
xdata uint8_t  TX_ADDRESS[5]  = {0xE1,0xE7,0xE7,0xE7,0xE7}; // TX address


void RfCofig(void)
{
  RFCKEN = 1;             //使能时钟
  hal_nrf_close_pipe(HAL_NRF_ALL);         
  hal_nrf_open_pipe(HAL_NRF_PIPE0,0);          // 通道0.         
  hal_nrf_open_pipe(HAL_NRF_PIPE1,0);          // 通道1         
  hal_nrf_set_operation_mode(HAL_NRF_PRX);        // 接收
  hal_nrf_set_rf_channel(48);                    // RF信道:48
  hal_nrf_set_datarate(HAL_NRF_250KBPS);          // RF速率
  hal_nrf_set_output_power(HAL_NRF_0DBM);        //0DB         
  hal_nrf_set_crc_mode(HAL_NRF_CRC_16BIT);      


  hal_nrf_set_address(HAL_NRF_TX,TX_ADDRESS);  //设置发射机地址
  hal_nrf_set_address(HAL_NRF_PIPE0,RX_ADDRESS); //设置通道0接收机地址
  hal_nrf_set_address(HAL_NRF_PIPE1,TX_ADDRESS);  //设置通道1接收机地址   
  hal_nrf_set_rx_payload_width(HAL_NRF_PIPE0, 6);  //设置通道0接收长度
  hal_nrf_set_rx_payload_width(HAL_NRF_PIPE1, 6);   //设置通道0接收长度
  hal_nrf_set_power_mode(HAL_NRF_PWR_UP);            
  RF = 1;        
  EA = 1;                     
        CE_HIGH();  
}

void rf_irq() interrupt INTERRUPT_RFIRQ
{
  uint8_t irq_flags,i;
  irq_flags = hal_nrf_get_clear_irq_flags();  
  if(irq_flags & (1<<HAL_NRF_RX_DR))
  {
    while(!hal_nrf_rx_fifo_empty())
    {
      PipeAndLen = hal_nrf_read_rx_payload(RxPayload);

                  if((PipeAndLen&0xFF) == RX_PAYLOAD_LEN)  
                  {
                             for(i=0;i<(6);i++)ID_BufTmp        = RxPayload;               
                                  RF_Recv_Flag = 1;
                  }
                  hal_nrf_flush_rx();
          }
  }
  if(irq_flags & ((1<<HAL_NRF_TX_DS)))                                 
  {
     radio_busy = false;               
    hal_nrf_flush_tx();                        
  }

  if(irq_flags & ((1<<HAL_NRF_MAX_RT)))                                 
  {
         radio_busy = false;
    hal_nrf_flush_tx();
  }
}

void SendToTag(void)
{
               TxPayload[0] = 0x11;
        TxPayload[1] = 0x11;   
        TxPayload[2] =0x33;  
        TxPayload[3] = 0x44;
        TxPayload[4] = 0x55;        
    TxPayload[5] = 0x66;

CE_LOW();
        hal_nrf_set_operation_mode(HAL_NRF_PTX);   //模式:发送         //一句切换

     hal_nrf_write_tx_payload(TxPayload,6);  
CE_PULSE();                  
   radio_busy = true;   
  while(radio_busy) ;  

hal_nrf_set_operation_mode(HAL_NRF_PRX);   //模式:接收
   CE_HIGH();  
}
*******
main() 里的

  P0DIR = 0xF6;
  P1DIR = 0xFF;               

hal_clk_set_16m_source(HAL_CLK_XOSC16M);   //使用外部16MHz晶振                        
    RfCofig();  
    hal_uart_init(UART_BAUD_9K6);
    while(hal_clk_get_16m_source() != HAL_CLK_XOSC16M) //等待时钟稳定
    ;


        while(1)
  {                  
                if(RF_Recv_Flag  )
          {
            RF_Recv_Flag = 0;           
          for(beep=0;beep<6;beep++)
          hal_uart_putchar(ID_BufTmp[beep]);
        }


                if(S1 == 0)
          {
            delay_ms(10);
            if(S1 == 0)
            {
              D1 = 0;
                    while(S1 == 0);                            // 等待按键释放
                    D1 = 1;
SendToTag();
            }
          }

}

Tag2:

uint8_t  TX_ADDRESS[5]  = {0xE7,0xE7,0xE7,0xE7,0xE7};
uint8_t  RX_ADDRESS[5]  = {0xE1,0xE7,0xE7,0xE7,0xE7};


void RfCofig(void)
{
    RFCKEN = 1;             //使能时钟
        
        hal_nrf_close_pipe(HAL_NRF_ALL); //关所有通道           

        hal_nrf_open_pipe(HAL_NRF_PIPE0,0);           // 开通道0
            hal_nrf_open_pipe(HAL_NRF_PIPE1,0);           // 开通道1

    hal_nrf_set_rf_channel(48);                          // RF信道:48
    hal_nrf_set_datarate(HAL_NRF_250KBPS);            // RF速率
    hal_nrf_set_output_power(HAL_NRF_0DBM);            
    hal_nrf_set_crc_mode(HAL_NRF_CRC_16BIT);   
  hal_nrf_set_address(HAL_NRF_TX,TX_ADDRESS);  //设置发射机地址
     hal_nrf_set_auto_retr(0,1500);               

        hal_nrf_set_operation_mode(HAL_NRF_PRX);        // 接收

   hal_nrf_set_address(HAL_NRF_PIPE0,TX_ADDRESS  );  //设置接收机地址
       hal_nrf_set_address(HAL_NRF_PIPE1,RX_ADDRESS);  //设置接收机地址
      hal_nrf_set_rx_payload_width(HAL_NRF_PIPE0, 6); //设置通道0接收长度
     hal_nrf_set_rx_payload_width(HAL_NRF_PIPE1, 6); //设置通道1接收长度

    hal_nrf_set_power_mode(HAL_NRF_PWR_UP);               
    RF = 1;      
    EA = 1;              
   CE_HIGH();  
}

void rf_irq() interrupt INTERRUPT_RFIRQ
{
  uint8_t  irq_flags;

     uint8_t i;

  irq_flags = hal_nrf_get_clear_irq_flags();  

  if(irq_flags & (1<<HAL_NRF_RX_DR))   
  {
          while(!hal_nrf_rx_fifo_empty())
    {  
                        PipeAndLen = hal_nrf_read_rx_payload(RxPayload);
     
         for(i=0;i<6;i++)ID_BufTmp        = RxPayload;               
                                  RF_Recv_Flag = 1;
    }

  }

  if(irq_flags & ((1<<HAL_NRF_TX_DS)))                        
  {

       hal_uart_putchar(0x22) ;
    radio_busy = false;                        
  }

  if(irq_flags & ((1<<HAL_NRF_MAX_RT)))                        
  {

       hal_uart_putchar(0x33) ;
   radio_busy = false;//
    hal_nrf_flush_tx();
  }
}


void SentDataTest(void)
{
            TxPayload[0] = 0x99;
        TxPayload[1] = 0x88;   
        TxPayload[2] =0x77;   
        TxPayload[3] = 0x66;
        TxPayload[4] = 0x55;        
    TxPayload[5] = 0x44;
CE_LOW();
            hal_nrf_set_operation_mode(HAL_NRF_PTX);   //模式:发送         

     hal_nrf_write_tx_payload(TxPayload,6);  
CE_PULSE();               
   radio_busy = true;   
  while(radio_busy)         ;  

hal_nrf_set_operation_mode(HAL_NRF_PRX);   //模式:接收
   CE_HIGH();  
}



*******
main() 里的

  P0DIR = 0xF6;
  P1DIR = 0xFF;               

hal_clk_set_16m_source(HAL_CLK_XOSC16M);   //使用外部16MHz晶振                        
    RfCofig();  
    hal_uart_init(UART_BAUD_9K6);
    while(hal_clk_get_16m_source() != HAL_CLK_XOSC16M) //等待时钟稳定
    ;


        while(1)
  {                  
                if(RF_Recv_Flag  )
          {
            RF_Recv_Flag = 0;           
          for(beep=0;beep<6;beep++)
          hal_uart_putchar(ID_BufTmp[beep]);
        }


                if(S1 == 0)
          {
            delay_ms(10);
            if(S1 == 0)
            {
              D1 = 0;
                    while(S1 == 0);                            // 等待按键释放
                    D1 = 1;
SentDataTest();
            }
          }

}

需要实现的功能,按键按下对应节点Tag1 或Tag2 ,另一个节点会收到 6个事先定好的字节,并打印到串口显示。
新手,还没能调通,帮看看看,卡了好些天了, 程序调试结果  是 Tag2 按下按键,能正常发数据给Tag1 ,但 T ag2按下按键  Tag1 进入无线接收中断后卡死    ; 程序里,
是无限参数错了?还是  无线的中断函数写错了?







回复

使用道具 举报

52

主题

339

帖子

6487

积分

版主

Rank: 7Rank: 7Rank: 7

积分
6487
发表于 2018-9-6 08:47:07 | 显示全部楼层
机灵的兔子 发表于 2018-9-5 23:46
1:可否具体讲讲  如何 发出读指令后 等几毫秒再读下一个? 是发出读命令后,等收到 应答包后(应答包可 ...

根据你的描述,你采用的是这种“点名”的工作方法。
假设有A  B  C三个TAG,一个READER,当READER想获取TAG A的信息时,发送指令给TAG A,发送完成后,马上进入接收模式,等待接收TAG A的信息,如果10ms内没接收到TAG A的信息,则认为本次“点名”失败,这时候可以接着去“点名”B,或者再次对TAG A“点名”,2次“点名”失败后则认为TAG A异常。
回复 支持 1 反对 0

使用道具 举报

52

主题

339

帖子

6487

积分

版主

Rank: 7Rank: 7Rank: 7

积分
6487
发表于 2018-9-5 08:58:57 | 显示全部楼层
机灵的兔子 发表于 2018-9-4 11:55
1、其实我是后面想把 例程里的有源RFID演示系统的例程做成能双向通信的,单个读取某个或几个标签的 电压 ...

1:通道并不能防止冲突,它只是在逻辑上进行了区分,无线收发时还是在一个信道上。你的应用是READER去读TAG的电压值,你可以发出读命令之后,等待几毫秒,再去读下一个,这本身就避免了无线的冲突,而且芯片硬件上也有自动重发的防冲突机制,对这样的应用,足够了。
2:无线中断中,进行简单的数组保存和校验,没任何问题,但是不要加串口输出之类的函数。
3:中断中不合适放串口输出函数,你可以用指示灯来指示。
你还可以参考提供的例子里面的  双向无线点灯的试验。
回复 支持 1 反对 0

使用道具 举报

52

主题

339

帖子

6487

积分

版主

Rank: 7Rank: 7Rank: 7

积分
6487
发表于 2018-9-4 11:17:11 | 显示全部楼层
无线配置里面看不出来明显的错误,注意一下几个地方:
1:这个点对点的应用里面,没有必要使用2个逻辑通道,在点对点里面没什么意义。
2:无线中断里面数据的读取。
3:无线中断里面尽量减少占用时间,不要使用串口输出函数。
回复 支持 1 反对 0

使用道具 举报

5

主题

14

帖子

95

积分

注册会员

Rank: 2

积分
95
 楼主| 发表于 2018-9-4 11:55:48 | 显示全部楼层
本帖最后由 机灵的兔子 于 2018-9-4 17:18 编辑
强光手电 发表于 2018-9-4 11:17
无线配置里面看不出来明显的错误,注意一下几个地方:
1:这个点对点的应用里面,没有必要使用2个逻辑通道 ...

1、其实我是后面想把 例程里的有源RFID演示系统的例程做成能双向通信的,单个读取某个或几个标签的 电压值,而不是标签们一直发卡号和电压值的数据回来, 用单通道也能够实现吗? 需要考虑加个防冲突机制吗?
2、无线中断里只放了一个for循环缓存无线收到的数据, 校验位的计算我看到例程里也可以放在这个地方计算( 现放一个for 循环缓存无线收到的数据 影响不大吧)现在 最大的一个疑问就是现在tag2的无线中断rf_irq() 跟tag1的无线中断rf_irq()  写得几乎一模一样,Tag1能无线正常接收数据,但Tag2不能无线正常接收数据(现象为,程序卡死,或复位卡死,或打印出一两次不正确的6个字节的数据信息然后卡死。)
3、我放了几句串口输出函数(都是打印一个字节信息(做标记用)的函数语句),是为了方便检查 无线中断都进了那个if语句里,都进了几次,   之前试了几次,感觉没问题就习惯用来调试。
回复 支持 反对

使用道具 举报

5

主题

14

帖子

95

积分

注册会员

Rank: 2

积分
95
 楼主| 发表于 2018-9-5 23:46:31 | 显示全部楼层
本帖最后由 机灵的兔子 于 2018-9-6 12:16 编辑
强光手电 发表于 2018-9-5 08:58
1:通道并不能防止冲突,它只是在逻辑上进行了区分,无线收发时还是在一个信道上。你的应用是READER去读T ...

1:可否具体讲讲  如何 发出读指令后 等几毫秒再读下一个? 是发出读命令后,等收到 应答包后(应答包可以放电压值的信息?),再发读命令读下一个?  是需要发送多次读命令才能保证READE 附近的多个TAG每个才能收到?      

   我想到的是:   READER  无线给多个TAG 发命令(带卡号和读命令的一帧自定义数据,),TAG们收到的这帧数据后,立马跟 自己的卡号对比,校验正确的再返回电压值给READER, 这样可行吗?
回复 支持 反对

使用道具 举报

5

主题

14

帖子

95

积分

注册会员

Rank: 2

积分
95
 楼主| 发表于 2018-9-6 23:28:47 | 显示全部楼层
强光手电 发表于 2018-9-6 08:47
根据你的描述,你采用的是这种“点名”的工作方法。
假设有A  B  C三个TAG,一个READER,当READER想获取 ...

感觉这个点名的方法 当标签多了就慢了,还什么其他好的方法没,
回复 支持 反对

使用道具 举报

52

主题

339

帖子

6487

积分

版主

Rank: 7Rank: 7Rank: 7

积分
6487
发表于 2018-9-7 08:38:26 | 显示全部楼层
机灵的兔子 发表于 2018-9-6 23:28
感觉这个点名的方法 当标签多了就慢了,还什么其他好的方法没,

还可以考虑自动应答的方式,不过这种工作方式很难控制。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|官方淘宝店|930电子网 ( 皖ICP备16000695号-2 )

GMT+8, 2024-4-26 10:47 , Processed in 0.070191 second(s), 22 queries .

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