MSP430F149实现无线传输(nrf24L01)。寄存器返回值0x00或0xff

2019-03-24 10:41发布

要用MSP430F149实现无线传输。无线传输模块用的nrf24l01. 
我在初始化nRF24L01模块中,用IAR查看配置的寄存器的值,当我没有烧录到板子里面,他都显示的是0x00,烧录到板子用IAR在线调试以后,他返回的值都是0xff,这是什么情况?就是说我要配置的信息都没有写到nRF24l01里面去啊!这是为什么呢? 

我把源代码贴上来,用P6端口模拟SPI。  我怀疑是不是那个SPI_RW函数有问题。看了很多代码,发现大部分代码在程序开始都有CLR_SCK这一步(有的代码没有),但是我贴上来的这个部分没有。是这个有问题么? 

我已经把程序调整为单纯的只要发送数据,STATUS相关位就会置位来判断是否发送成功。没有自动应答和重发。
 程序虽然常,但是大部分都是通用的配置程序,主程序其实很短。

#include<msp430X14X.h> 

#define uint unsigned int 
#define uchar unsigned char 

#define TX_ADR_WIDTH 4 
#define RX_PLOAD_WIDTH 4 
#define TX_PLOAD_WIDTH 4 



//选择路数 
uchar routine1[]="0x01"; 
uchar routine2[]="0x02"; 
uchar routine3[]="0x04"; 
uchar routine4[]="0x08"; 

//设定一个阈值温度 
uchar threshold_high[]="0045"; 
uchar threshold_low[]="0010"; 

uchar TX_ADDRESS[]={0xe7,0xe7,0xe7,0xe7}; 
uchar rx_buf[4]="19.3"; 

#define SET_CSN P6OUT|=BIT7//P6.7 SPI 
#define CLR_CSN P6OUT&=~BIT7 

#define SET_CE P6OUT|=BIT2//P6.2芯片发射使能 
#define CLR_CE P6OUT&=~BIT2 

#define READ_IRQ P6IN&BIT3 //P6.3的值 

/****************模拟SPI模式**************/ 

#define SET_MOSI P6OUT|=BIT5//P6.5--MOSI 
#define CLR_MOSI P6OUT&=~BIT5 

#define READ_MISO P6IN&BIT4 //P6,4 MISO 

#define SET_SCK P6OUT|=BIT6 //P6.6 SCK 
#define CLR_SCK P6OUT&=~BIT6 

//24L01寄存器地址 
#define CONFIG 0x00//配置寄存器 
#define EN_AA 0x01//自动寄存器 
#define EN_RXADDR 0x02//接收地址使能 
#define SETUP_AW 0x03//设置地址宽度 
#define SETUP_RETR 0x04//建立自动重发 
#define RF_CH 0x05//射频频道 
#define RF_SETUP 0x06//射频寄存器 
#define STATUS 0x07//状态寄存器 
#define OBSERVE_TX 0x08//发送检测寄存器 
#define CD 0x09//载波检测 
#define RX_ADDR_P0 0x0a//数据通道0接收地址 
#define RX_ADDR_P1 0x0b 
#define RX_ADDR_P2 0x0c 
#define RX_ADDR_P3 0x0d 
#define RX_ADDR_P4 0x0e 
#define RX_ADDR_P5 0x0f 
#define TX_ADDR 0x10//发送地址寄存器地址 
#define RX_PW_P0 0x11//接收地址通道0有效数据宽度 
#define RX_PW_P1 0x12 
#define RX_PW_P2 0x13 
#define RX_PW_P3 0x14 
#define RX_PW_P4 0x15 
#define RX_PW_P5 0x16 
#define FIFO_STATUS 0x17//FIFO状态寄存器 

//SPI命令字 
#define READ_REG 0x00//读寄存器命令 
#define WRITE_REG 0x20//写寄存器命令 
#define RD_RX_PLOAD 0x61//读有效数据命令 
#define WR_TX_PLOAD 0xa0//写有效数据命令 
#define FLUSH_TX 0xe1//清除TX_FIFO应用于发射模式 
#define FLUSH_RX 0xe2//清除RX_FIFO应用于接收模式 
#define REUSE_TX_PL 0xe3//重新使用上一包有效数据 
#define nop 0xef//空操作命令 



//****************延时函数******************// 
//delay 2us 
//================================= 
void Delay2us(uchar Counter) 

  while(--Counter); 

//================================== 



//delay100us 
//================================= 
void Delay100us(uchar Counter) 

  while(Counter--) 
  { 
    Delay2us(250); 
  } 

