要用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具体的使用方法也不是很熟悉。希望大神们给解答解答啊。
此帖出自
小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
一周热门 更多>