搜索
bottom↓
回复: 12

nRF24L01中的IRQ怎么使用

[复制链接]

出0入0汤圆

发表于 2014-1-10 15:40:50 | 显示全部楼层 |阅读模式
手册要求irq接外部中断,我在写主程序是始终感觉用不到irq,求问大声irq的使用方法,最好给个例子,

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

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2014-1-14 10:50:49 | 显示全部楼层
1. 00寄存器的高4位要设置成0  这样发送 接收 和超时都会引发中断
2. 特别注意的是每次进入中断之前要清除下状态寄存器07
sta=NRF24L01_Read_Reg(STATUS);  //读取状态寄存器的值          
NRF24L01_Write_Reg(NRF24L01_WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中断标志
3.当然调通的前提还要保证收和发的地址 通道 频率都要 相同  建议你用最方便的0通道 一般情况下也够用了
例子就在网上大把代码的基础上改吧   也就不到10来个寄存器弄清楚就可以了

出0入0汤圆

 楼主| 发表于 2014-1-14 22:27:49 | 显示全部楼层
4058665 发表于 2014-1-14 10:50
1. 00寄存器的高4位要设置成0  这样发送 接收 和超时都会引发中断
2. 特别注意的是每次进入中断之前要清除 ...

那么还要对Irq那个接口编写一个低电平触发的中断函数吧!那么中断函数里写啥呢?,还是只要使能了那个外部中断就行了。我还是个初学者,希望能够赐教

出0入0汤圆

发表于 2014-1-16 13:45:15 | 显示全部楼层
里面主要读取下状态寄存器      因为NRF24L01中断了 ,可能会是超时中断   或者 接收数据中断了    或者 发送数据成功了 这3个里面的一种

所以你要区分是哪种      CPU向你扔了水果    你还要区分是苹果  香蕉  还是黄瓜      然后有选择的用吧...

sta = 读取状态寄存器的值
把sta重新写入状态寄存器  来清除NRF的中断标志          //这句必须有的
if(sta ==超时)
{
   //向程序段   发送消息 或者事件     你可以用个flag
}

else if(sta == 接收数据 )
{
.........
}
else if(sta == 发送数据 )
{
.........
}


主循环

while(1)
{
    if(消息 == 收到数据)
    {
       清除标志        读取NRF接收具体的数据       再处理数据
    }
}

最后别忘了 读取好数据要随时清空NRF的接受缓存         还有CPU刚启动初始化的时候也要清空NRF缓存         
大概就这样了     自己慢慢调看       也不是很难          这种结构CPU效率还是蛮高的   

出0入0汤圆

 楼主| 发表于 2014-1-16 18:26:51 | 显示全部楼层
4058665 发表于 2014-1-16 13:45
里面主要读取下状态寄存器      因为NRF24L01中断了 ,可能会是超时中断   或者 接收数据中断了    或者 发 ...

先谢谢啦,我试试看

出0入0汤圆

 楼主| 发表于 2014-1-16 18:52:18 | 显示全部楼层
thy110 发表于 2014-1-16 18:26
先谢谢啦,我试试看

那么这些直接在主函数里写就可以了吧,不用再另外编写中断函数了吧!那个IRQ接的外部中断还要为他编写初始化函数吧,麻烦你解释一下吧,谢谢啦

出0入0汤圆

 楼主| 发表于 2014-1-16 19:10:06 | 显示全部楼层
4058665 发表于 2014-1-16 13:45
里面主要读取下状态寄存器      因为NRF24L01中断了 ,可能会是超时中断   或者 接收数据中断了    或者 发 ...

  我仅仅让他实现一下发送功能,我在主函数里这样写行吗?
还是我要把IF语句写到中断函数里这有两种你帮忙看一下,谢谢啦
一、
while(1)
  {           
              TX_Mode();
                  sta=SPI_Read(STATUS);
                  SPI_RW_Reg(WRITE_REG+STATUS,sta);   
                  
                  if(sta==MAX_RT)
         {
                       PORTB=0xfe;
                       Delayms(10);
                           PORTB=0xff;
                           Delayms(10);
                 }
         else if(sta==TX_DS)
         {
            PORTB=0xfe;
          }
       }           
二、中断函数
void Increase_INT0_Ir(void)
{
if(sta==MAX_RT)
         {
                       PORTB=0xfe;
                       Delayms(10);
                           PORTB=0xff;
                           Delayms(10);
                 }
         else if(sta==TX_DS)
         {
            PORTB=0xfe;
          }
}

主函数

出0入0汤圆

 楼主| 发表于 2014-1-16 19:26:10 | 显示全部楼层
4058665 发表于 2014-1-16 13:45
里面主要读取下状态寄存器      因为NRF24L01中断了 ,可能会是超时中断   或者 接收数据中断了    或者 发 ...

还有帮忙看一下被人写的程序中的那个IRQ为什么这样用,是什么意思,问题有点多麻烦你了

while(KEY == 0 || KEY2 == 0){
IRQ=1;
SPI_RW_Reg(WRITE_REG+STATUS,0xff);
if (KEY == 0) {
tx_buf[4]+=1;
} else if (KEY2 == 0) {
tx_buf[4]-=1;
}
ifnnrf_tx_mode();
while(IRQ);
sta=SPI_Read(STATUS);
SPI_RW_Reg(WRITE_REG+STATUS,0xff);
if(sta&STA_MARK_TX){
if (KEY == 0){
led=0;
Delay100ms();
led=1;
Delay100ms();
} else {
led2=0;
Delay100ms();
led2=1;
Delay100ms();
}
} else {
ifnnrf_CLERN_ALL();
}
lock_key=1;
}  //发送

出0入0汤圆

发表于 2014-1-16 21:04:46 | 显示全部楼层
你的发送频率不要放在while循环里,你想想,单片机的主频随便都有几MHZ啦,一直死循环,是否发送频率太高啦?可以用定时器设置发送频率,你这里的IRQ是单片机与nrf相连的一个引脚吧?如果是引脚,此处的IRQ就是用来:确保数据已经发送成功了(对方已接收)。

出0入0汤圆

发表于 2014-1-17 09:03:54 | 显示全部楼层
NRF的手册最好先好好看一下:
硬件连接   NRF24L01:  主要就分有SPI接口     SPI_CSN使能管脚       NRF_CE使能管教       IRQ管脚
其中SPI_CSN部分用控制用户数据用的      NRF_CE主要用于控制配置NRF24L01模块的内部寄存器           IRQ主要标志芯片状态变化

当你发送一个数据的时候,无非通过2中方式发送   
一种是通过事件方式  也就是比如按了一个按键了,就像程序上红字部分按键后有了个IRQ=1,为了区分我改成了KEY_Down_Flag=1,然后再调用NRF发送
另外一种方式就是定时发送,网上程序一般是while(1){  RF_Send()   ; delay_ms(1000);             }每一秒钟发送一个数据   达到发送的目的
对于发送没有什么好讲的      
如果发送的过程中你需要保证你的数据100%被对方接受了    那发送后你还需要获取NRF的状态来搞清数据有没有被对方接受
定时发送的结构就变为
while(1)
{
    send();
    wihile(1   ||   超时)
    {
        if(IRQ == 0)
        {  
             sta =获取NRF状态
            if(sta  == 发送完成){记录下发送状态  break;}
            .......
        }
        判断下发送状态   超时 了还是 发送完成了        你的处理
        //delay_ms(1000);
    }
   

}

如果发送你想用中断的方式知道系统的发送状态
while(1)
{
     RF_Send();
     while(1 ||超时)
     {
         if(中断里的发送状态 == 发送完成){  break; }
    }
    根据发送的情况进行处理   
    delay_ms(1000)
}

PIN_IRQ
{
  sta = 获取状态
  清除NRF中断状态  
  if(sta == 发送完成)
  {
     中断里的发送状态  = 发送完成
  }
....
}

这种结构可以保证中断占用很短的时间   ,因为本来中断的任务标志状态用的    而具体做什么交给CPU完成

以上只是介绍了思路        代码很多细节没有考虑      
楼主需要1.首先搞清楚系统的程序架构(譬如这个前后台程序)     2.NRF的手册  特别是那不到10个寄存器的配置         3.真正搞清单片机中断与CPU的结合使用,以及中断真正要做的内容
才能玩好这个模块啊

出0入0汤圆

 楼主| 发表于 2014-1-19 17:36:44 | 显示全部楼层
4058665 发表于 2014-1-17 09:03
NRF的手册最好先好好看一下:
硬件连接   NRF24L01:  主要就分有SPI接口     SPI_CSN使能管脚       NRF_CE ...

我用16发送数据,其中如果有数据发送则让一个led灯闪烁,成功了,接着我用k60接收,但是我调试的时候,k60一直接收不到数据怎么办啊

出0入0汤圆

发表于 2014-1-20 13:32:57 | 显示全部楼层
配置的时候需要配置自动应答模式
发送程序中检测到发送完成中断  说明你发送的内容肯定被从机接收到了
否则检测的是超时事件

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-7-23 11:17

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

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