//================================= 
//delay 1ms 
void Delay1ms(uchar Counter) 

  while(Counter--) 
  { 
    Delay100us(11); 
  } 




//******************温度比较函数,适用于uchar型数据收*************** 
//收到的温度以xx.x,4字节存储,阈值温度以00XX,4字节存储 
uint compare_tem_high(uchar *tem) 

  if(tem[3]>threshold_high[1]) return 1;//高于阈值 
    
  else if(tem[3]<threshold_high[1]) return 0;//低于阈值 
   
  else 
  { 
    if(tem[2]>=threshold_high[0]) return 1;//高于阈值 
    else return 0;//低于阈值 
  } 

uint compare_tem_low(uchar *tem) 

  if(tem[3]>threshold_low[1]) return 1;//高于阈值 
     
  else if(tem[3]<threshold_low[1]) return 0;//低于阈值 
   
  else 
  { 
    if(tem[2]>threshold_low[0]) return 1;//高于阈值 
    else return 0;//低于阈值 
  } 

//******************初始化时钟************** 
void Init_CLK(void) 

  volatile unsigned int i; 
  WDTCTL=WDTPW+WDTHOLD; 
  BCSCTL1&=~XT2OFF; 
  do 
  { 
    IFG1&=~OFIFG; 
    for(i=0xff;i>0;i--); 
  } 
  while((IFG1&OFIFG)); 
   
  BCSCTL2|=SELM_2+SELS; 




//************模拟SPI方式***************==================是不是这个函数有问题? 
uchar SPI_RW(uchar byte) 

  uchar bit_ctr; 
  uchar a,b; 
  for(bit_ctr=0;bit_ctr<8;bit_ctr++) 
  { 
    a=(byte&0x80); 
    if(a!=0) 
      SET_MOSI; 
    else 
      CLR_MOSI; 
    byte=(byte<<1); 
    SET_SCK; 
    b=READ_MISO; 
    if(b!=0) 
      byte+=1; 
    else 
      CLR_SCK; 
  } 
  return byte; 


//***************向寄存器写一字节的数据,同时返回状态字**************** 
uchar SPI_RW_Reg(uchar reg,uchar value) 

  uchar status; 
  CLR_CSN; 
  status=SPI_RW(reg); 
  SPI_RW(value); 
  SET_CSN; 
  return status; 


//********************寄存器读出一字节数据********************* 
uchar SPI_Read(uchar reg) 

  uchar byte; 
  CLR_CSN; 
  SPI_RW(reg); 
  byte=SPI_RW(0x00);//写入一个0x00,读出数据 
  SET_CSN; 
  return byte; 


//*****************读出bytes数据********************* 
uchar SPI_Read_Buf(uchar reg,uchar *pBuf,uchar bytes) 

  uchar status,byte_ctr; 
  CLR_CSN; 
  status=SPI_RW(reg); 
  for(byte_ctr=0;byte_ctr<bytes;byte_ctr++) 
    pBuf[byte_ctr]=SPI_RW(0); 
  SET_CSN; 
  return(status); 


//******************写入bytes字节***************** 
uchar SPI_RW_Buf(uchar reg,uchar *pBuf,uchar bytes) 

  uchar status,byte_ctr; 
  CLR_CSN; 
  status=SPI_RW(reg); 
  for(byte_ctr=0;byte_ctr<bytes;byte_ctr++) 
     SPI_RW(*pBuf++); 
  SET_CSN; 
  return(status);   



//***************RX_MODE********************** 
void RX_Mode(void) 

  CLR_CE; 
  SPI_RW_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH); 
   
  SPI_RW_Reg(WRITE_REG+EN_AA,0x01);//通道0允许自动应答 
  SPI_RW_Reg(WRITE_REG+EN_RXADDR,0x01);//通道0允许 
  SPI_RW_Reg(WRITE_REG+RF_CH,0x02);//设置工作通道频率 
  SPI_RW_Reg(WRITE_REG+RX_PW_P0,TX_PLOAD_WIDTH);//接收数据有效宽度和发送数据有效宽度一样 
  SPI_RW_Reg(WRITE_REG+RF_SETUP,0x07);//0db,1mbps,lna_hcurr 
  SPI_RW_Reg(WRITE_REG+CONFIG,0x0f);//set pwr_up,enable crc,set prim_rx 
  SET_CE; 



