圣龙扬特-AVR电子

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1189|回复: 2
打印 上一主题 下一主题

NRF24L01收发程序

[复制链接]

4

主题

0

好友

62

积分

初级会员

Rank: 2

UID
488
帖子
9
精华
0
注册时间
2013-8-16
在线时间
2 小时
跳转到指定楼层
楼主
发表于 2013-10-19 10:19:47 |只看该作者 |倒序浏览
本帖最后由 oyt88 于 2013-10-19 10:26 编辑

$regfile = "M8def.dat"
$crystal = 7372800
$baud = 9600
$hwstack = 40
$swstack = 20
$framesize = 40

'=== 过程声明

Declare Sub R_register(byval Command As Byte , Byval C_bytes As Byte)
Declare Sub W_register(byval C_bytes As Byte)

'=== 常量 ===
'定义了nRF24L01中断标志

Const Idle_int = &H00                                      '闲置,没有中断
Const Max_rt = &H10                                        '最多重发中断
Const Tx_ds = &H20                                         'TX数据发送中断
Const Rx_dr = &H40                                         'RX数据接收
'SPI(nRF24L01)命令
Const Read_reg = &H00                                      '定义读命令寄存器
Const Write_reg = &H20                                     '定义写入命令寄存器
Const Rd_rx_pload = &H61                                   '定义接收寄存器地址
Const Wr_tx_pload = &HA0                                   '定义TX发射寄存器地址
Const Flush_tx = &HE1                                      '定义TX寄存器指令
Const Flush_rx = &HE2                                      '定义Rx注册命令
Const Reuse_tx_pl = &HE3                                   '定义重用TX有效命令寄存器
Const Nop_comm = &HFF                                      '不定义操作,可以用来读状态寄存器
'SPI(nRF24L01)寄存器(地址)
Const Config_nrf = &H00                                    '配置寄存器地址
Const En_aa = &H01                                         '使能自动应答
Const En_rxaddr = &H02                                     '启用接收地址寄存器地址 允许
Const Setup_aw = &H03                                      '设置地址宽度,(所有数据通道)
Const Setup_retr = &H04                                    '建立自动重发
Const Rf_ch = &H05                                         '射频信道寄存器地址(设置通道频率)
Const Rf_setup = &H06                                      'RF设置寄存器地址(设置空中速率。发射功率。接收放大增益)
Const Status = &H07                                        '状态寄存器地址 (接收中断。发送完中断。多次重发中断,接收数年据通道号。寄存器满标志)
Const Observe_tx = &H08                                    '发送检测寄存器地址(数据丢包计数,重发计数)
Const Cd = &H09                                            '载波检测寄存器地址
Const Rx_addr_p0 = &H0A                                    '数据通道0接收地址
Const Rx_addr_p1 = &H0B                                    '数据通道1接收地址
Const Rx_addr_p2 = &H0C                                    '数据通道2接收地址
Const Rx_addr_p3 = &H0D                                    '数据通道3接收地址
Const Rx_addr_p4 = &H0E                                    '数据通道4接收地址
Const Rx_addr_p5 = &H0F                                    '数据通道5接收地址
Const Tx_addr = &H10                                       'TX 发送地址寄存器地址
Const Rx_pw_p0 = &H11                                      '接收通道0的有效数据宽度
Const Rx_pw_p1 = &H12                                      '接收通道1的有效数据宽度
Const Rx_pw_p2 = &H13                                      '接收通道2的有效数据宽度
Const Rx_pw_p3 = &H14                                      '接收通道3的有效数据宽度
Const Rx_pw_p4 = &H15                                      '接收通道4的有效数据宽度
Const Rx_pw_p5 = &H16                                      '接收通道5的有效数据宽度
Const Fifo_status = &H17                                   'FIFO状态寄存器的寄存器地址
'Various
Const True = 1
Const False = 0

  Dim D_bytes(33) As Byte , B_bytes(33) As Byte , Data0(32) As Byte       '定义函数类型
  Dim Temp As Byte , Run As Byte , Tudr As Byte
  Dim Packet_count As Byte , Cntr As Byte
  Dim Ok As Bit , W As Word , I As Word
  Run = 1 : Reset Ok

  '=== 硬件配置 ===
Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 4 , Noss = 1
'使用硬件SPI,但SS引脚必须由自我控制
Config Timer0 = Timer , Prescale = 1


   Config Pinc.5 = Output                                   'CE引脚输出
   Config Pinb.2 = Output                                   'SS引脚输出
   Config Pinc.4 = Input                                    'IRQ 引脚输入
   Config Pinc.3 = Input                                    '发射/接收装置_选择

   Ce Alias Portc.5                                         '别名
   Ss Alias Portb.2
   Irq Alias Pinc.4
   Txrx_device Alias Pinc.3

