|
MSP430F149实现无线传输(nrf24L01)。寄存器返回值0x00或0xff
[复制链接]
要用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具体的使用方法也不是很熟悉。希望大神们给解答解答啊。
|
|