注册 登录
查看: 1032|回复: 10

关于NRF24L01模块改中断的问题

[复制链接]
发表于 2013-7-3 21:44:17 | 显示全部楼层 |阅读模式
看过山外写的零死角玩转STM32,在里面看到无线发射模块NRF24L01在接收端改成用IRQ下降沿触发中断接收,刚好现在制作一个移动小车子想在里面实现自动与手动的自由切换,如果采用查询的方法将导致响应不灵敏以及经常接收不到按键的消息。故想改成在发送端发送一个数据之后,在接收端产生中断来接收信息。可是经过两天的修改,发现在STM32上死活不行,只能在上电的那一下进入中断,后面无论按键怎么按都进不去,希望有做过这方面的朋友帮帮忙,万分感谢。我也将我的代码贴上来给大家看看是不是什么地方弄错了!!
NRF程序:
NRF配置:
#ifndef __NRF24L01_H
#define __NRF24L01_H
#include "stm32f10x.h"
#include "SPI.H"

#define uchar unsigned char

// SPI(nRF24L01) commands
//NRF24L01寄存器操作命令
#define NRF24L01_READ_REG        0x00  //读配置寄存器,低5位为寄存器地址
#define NRF24L01_WRITE_REG       0x20  //写配置寄存器,低5位为寄存器地址
#define RD_RX_PLOAD     0x61  //读RX有效数据,1~32字节
#define WR_TX_PLOAD     0xA0  //写TX有效数据,1~32字节
#define FLUSH_TX        0xE1  //清除TX FIFO寄存器.发射模式下用
#define FLUSH_RX        0xE2  //清除RX FIFO寄存器.接收模式下用
#define REUSE_TX_PL     0xE3  //重新使用上一包数据,CE为高,数据包被不断发送.
#define NOP             0xFF  //空操作,可以用来读状态寄存器  
//SPI(NRF24L01)寄存器地址
#define CONFIG          0x00  //配置寄存器地址;bit0:1接收模式,0发射模式;bit1:电选择;bit2:CRC模式;bit3:CRC使能;
          //bit4:中断MAX_RT(达到最大重发次数中断)使能;bit5:中断TX_DS使能;bit6:中断RX_DR使能
#define EN_AA           0x01  //使能自动应答功能  bit0~5,对应通道0~5
#define EN_RXADDR       0x02  //接收地址允许,bit0~5,对应通道0~5
#define SETUP_AW        0x03  //设置地址宽度(所有数据通道):bit1,0:00,3字节;01,4字节;02,5字节;
#define SETUP_RETR      0x04  //建立自动重发;bit3:0,自动重发计数器;bit7:4,自动重发延时 250*x+86us
#define RF_CH           0x05  //RF通道,bit6:0,工作通道频率;
#define RF_SETUP        0x06  //RF寄存器;bit3:传输速率(0:1Mbps,1:2Mbps);bit2:1,发射功率;bit0:低噪声放大器增益
#define STATUS          0x07  //状态寄存器;bit0:TX FIFO满标志;bit3:1,接收数据通道号(最大:6);bit4,达到最多次重发
          //bit5:数据发送完成中断;bit6:接收数据中断;