Spiinit                                                     '初始化SPI引脚
   Set Ce                                                   'CE引脚设置高
       Waitms 10                                            '等一会儿直到所有的硬件是稳定的
   Reset Ce                                                 'CE引脚设置低
   Reset Ss                                                 ' SS 引脚设置低 (CSN pin)


If Txrx_device = True Then Goto Main_tx                    '如果txrx_device =真 然后去main_tx (Pinc.3=1发射 Pinc.3=0接收)

'===接收主程序==========================================================================================================================
Main_rx:

  Call R_register(status , 1)                               '读状态寄存器
        Print "Rx_device"                                   '发送到终端"Rx_device"
     Reset Ce                                               'CE引脚设置低访问寄存器
  Gosub Setup_rx                                            '设置为接收nRF24L01
      Waitms 2                                              '在RX之前延迟2毫秒
     Set Ce                                                 '置CE为高电平,NRF2401为接收模式
Do                                                         '主循环接收
   If Irq = 0 Then                                          '等到IRQ中断引脚变低
     Reset Ce                                               'CE置低电平,禁用
   Do                                                       '循环直到所有3个FIFO缓冲区是空的
     Call R_register(rd_rx_pload , 32)                      '读5个字节RX PLOAD寄存器

        Print "PLOAD=" ; Hex(b_bytes(1)) ; Hex(b_bytes(2)) ; Hex(b_bytes(3)) ; Hex(b_bytes(4)) ; Hex(b_bytes(5)) ; Hex(b_bytes(6)) ; Hex(b_bytes(7)) ; Hex(b_bytes(8)) ; Hex(b_bytes(9)) ; Hex(b_bytes(10)) ; Hex(b_bytes(11)) ; Hex(b_bytes(12)) ; Hex(b_bytes(13)) ; Chr(b_bytes(14)) ; B_bytes(15) ; Chr(b_bytes(16)) ; Chr(b_bytes(17)) ; Chr(b_bytes(18)) ; Chr(b_bytes(19)) ; Chr(b_bytes(20))       '打印PLOAD

     Call R_register(fifo_status , 1)                       '读 FIFO寄存器状态
   Loop Until B_bytes(1).0 = True                           '测试或rx_empty位是真,Rx FIFO空
      D_bytes(1) = Write_reg + Status                       '重置rx_dr状态位
      D_bytes(2) = &B01000000                               '写1到rx_dr位复位中断
     Call W_register(2)
      Set Ce                                                '置CE为高电平,接收
       Waitms 2
   End If


Loop
Return