//****************TX_MODE********************* 
void TX_Mode(uchar *data) 

  CLR_CE; 
  SPI_RW_Buf(WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH); 
  SPI_RW_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH); 
  SPI_RW_Buf(WR_TX_PLOAD,data,TX_PLOAD_WIDTH);//将数据写到WR_TX_PLOAD里面 
   
  /*SPI_RW_Reg(WRITE_REG+EN_AA,0x01); 
  SPI_RW_Reg(WRITE_REG+EN_RXADDR,0x01); 
  SPI_RW_Reg(WRITE_REG+SETUP_RETR,0x1a);*/ 
   
   SPI_RW_Reg(WRITE_REG+EN_AA,0x00); 
  SPI_RW_Reg(WRITE_REG+EN_RXADDR,0x00); 
  SPI_RW_Reg(WRITE_REG+SETUP_RETR,0x00); 
   
  SPI_RW_Reg(WRITE_REG+RF_CH,0x02); 
  SPI_RW_Reg(WRITE_REG+RF_SETUP,0x07); 
  SPI_RW_Reg(WRITE_REG+CONFIG,0x0e); 
   
  SET_CE;//使能收到回复信号 
  Delay2us(5); 
  CLR_CE; 





//******************nRf24L01配置,配置成接收模式**************===============调整成为单纯调试发送 
void nRF24L01_Config() 

  CLR_CE; 
  uchar temp; 
  SET_CSN;//SPI复位 
  //0x0f使能接收模式,0x0e为发射模式 
  SPI_RW_Reg(WRITE_REG+CONFIG,0x0e); 
  temp = SPI_Read(CONFIG); 
  if(temp==0x0e); 
  //数据通道0自动应答 
  //SPI_RW_Reg(WRITE_REG+EN_AA,0x01); 
  SPI_RW_Reg(WRITE_REG+EN_AA,0x00); 
   
  //通道0允许 
  //SPI_RW_Reg(WRITE_REG+EN_RXADDR,0x01); 
  SPI_RW_Reg(WRITE_REG+EN_RXADDR,0x00); 
   
  //设置地址宽度为4字节 
  SPI_RW_Reg(WRITE_REG+SETUP_AW,0x02); 
   
  //自动重发,500+86us,10次 
  //SPI_RW_Reg(WRITE_REG+SETUP_RETR,0x1a); 
  SPI_RW_Reg(WRITE_REG+SETUP_RETR,0x00); 
   
  //工作通道频率 
  SPI_RW_Reg(WRITE_REG+RF_CH,0x02); 
   
  //工作通道传输速率,发射功率 
  SPI_RW_Reg(WRITE_REG+RF_SETUP,0x07); 
   
  //通道0有效数据宽度 
  SPI_RW_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH); 



//****************初始化I/O端口**************** 
void IO_INIT() 

  P6SEL=0;//一般接口 
  P6DIR=0xe7;//1110 0111,p6.3,6.4为输入,其他输出 
  P6OUT|=BIT7;//p6.7输出高电平 
   
  P1SEL=0x00;//p1为键盘 
  P1DIR&=~BIT0;//p1.0为输入,其余输出 

   
  P5DIR=0xff;//led灯 
  P5OUT=0xff; 
   
  P2SEL=0;//蜂鸣器 
  P2DIR|=BIT6; 
  P2OUT|=BIT6; 
   
  return; 



//*************************主函数**************** 
void main() 

  uchar sta,temp; 
  WDTCTL=WDTPW+WDTHOLD; 
  Init_CLK(); 
  IO_INIT(); 
  nRF24L01_Config();//已经设置为发射模式 
   
  //发送数据,选择路数 
  TX_Mode(routine1);//进入发射模式 
  sta=SPI_Read(READ_REG+FIFO_STATUS); 
  if(sta&0x2e==0x2e) P5OUT=0x00;//发送成功 
  SPI_RW_Reg(WRITE_REG+STATUS,sta); 
  Delay1ms(50); 
  P5OUT=0xff; 


在nrf24l01_init函数中我烧进板子后在线调试,显示的不是0x0e,而是0xff,在main函数中,烧录程序之前只在iar中用simulator调试,sta显示的是0x00,烧录程序以后在线调试local中显示的是0xff.
这到底是什么问题啊?是nrf24l01压根没有成功启动,还是电路没有接好,还是程序有问题阿? 
如果是我前面提到的SPI_RW函数的问题,那么为什么会造成这个问题呢? 
因为做这个设计时间较短,自己对SPI具体的使用方法也不是很熟悉。希望大神们给解答解答啊。
此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
7条回答
IDZSJ
1楼-- · 2019-03-25 02:00
路过,支持一下






一周热门 更多>

相关问题

    相关文章