#define MAX_TX   0x10  //达到最大发送次数中断
#define TX_OK    0x20  //TX发送完成中断
#define RX_OK    0x40  //接收到数据中断
#define OBSERVE_TX      0x08  //发送检测寄存器,bit7:4,数据包丢失计数器;bit3:0,重发计数器
#define CD              0x09  //载波检测寄存器,bit0,载波检测;
#define RX_ADDR_P0      0x0A  //数据通道0接收地址,最大长度5个字节,低字节在前
#define RX_ADDR_P1      0x0B  //数据通道1接收地址,最大长度5个字节,低字节在前
#define RX_ADDR_P2      0x0C  //数据通道2接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等;
#define RX_ADDR_P3      0x0D  //数据通道3接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等;
#define RX_ADDR_P4      0x0E  //数据通道4接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等;
#define RX_ADDR_P5      0x0F  //数据通道5接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等;
#define TX_ADDR         0x10  //发送地址(低字节在前),ShockBurstTM模式下,RX_ADDR_P0与此地址相等
#define RX_PW_P0        0x11  //接收数据通道0有效数据宽度(1~32字节),设置为0则非法
#define RX_PW_P1        0x12  //接收数据通道1有效数据宽度(1~32字节),设置为0则非法
#define RX_PW_P2        0x13  //接收数据通道2有效数据宽度(1~32字节),设置为0则非法
#define RX_PW_P3        0x14  //接收数据通道3有效数据宽度(1~32字节),设置为0则非法
#define RX_PW_P4        0x15  //接收数据通道4有效数据宽度(1~32字节),设置为0则非法
#define RX_PW_P5        0x16  //接收数据通道5有效数据宽度(1~32字节),设置为0则非法
#define FIFO_STATUS     0x17  //FIFO状态寄存器;bit0,RX FIFO寄存器空标志;bit1,RX FIFO满标志;bit2,3,保留
                              //bit4,TX FIFO空标志;bit5,TX FIFO满标志;bit6,1,循环发送上一数据包.0,不循环;
extern uint8_t NEF24L01_Ready ;  //NRF24L01准备好,0表示没有准备好,0xFF表示准备好
extern uint8_t NEF24L01_TX_Over ; //发送完成标志,0表示发送完成,0xFF表示正在发送
extern uint32_t NEF24L01_MAX_RT_Time, NEF24L01_TX_Time ; //最大次数重发失败的次数,发送数据包的次数

extern uint8_t TX_ADDRESS[]; //发送地址寄存器
extern uint8_t RX_ADDRESS[]; //接收地址寄存器

extern uint8_t rxbuf[]; //发送数据包寄存器
extern uint8_t txbuf[]; //接收数据包寄存器
extern uint8_t status_buf[]; //
//24L01发送接收数据宽度定义
#define TX_ADR_WIDTH    5   //5字节的地址宽度
#define RX_ADR_WIDTH    5   //5字节的地址宽度
#define TX_PLOAD_WIDTH  32  //32字节的用户数据宽度
#define RX_PLOAD_WIDTH  32  //32字节的用户数据宽度
uint8_t NRF24L01_RW(uint8_t byte);
uint8_t NRF24L01_RW_Reg(uint8_t reg, uint8_t value);
uint8_t NRF24L01_Write_Buf(uint8_t reg, uint8_t *pBuf, uint8_t bytes);
uint8_t NRF24L01_Read(uint8_t reg);
uint8_t NRF24L01_Read_Buf(uint8_t reg, uint8_t *pBuf, uint8_t bytes);
void NRF24L01_RX_Mode(void);
void NRF24L01_TX_Mode(void);
void NRF24L01_TxPacket(uint8_t* txbuf);
uint8_t NRF24L01_RxPacket(uint8_t* rxbuf);
u8 RF24L01_Check(void);
void NRF24L01_Config(void);
#endif




回复

使用道具 举报

 楼主| 发表于 2013-7-3 21:44:53 | 显示全部楼层
#include "NRF24L01.h"

#include <string.h>
/**********************************************************************/

#define NRF24L01_CSN_High() GPIO_SetBits(GPIOC,GPIO_Pin_4)  //NRF24L01 CSN高电平
#define NRF24L01_CSN_Low() GPIO_ResetBits(GPIOC,GPIO_Pin_4)  //NRF24L01 CSN低电平

#define NRF24L01_CE_High() GPIO_SetBits(GPIOA,GPIO_Pin_4)  //NRF24L01 CE低电平
#define NRF24L01_CE_Low() GPIO_ResetBits(GPIOA,GPIO_Pin_4)  //NRF24L01 CE低电平