'===发射主程序==========================================================================================================================
Main_tx:

      Print "TX_device"                                     '发送到终端 "TX_device"
      D_bytes(1) = Flush_tx                                 '清tx_fifo缓冲
    Call W_register(1)
      D_bytes(1) = Write_reg + Status                       'IRQ位复位
      D_bytes(2) = &B00110000
    Call W_register(2)
  Do                                                        '主循环发射
     ' Incr Packet_count                                     '发送计数器,仅用于测试
   'If Packet_count > 254 Then Packet_count = 0
      Gosub Setup_tx                                        'nrf240l01 发射设置
         D_bytes(1) = Wr_tx_pload                           '把32字节输入到TX PLOAD缓冲(发射寄存器地址  &HA0  )
         D_bytes(2) = 1                             'Byte 1
         D_bytes(3) = 2                             'Byte 2
         D_bytes(4) = 3                              'Byte 3
         D_bytes(5) = 4                              'Byte 4
         D_bytes(6) = 5      
         D_bytes(7) = 6
         D_bytes(8) = 7         
         D_bytes(9) = 8        
          D_bytes(10) = 9         
          D_bytes(11) =10                           
        D_bytes(12) = 11         
         D_bytes(13) = 12
         D_bytes(14) = 13
         D_bytes(15) = 14
         D_bytes(16) = &HFF
         D_bytes(17) = 78
         D_bytes(18) = 79
         D_bytes(19) = 76
‘。。。。。。。。。。
      Call W_register(33)                                   '写33字节的寄存器
         Waitms 2
      Set Ce                                                '置CE为高电平,发送FIFO缓冲区数据
         Waitms 1                                           '延时一毫秒
      Reset Ce                                              '置CE为高低平
         Waitms 100                                         '一些延迟读取终端上的输出
          W = 0                                             '计数器的时间
    Do

      If Irq = 0 Then
                Call R_register(status , 1)
                Temp = B_bytes(1) And &B01110000            ' IRQ 中断状态字节位

       Select Case Temp                                     'IRQ发生

          Case Max_rt                                       '最多重发中断
               Print "Maximum number of TX retries, Flussing the TX buffer now !"
               D_bytes(1) = Flush_tx                        '清除发送缓冲区
               Call W_register(1)
               D_bytes(1) = Write_reg + Status              '写状态寄存器
               D_bytes(2) = &B00010000                      '明确max_rt中断点
               Call W_register(2)
                 Exit Do

          Case Tx_ds                                        'TX数据发送中断
               Print "Packet " ; Packet_count ; " send and ACK received."
               D_bytes(1) = Write_reg + Status              '写状态寄存器
               D_bytes(2) = &B00100000                      '明确tx_ds中断点
               Call W_register(2)
                 Exit Do

          Case Else                                         '其他的IRQ??
               Print "Other irq " ; Bin(temp)
               D_bytes(1) = Flush_tx                        '清除发送缓冲区
               Call W_register(1)
               D_bytes(1) = Write_reg + Status              '写状态寄存器
               D_bytes(2) = &B00110000                      '明确的max_rt,tx_ds位
               Call W_register(2)

       End Select

      End If

         Waitms 1
                                                   '时间等待IRQ 1ms×100
       Incr W
                                                     'W加一
      If W > 100 Then                                       '等待100ms
         Print "No irq response from RF20L01 within 100ms"
        Exit Do                                             '退出等待循环
      End If

    Loop
       Goto Main_rx
  Loop
Return

'=================================SPI读写子过程 ====================================================
   Sub W_register(byval C_bytes As Byte)                    '写SPI寄存器
      Reset Ss                                              '手动控制SS引脚设置低,
      Spiout D_bytes(1) , C_bytes                           '移出的数据字节通过SPI
      Set Ss                                                'SS置高电平
   End Sub

   Sub R_register(byval Command As Byte , Byval C_bytes As Byte) As Byte       '读SPI寄存器
      Reset Ss                                              '手动控制SS引脚设置低之前,移动/字节
      Spiout Command , 1                                    '第一移出寄存器被读取
      Spiin B_bytes(1) , C_bytes                            '读取的字节从SPI发送到nrf2401
      Set Ss                                                'SS回到高电平
   End Sub