uint8_t TX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //发送地址
uint8_t RX_ADDRESS[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //发送地址


uint8_t rxbuf[TX_PLOAD_WIDTH]; //发送数据包寄存器
uint8_t txbuf[TX_PLOAD_WIDTH]; //接收数据包寄存器
uint8_t status_buf[TX_PLOAD_WIDTH];
uint8_t flag,nrf_baud,_it0,_it1,_it2,_it3,nrf_Pipe,nrf_Pipe_r;
uint8_t NEF24L01_Ready ; //NRF24L01准备好,0表示没有准备好,0xFF表示准备好
uint8_t NEF24L01_TX_Over ; //发送完成标志,0表示发送完成,0xFF表示正在发送
uint32_t NEF24L01_MAX_RT_Time, NEF24L01_TX_Time ; //最大次数重发失败的次数,发送数据包的次数
/********************************************************************************************************
函数名:NEF24L01_Delay_us
输入参数:uint16_t NRF24L01_DelayTime
输出参数:
函数功能:延时约NRF24L01_DelayTime us
*********************************************************************************************************/
void NEF24L01_Delay_us(uint16_t NRF24L01_DelayTime)
{
uint16_t NRF24L01_DelayTime1, NRF24L01_DelayTime2 ;
for(NRF24L01_DelayTime1=0;NRF24L01_DelayTime1<NRF24L01_DelayTime;NRF24L01_DelayTime1++)
  for(NRF24L01_DelayTime2=0;NRF24L01_DelayTime2<50;NRF24L01_DelayTime2++);
}
/********************************************************************************************************
函数名:NRF24L01_Config
输入参数:
输出参数:
函数功能:对NRF24L01进行初始化配置
*********************************************************************************************************/
void NRF24L01_Config(void)
{
/***配置NRF24L01的CSN,CE引脚的GPIO***/
GPIO_InitTypeDef GPIO_InitStructure ;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/***配置NRF24L01用到的SPI***/
SPI1_Config();
/****初始化发送次数、最大重发引起的中断次数、发送完成状态***/
NEF24L01_TX_Time = 0 ;
NEF24L01_MAX_RT_Time = 0 ;
NEF24L01_TX_Over = 0 ;

NEF24L01_Delay_us(100);
NRF24L01_CE_Low();        // 待机
NRF24L01_CSN_High();        // SPI禁止


NRF24L01_RW_Reg(NRF24L01_WRITE_REG + CONFIG, 0x00); //初始化配置寄存器
NRF24L01_RW_Reg(NRF24L01_WRITE_REG + STATUS, 0x70); //清除状态寄存器的中断
}
/********************************************************************************************************
函数名:NRF24L01_RW
输入参数:uint8_t  byte
输出参数:SPI_ReceiveByte(SPI1)
函数功能:写一个字节数据byte到NRF24L01.同时返回读到的数据
*********************************************************************************************************/
uint8_t  NRF24L01_RW(uint8_t  byte)
{
SPI_SendByte(SPI1,byte);                //发送一个字节
return ( SPI_ReceiveByte(SPI1) );  // Return the byte read from the SPI bus
}

/********************************************************************************************************
函数名:NRF24L01_RW_Reg
输入参数:uint8_t reg, uint8_t value
输出参数:status
函数功能:往寄存器reg写入字节数据value,同时返回状态字status
*********************************************************************************************************/
uint8_t  NRF24L01_RW_Reg(uint8_t reg, uint8_t value)
{
  uint8_t status;
  
  NRF24L01_CSN_Low(); // CSN置低,开始传输数据
  status = NRF24L01_RW(reg); // 选择寄存器,同时返回状态字
  NRF24L01_RW(value);   // 然后写数据到该寄存器
  NRF24L01_CSN_High();    // CSN拉高,结束数据传输
  return(status);            // 返回状态寄存器
}


回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-7-3 21:45:13 | 显示全部楼层
/********************************************************************************************************
函数名:NRF24L01_Write_Buf
输入参数:uint8_t reg, uint8_t *pBuf, uint8_t bytes
输出参数:status
函数功能:把起始地址为pBuf寄存器中的数据连续bytes个写入NRF24L01的寄存器reg,同时返回状态字status
*********************************************************************************************************/
uint8_t NRF24L01_Write_Buf(uint8_t reg, uint8_t *pBuf, uint8_t bytes)
{
uint8_t status,i;

   NRF24L01_CSN_Low();                             // CSN置低,开始传输数据
status = NRF24L01_RW(reg);   // 选择寄存器,同时返回状态字
   for(i=0; i<bytes; i++)
    {
  NRF24L01_RW(*pBuf);     // 逐个字节写入nRF24L01
  pBuf++ ;
}
    NRF24L01_CSN_High();                   // CSN拉高,结束数据传输
   return(status);           // 返回状态寄存器
}


/********************************************************************************************************
函数名:NRF24L01_Read
输入参数:uint8_t reg
输出参数:status
函数功能:读NRF24L01的寄存器reg,并返回读到的数据status
*********************************************************************************************************/
unsigned char NRF24L01_Read(uint8_t reg)
{
unsigned char status;
NRF24L01_CSN_Low();                   // CSN置低,开始传输数据
NRF24L01_RW(reg);           // 选择寄存器
status=NRF24L01_RW(0);          // 然后从该寄存器读数据
NRF24L01_CSN_High();               // CSN拉高,结束数据传输
return (status);              // 返回寄存器数据
}

/********************************************************************************************************
函数名:NRF24L01_Read_Buf
输入参数:uint8_t reg, uint8_t *pBuf, uint8_t bytes
输出参数:uint8_t status
函数功能:从NRF24L01的寄存器reg中连续读出bytes个字节数据,并存储到首地址为pBuf的寄存器中
*********************************************************************************************************/
uint8_t NRF24L01_Read_Buf(uint8_t reg, uint8_t *pBuf, uint8_t bytes)
{  
uint8_t status,i;
   NRF24L01_CSN_Low();             // CSN置低,开始传输数据
   status = NRF24L01_RW(reg);  // 选择寄存器,同时返回状态字
   for(i=0; i<bytes; i++)
    {         
  pBuf[i]=NRF24L01_RW(0); // 逐个字节从nRF24L01读出
}
   NRF24L01_CSN_High();                // CSN拉高,结束数据传输
   return(status);         // 返回状态寄存器
}


/********************************************************************************************************
函数名:NRF24L01_RX_Mode
输入参数:无
输出参数:无
函数功能:把NRF24L01设置为接收模式
*********************************************************************************************************/
void NRF24L01_RX_Mode(void)
{
NRF24L01_CE_Low();
NRF24L01_RW_Reg(NRF24L01_WRITE_REG + CONFIG, 0x00);    // NRF24L01断电
NRF24L01_Write_Buf(NRF24L01_WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收地址和数据宽度
NRF24L01_RW_Reg(NRF24L01_WRITE_REG + EN_AA, 0x01);               // 使能接收通道0自动应答
NRF24L01_RW_Reg(NRF24L01_WRITE_REG + EN_RXADDR, 0x01);           // 使能接收通道0
NRF24L01_RW_Reg(NRF24L01_WRITE_REG + RF_CH, 40);                 // 选择射频通道0x40
NRF24L01_RW_Reg(NRF24L01_WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH);  // 接收通道0选择和发送通道相同有效数据宽度
NRF24L01_RW_Reg(NRF24L01_WRITE_REG + RF_SETUP, 0x0F);            // 数据传输率2Mbps,发射功率0dBm,低噪声放大器增益
NRF24L01_RW_Reg(NRF24L01_WRITE_REG + CONFIG, 0x0F);              // CRC使能,16位CRC校验,上电,接收模式
NRF24L01_CE_High();                                          // 拉高CE启动接收设备                                        // 拉高CE启动接收设备
}

/********************************************************************************************************
函数名:NRF24L01_TX_Mode
输入参数:无
输出参数:无
函数功能:把NRF24L01设置为发送模式
*********************************************************************************************************/
void NRF24L01_TX_Mode(void)
{
NRF24L01_CE_Low();
// NRF24L01_RW_Reg(NRF24L01_WRITE_REG + SETUP_AW, 0x03);//0x01);
NRF24L01_RW_Reg(NRF24L01_WRITE_REG + CONFIG, 0x00); // NRF24L01断电
    NRF24L01_Write_Buf(NRF24L01_WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);//写TX节点地址  
    NRF24L01_RW_Reg(NRF24L01_WRITE_REG + EN_AA, 0x01);     //  频道0自动 ACK应答允许
NRF24L01_RW_Reg(NRF24L01_WRITE_REG + EN_RXADDR, 0x01);  //  允许接收地址只有频道0  
NRF24L01_RW_Reg(NRF24L01_WRITE_REG + SETUP_RETR, 0x5F); // 设置自动重发时间和次数:500us + 86us, 10 retrans...
NRF24L01_RW_Reg(NRF24L01_WRITE_REG + RF_CH, 40);        // 设置信道工作为2.4GHZ,收发必须一致
// NRF24L01_RW_Reg(NRF24L01_WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
NRF24L01_RW_Reg(NRF24L01_WRITE_REG + RF_SETUP, 0x0F);     //设置发射速率为2MHZ,发射功率为最大值0dB

NRF24L01_RW_Reg(NRF24L01_WRITE_REG + CONFIG, 0x0E);// CRC使能,16位CRC校验,上电,发送模式

NRF24L01_CE_High();
   }   
/********************************************************************************************************
函数名:NRF24L01_TxPacket
输入参数:uint8_t* txbuf
输出参数:无
函数功能:把首地址为txbuf寄存器中的数据发送出去
*********************************************************************************************************/
void NRF24L01_TxPacket(uint8_t* txbuf)
{
NRF24L01_CE_Low();   //StandBy I模式
NRF24L01_Write_Buf(NRF24L01_WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);//装载接收端地址
NRF24L01_Write_Buf(WR_TX_PLOAD, txbuf, TX_PLOAD_WIDTH);     // 装载数据
// NRF24L01_RW_Reg(NRF24L01_WRITE_REG + CONFIG, 0x0e);      // IRQ收发完成中断响应,16位CRC,主发送
NRF24L01_CE_High();   //置高CE,激发数据发送
NEF24L01_Delay_us(20);
}

/********************************************************************************************************
函数名:NRF24L01_RxPacket
输入参数:uint8_t* rxbuf
输出参数:unsigned char revale
函数功能:读取NRF24L01接收到数据,并存储到首地址为rxbuf寄存器中,返回读取标志位revale
*********************************************************************************************************/
uint8_t NRF24L01_RxPacket(uint8_t* rxbuf)
{
   unsigned char revale=0;
   uint8_t status;
   status=NRF24L01_Read(STATUS); // 读取状态寄存其来判断数据接收状况
NRF24L01_RW_Reg(NRF24L01_WRITE_REG+STATUS, status);   //接收到数据后RX_DR,TX_DS,MAX_RT都置高为1,通过写1来清楚中断标志
if(status & 0x40)    // 判断是否接收到数据
{
//      NRF24L01_CE_Low();    //SPI使能
   NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
   NRF24L01_RW_Reg(FLUSH_RX,0xff);      //清除RX FIFO寄存器
   revale =1;   //读取数据完成标志  
}

return revale;
}
u8 RF24L01_Check(void)
{
u8 buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5};
u8 i;
// SPIx_SetSpeed(SPI_SPEED_8); //spi速度为9Mhz(24L01的最大SPI时钟为10Mhz)     
NRF24L01_Write_Buf(NRF24L01_WRITE_REG+TX_ADDR,buf,5);//写入5个字节的地址.
NRF24L01_Read_Buf(TX_ADDR,buf,5); //读出写入的地址  
for(i=0;i<5;i++)if(buf[i]!=0XA5)break;            
if(i!=5)return 1;//检测24L01错误
return 0;   //检测到24L01
}
中断配置:
#include "EXTI.H"

void EXTI_GPIOConfig(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);


GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_5 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource5);
}
void EXTI_NVICConfig(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure one bit for preemption priority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_Init(&NVIC_InitStructure);
/* Enable the EXTI9_5 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void EXTI_Config(void)
{
EXTI_InitTypeDef EXTI_InitStructure;

  EXTI_GPIOConfig();
EXTI_NVICConfig();
   
EXTI_InitStructure.EXTI_Line = EXTI_Line5;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
//EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_Trigger =EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* Generate software interrupt: simulate a falling edge applied on Key Button EXTI line */
EXTI_GenerateSWInterrupt(EXTI_Line5);
}

中断服务程序:
void EXTI9_5_IRQHandler(void)
{

int i;
for(i=0;i<20;i++)
{
   GPIO_SetBits(GPIOD,GPIO_Pin_2);
  Delay_Ms(200);
  GPIO_ResetBits(GPIOD,GPIO_Pin_2);
  Delay_Ms(200);
}
EXTI_ClearITPendingBit(EXTI_Line5);  

}  
}

主函数:
int main(void)
{
//uint8_t NRF24L01_TXBuf[32];
uint8_t NEF24L01_Stattus ;
//uint8_t rxbuf[1];

int i;
NEF24L01_Ready = 0 ;
   RCC_Configuration();
GPIO_Configuration();
NRF24L01_Config() ;
//EXTI_Config();
while(RF24L01_Check())
{
     GPIO_SetBits(GPIOD,GPIO_Pin_2);
  Delay_Ms(200);
  GPIO_ResetBits(GPIOD,GPIO_Pin_2);
  Delay_Ms(200);
}


NRF24L01_RX_Mode() ;
NRF24L01_Read(CONFIG);
NEF24L01_Ready  = 0xFF ;

   while (1)
{  
   GPIO_SetBits(GPIOA,GPIO_Pin_8);
   Delay_Ms(200);
      GPIO_ResetBits(GPIOA,GPIO_Pin_8);
   Delay_Ms(200);
    }
}}
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-7-3 21:47:08 | 显示全部楼层
希望做过这方面的人能够帮忙解答下!!万分感谢
回复 支持 反对