Setup_rx:                                                   '设置接收
    ' D_bytes(1) = Write_reg + Setup_aw                      '设置地址宽度(所有数据通道)
    ' D_bytes(2) = &H01
    'Call W_register(2)
      D_bytes(1) = Write_reg + Rx_addr_p0                   '接收地址pipe0
      D_bytes(2) = &H34
      D_bytes(3) = &H43
      D_bytes(4) = &H10
      D_bytes(5) = &H10
      D_bytes(6) = &H01
   Call W_register(4)                                       '发送6字节的SPI
      D_bytes(1) = Write_reg + En_aa                        '使pipe0自动应答
      D_bytes(2) = &H01
   Call W_register(2)
      D_bytes(1) = Write_reg + En_rxaddr                    '使接收地址pipe0 允许
      D_bytes(2) = &H01
   Call W_register(2)
      D_bytes(1) = Write_reg + Rf_ch                        'Set RF信道
      D_bytes(2) = 40
   Call W_register(2)
      D_bytes(1) = Write_reg + Rx_pw_p0                     '为pipe0 RX PLOAD宽度
      D_bytes(2) = 32                                       'pipe0 RX 数据宽度为32字节
   Call W_register(2)
      D_bytes(1) = Write_reg + Rf_setup                     '设置射频->输出功率为0dBm,2Mbps速率和LNA增益
      D_bytes(2) = &H0F
   Call W_register(2)
      D_bytes(1) = Write_reg + Config_nrf                   '设置程序配置-> PRX = 1(rx_device),pwr_up = 1,2bytes CRC CRC,
      D_bytes(2) = &H0F
   Call W_register(2)
Return

Setup_tx:                                                   '设置发射
     ' D_bytes(1) = Write_reg + Setup_aw                     '设置地址宽度(所有数据通道)
     ' D_bytes(2) = &H01
   ' Call W_register(2)
      D_bytes(1) = Write_reg + Tx_addr                      '发射地址
      D_bytes(2) = &H34
      D_bytes(3) = &H43
      D_bytes(4) = &H10
      D_bytes(5) = &H10
      D_bytes(6) = &H01
   Call W_register(4)
      D_bytes(1) = Write_reg + Rx_addr_p0                   '接收地址pipe0
      D_bytes(2) = &H34
      D_bytes(3) = &H43
      D_bytes(4) = &H10
      D_bytes(5) = &H10
      D_bytes(6) = &H01
   Call W_register(4)
      D_bytes(1) = Write_reg + En_aa                        '使pipe0自动应答
      D_bytes(2) = &H01
   Call W_register(2)
      D_bytes(1) = Write_reg + En_rxaddr                    '接收地址pipe0
      D_bytes(2) = &H01
   Call W_register(2)
      D_bytes(1) = Write_reg + Rf_ch                        '设 RF信道
      D_bytes(2) = 40
   Call W_register(2)
      D_bytes(1) = Write_reg + Rf_setup                     '设置 射频->输出功率为0dBm,2Mbps速率和LNA增益
      D_bytes(2) = &H0F
   Call W_register(2)
      D_bytes(1) = Write_reg + Config_nrf                   '设置配置-> PRX = 0(tx_device),pwr_up = 1,2bytes CRC CRC,
      D_bytes(2) = &H0E
   Call W_register(2)
Return
回复

使用道具 举报

67

主题

4

好友

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

UID
2
帖子
343
精华
0
注册时间
2013-2-20
在线时间
368 小时
沙发
发表于 2013-10-21 09:48:26 |只看该作者
成功了吧,谢谢分享!
回复

使用道具 举报

11

主题

0

好友

3245

积分

版主

Rank: 7Rank: 7Rank: 7

UID
45
帖子
31
精华
0
注册时间
2013-2-27
在线时间
29 小时
板凳
发表于 2013-10-23 20:46:34 |只看该作者
回复

使用道具 举报

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

Archiver|手机版|圣龙扬特-AVR电子 ( 鲁ICP备05022832号 )

GMT+8, 2024-12-22 01:11 , Processed in 0.200209 second(s), 18 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部