使用道具 举报

发表于 2013-7-3 22:28:22 | 显示全部楼层
是否没清中断?
我们的 k60 无线调试,就是 用中断方式来实现 无线发送和接收 消息的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-7-4 08:54:47 | 显示全部楼层
山外メ雲ジ 发表于 2013-7-3 22:28
是否没清中断?
我们的 k60 无线调试,就是 用中断方式来实现 无线发送和接收 消息的

我记得在中断服务程序已经清理中断了啊!!还请山外版主能不能发一个小程序给小弟调试下呢??改了好多天都没成功!!万分感谢啊!!
回复 支持 反对

使用道具 举报

发表于 2013-7-4 09:23:56 | 显示全部楼层
ljh407055315 发表于 2013-7-4 08:54
我记得在中断服务程序已经清理中断了啊!!还请山外版主能不能发一个小程序给小弟调试下呢??改了好多天 ...

参考一下山外哥的k60那个代码吧,是中断接收发送的

回复 支持 反对

使用道具 举报

发表于 2013-7-4 09:31:23 | 显示全部楼层
基本上都是中断复位函数出错,我贴上 k60 的代码把:

发送中断复位函数
  1. //由中断服务函数调用
  2. void NRF_ISR_Tx_Handler(void)
  3. {
  4.     if(isr_addr == NULL)
  5.     {
  6.         return;         //无效
  7.     }

  8.     //检测发送结果
  9.     isr_state = NRF_ReadReg(STATUS);                    /*读取状态寄存器的值 */

  10.     NRF_WriteReg(NRF_WRITE_REG + STATUS, isr_state);     /*清除TX_DS或MAX_RT中断标志*/

  11.     NRF_WriteReg(FLUSH_TX, NOP);                        //清除TX FIFO寄存器

  12.     if( (!(isr_state & TX_DS) ) || (isr_L == 0) )       //如果发送不成功,或者已经发送完成,则结束
  13.     {
  14.         isr_addr = NULL;                                //通过判断 isr_addr 就知道是否发送完毕。
  15.         isr_L    = 0;                                   //isr_L就不一定了
  16.         return;                                         //通过 isr_state 判断状态
  17.     }

  18.     //还没发送完成,就继续发送
  19.     isr_addr += MAX_ONCE_TX_NUM;       //指向下一个地址

  20.     NRF_ISR_Tx_Dat_Once();
  21. }


接收中断复位函数
  1. //由中断服务函数调用
  2. void NRF_ISR_Rx_Handler(void)
  3. {
  4.     uint8 state;

  5.     NRF_CE_LOW();    //进入待机状态

  6.     /*读取status寄存器的值  */
  7.     state = NRF_ReadReg(STATUS);

  8.     /* 清除中断标志*/
  9.     NRF_WriteReg(NRF_WRITE_REG + STATUS, state);

  10.     if(re_flag == QUEUE_FULL)       //满了就直接清FIFO,退出
  11.     {
  12.         NRF_WriteReg(FLUSH_RX, NOP);                    //清除RX FIFO寄存器
  13.         NRF_CE_HIGH();       //进入接收模式
  14.         return;       //接收队列满了,不进行处理
  15.     }

  16.     //还没满,则继续接收

  17.     /*判断是否接收到数据*/
  18.     if(state & RX_DR)                                 //接收到数据
  19.     {
  20.         NRF_ReadBuf(RD_RX_PLOAD, (uint8 *)&(RX_ISR_FIFO[rear]), RX_PLOAD_WIDTH); //读取数据
  21.         NRF_WriteReg(FLUSH_RX, NOP);                    //清除RX FIFO寄存器

  22.         rear++;

  23.         if(rear >= RX_ISR_FIFO_PACKET)
  24.         {
  25.             rear = 0;                       //重头开始
  26.         }

  27.         if(rear == front)                   //追到屁股了,满了
  28.         {
  29.             re_flag = QUEUE_FULL;
  30.         }
  31.         else
  32.         {
  33.             re_flag = QUEUE_NORMAL;
  34.         }
  35.     }
  36.     else
  37.     {
  38.         //没收到任何数据
  39.     }

  40.     NRF_CE_HIGH();       //进入接收模式

  41. }
回复 支持 反对

使用道具 举报

发表于 2013-7-4 09:32:29 | 显示全部楼层
你的代码,直接贴,很难看,没人会看 的 ,高亮一下,方便别人,别人才会看
回复 支持 反对

使用道具 举报

发表于 2013-7-4 09:33:16 | 显示全部楼层
最主要的是 清空  NRF 的 中断标志位 和清空FIFO
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-7-4 10:18:52 | 显示全部楼层
风落小鱼 发表于 2013-7-4 09:33
最主要的是 清空  NRF 的 中断标志位 和清空FIFO

嗯 谢谢提醒 新手刚来论坛 以后多指教!!能否加个朋友 我把我的代码发给你 你帮我看下 哪里错了 QQ407055315
回复 支持 反对

使用道具 举报

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

本版积分规则

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