X
首页
技术
模拟电子
单片机
半导体
电源管理
嵌入式
传感器
最能打国产芯
应用
汽车电子
工业控制
家用电子
手机便携
安防电子
医疗电子
网络通信
测试测量
物联网
最能打国产芯
大学堂
首页
直播
专题
TI 培训
论坛
汽车电子
国产芯片
电机驱动控制
电源技术
单片机
模拟电子
PCB设计
电子竞赛
DIY/开源
嵌入式系统
医疗电子
颁奖专区
【厂商专区】
【电子技术】
【创意与实践】
【行业应用】
【休息一下】
最能打国产芯
活动中心
直播
发现活动
颁奖区
电子头条
参考设计
下载中心
分类资源
文集
排行榜
电路图
Datasheet
最能打国产芯
微控制器 MCU
[求助] g2553与nrf24l01接收端总能检测到载波
ZJ3024
2016-6-28 20:10
楼主
暑假期间要做一个5发一收的小玩意,因为以前调过51的24l01,决定移植到2553上,改用spi模块做,按教程一步一步调,发送端调完了,接收端出问题了,只有接收端,检测载波,不管哪个信道,全是有载波,把发送端上电,依旧没有接收,但是一直有载波没法调啊,是我家周围2.4G的wifi太多了的原因吗?
点赞
回复评论 (1)
沙发
ZJ3024
我自己上个程序,万一程序的原因呢?
spi24l01.h
#include <msp430.h>
#define NRF24L01DIR P1DIR
#define NRF24L01REN P1REN
#define NRF24L01IE P1IE
#define NRF24L01IES P1IES
#define NRF24L01IFG P1IFG
#define MCU2NRF24L01 P1OUT
#define NRF24L012MCU P1IN
#define CE BIT5
#define CSN BIT3
#define IRQ BIT0
#define OUTDIR NRF24L01DIR |= CE + CSN
#define IRQ_H MCU2NRF24L01 |= IRQ
#define IRQ_REN NRF24L01REN |= IRQ
#define IRQ_IE NRF24L01IE |= IRQ
#define IRQ_IES NRF24L01IES |= IRQ
#define IRQ_IFG NRF24L01IFG &= ~IRQ
#define CE_H MCU2NRF24L01 |= CE
#define CE_L MCU2NRF24L01 &= ~CE
#define CSN_H MCU2NRF24L01 |= CSN
#define CSN_L MCU2NRF24L01 &= ~CSN
/********** NRF24L01寄存器操作命令 ***********/
#define R_REGISTER 0x00 //读配置寄存器,低5位为寄存器地址
#define W_REGISTER 0x20 //写配置寄存器,低5位为寄存器地址
#define R_RX_PAYLOAD 0x61 //读RX有效数据,1~32字节
#define W_TX_PAYLOAD 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 //空操作,可以用来读状态寄存器
/********** NRF24L01寄存器地址 *************/
#define CONFIG 0x00 //配置寄存器地址
#define EN_AA 0x01 //使能自动应答功能
#define EN_RXADDR 0x02 //接收地址允许
#define SETUP_AW 0x03 //设置地址宽度(所有数据通道)
#define SETUP_RETR 0x04 //建立自动重发
#define RF_CH 0x05 //RF通道
#define RF_SETUP 0x06 //RF寄存器
#define STATUS 0x07 //状态寄存器
#define OBSERVE_TX 0x08 // 发送检测寄存器
#define CD 0x09 // 载波检测寄存器
#define RX_ADDR_P0 0x0A // 数据通道0接收地址
#define RX_ADDR_P1 0x0B // 数据通道1接收地址
#define RX_ADDR_P2 0x0C // 数据通道2接收地址
#define RX_ADDR_P3 0x0D // 数据通道3接收地址
#define RX_ADDR_P4 0x0E // 数据通道4接收地址
#define RX_ADDR_P5 0x0F // 数据通道5接收地址
#define TX_ADDR 0x10 // 发送地址寄存器
#define RX_PW_P0 0x11 // 接收数据通道0有效数据宽度(1~32字节)
#define RX_PW_P1 0x12 // 接收数据通道1有效数据宽度(1~32字节)
#define RX_PW_P2 0x13 // 接收数据通道2有效数据宽度(1~32字节)
#define RX_PW_P3 0x14 // 接收数据通道3有效数据宽度(1~32字节)
#define RX_PW_P4 0x15 // 接收数据通道4有效数据宽度(1~32字节)
#define RX_PW_P5 0x16 // 接收数据通道5有效数据宽度(1~32字节)
#define FIFO_STATUS 0x17 // FIFO状态寄存器
/****** STATUS寄存器bit位定义 *******/
#define MAX_RT 0x10 //达到最大发送次数中断
#define TX_DS 0x20 //数据发送完成中断
#define RX_DR 0x40 //接收到数据中断
void init_hwspi(void);
void init_nrf24l01_io(void);
unsigned char SPI_RW(unsigned char Byte);
unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value);
unsigned char SPI_Read(unsigned char reg);
unsigned char SPI_Read_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes);
unsigned char SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes);
spi24l01.c
#include <msp430.h>
#include "spi24l01.h"
void init_hwspi(void)
{
//DataIn + DataOut + SerialClockOut
//UCA0SOMI+UCA0SIMO+UCA0CLK
P1SEL = BIT1 + BIT2 + BIT4;
P1SEL2 = BIT1 + BIT2 + BIT4;
//USCI复位状态。
UCA0CTL1 |= UCSWRST;
//USCI时钟源选择SMCLK
UCA0CTL1 |= UCSSEL_2;
//在第一个 UCLK 边沿上捕获的数据和在下列边沿上改变的数据,未激活的状态是低电平
//MSB优先+主控模式+3线SPI+同步模式
UCA0CTL0 |= UCCKPH + UCMSB + UCMST + UCMODE_0 + UCSYNC;
//设定波特率
UCA0BR0 = 2;
UCA0BR1 = 0;
//USCI复位操作释放
UCA0CTL1 &= ~UCSWRST;
//使能接收和发送中断
// IE2 |= UCA0RXIE + UCA0TXIE;
}
void init_nrf24l01_io(void)
{
OUTDIR;
// IRQ_H;
// IRQ_REN;
// IRQ_IE;
// IRQ_IES;
// IRQ_IFG;
P1OUT |= BIT0;
P1REN |= BIT0;
P1IE |= BIT0;
P1IES |= BIT0;
P1IFG =0;
}
//硬件SPI数据交换函数
//SPI_RW(待交换的数据)
unsigned char SPI_RW(unsigned char byte)
{
UCA0TXBUF = byte;
while((UCA0STAT&UCBUSY)>0);
return UCA0RXBUF;
}
//寄存器写值函数
//SPI_RW_Reg(访问地址,要设定的值)
unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value)
{
//设定状态值
unsigned char status;
// 拉低CSN,初始化SPI传输
CSN_L;
// 写入待访问的地址(写寄存器命令(0x20)+寄存器地址),同时读取状态值
status = SPI_RW(reg);
// 写入要设定的值
SPI_RW(value);
// 拉高CSN,结束SPI传输
CSN_H;
// 返回状态值
return (status);
}
//读取寄存器值的函数
//SPI_Read(要读取的寄存器地址)
unsigned char SPI_Read(unsigned char reg)
{
//设定读取到值
unsigned char reg_val;
// 拉低CSN,初始化SPI传输
CSN_L;
// 写入待访问的寄存器地址(读寄存器命令(0x00可省略)+寄存器地址),同时读取状态值
SPI_RW(reg);
//读取寄存器的值
reg_val = SPI_RW(0);
// 拉高CSN,结束SPI传输
CSN_H;
//返回读取到的寄存器的值
return (reg_val);
}
//读取多字节的数据(主要用来在接收时读取 FIFO 缓冲区中的值)
//SPI_Read_Buf(待读寄存器地址,待读数据的存放地址(即存放读取数据的数组),数据的字节数)
unsigned char SPI_Read_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
{
//设定状态值,当前字节数
unsigned char status, byte_ctr;
// 拉低CSN,初始化SPI传输
CSN_L;
// 写入待访问的地址(写寄存器命令(0x20)+寄存器地址),同时读取状态值
status = SPI_RW(reg);
//按照数据字节数读取每字节数据
for (byte_ctr = 0; byte_ctr < bytes; byte_ctr++)
{
//将读取到每字节数据存入对应的数据地址
pBuf[byte_ctr] = SPI_RW(0);
}
// 拉高CSN,结束SPI传输
CSN_H;
// 返回状态值
return (status);
}
//写入多字节的数据(主要用来把数组里的数放到发射 FIFO 缓冲区中)
//SPI_Write_Buf(待写寄存器地址,待写数据的存放地址(即存放待写数据的数组),数据的字节数)
unsigned char SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
{
//设定状态值,当前字节数
unsigned char status, byte_ctr;
// 拉低CSN,初始化SPI传输
CSN_L;
// 写入待访问的地址(写寄存器命令(0x20)+寄存器地址),同时读取状态值
status = SPI_RW(reg);
//按照数据字节数写入每字节数据
for (byte_ctr = 0; byte_ctr < bytes; byte_ctr++)
{
//写入当前地址的一字节数据,并移动到下一字节的地址
SPI_RW(*pBuf++);
}
// 拉高CSN,结束SPI传输
CSN_H;
// 返回状态值
return (status);
}
发送端
#include <msp430.h>
#include "spi24l01.h"
unsigned char sta;
unsigned char fifo_s;
unsigned char flag,i,flag_rx=0;
unsigned char addr[5]={0,0,0,0,0};
unsigned char TX[3]={1,2,3};
unsigned char RX[3]={0,0,0};
//有效数据宽度
#define PLOAD_WIDTH 3
//地址宽度
#define ADR_WIDTH 5
//发送地址&自动应答接收地址
unsigned char ADDR[ADR_WIDTH]={1,2,3,4,5};
void init_clock(void)
{
// 检查校准信息是否被擦除
while(CALBC1_1MHZ==0xff||CALDCO_1MHZ==0XFF);
// 设置SELX的范围
DCOCTL=CALDCO_1MHZ;
// 设置SELX的范围
BCSCTL1=CALBC1_1MHZ;
//设置MCLK和SMCLK均为DCO_1MHz,8分频
BCSCTL2=DIVM_3+DIVS_3;
}
void delay_ms(unsigned int x)
{
unsigned int i,j;
for (i=0;i<x;i++)
for(j=0;j<100;j++);
}
void TX_init(void)
{
init_hwspi();
init_nrf24l01_io();
//模式选择,设定为待机模式
CE_L;
//停止寄存器读写
CSN_H;
//清除状态寄存器的值
SPI_RW_Reg(STATUS,0xff);
//设定发送节点的地址TX_ADDR, 地址数据, 地址宽度
SPI_Write_Buf(W_REGISTER + TX_ADDR, ADDR, ADR_WIDTH);
//设定应答信号待接收节点的地址RX_ADDR_P0, 地址数据, 地址宽度
SPI_Write_Buf(W_REGISTER + RX_ADDR_P0, ADDR, ADR_WIDTH);
//设定自动应答功能EN_AA,数据通道0自动应答允许
SPI_RW_Reg(W_REGISTER + EN_AA, 0x01);
//设定接收地址允许,接收数据通道0,允许接收数据通道0允许
SPI_RW_Reg(W_REGISTER + EN_RXADDR, 0x01);
//设定自动重发,等待500+86us,自动重发10次
SPI_RW_Reg(W_REGISTER + SETUP_RETR, 0x1a);
//设定通信通道频率RF_CH,选择信道为40
SPI_RW_Reg(W_REGISTER + RF_CH, 22);
//设定射频寄存器,发射功率0dBm 数据传输率2Mbps
SPI_RW_Reg(W_REGISTER + RF_SETUP, 0x07);
}
//发送数据包
void TX_Packet(unsigned char * tx_buf)
{
//模式选择,设定为待机模式
CE_L;
//清除状态寄存器的值
SPI_RW_Reg(W_REGISTER + STATUS,0xff);
//写TX有效数据,数据地址,数据量(选择TX_PLOAD_WIDTH(根据设定值))
SPI_Write_Buf(W_TX_PAYLOAD, tx_buf, PLOAD_WIDTH);
//设定配置寄存器,发射模式 上电 16位CRC校验 CRC使能
SPI_RW_Reg(W_REGISTER + CONFIG, 0x0e);
//启动发射
CE_H;
delay_ms(1);
}
/*
* main.c
*/
void main(void)
{
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
init_clock();
TX_init();
sta=SPI_Read(STATUS);
SPI_Read_Buf(RX_ADDR_P0,addr,5);
TX_Packet(TX);
sta=SPI_Read(STATUS);
sta=SPI_Read(STATUS);
_EINT();
while(1)
{
// sta=SPI_Read(STATUS);
if(TX[2]>99)
TX[2]=0;
}
}
//P1口中断服务函数
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
if(P1IFG&BIT0)
{
P1IFG &= ~BIT0;
sta=SPI_Read(STATUS);
SPI_RW_Reg(STATUS,0xff);
if(sta&MAX_RT)
{
TX_Packet(TX);
}
else if(sta&TX_DS)
{
TX[2]++;
TX_Packet(TX);
}
}
}
接收端
#include <msp430.h>
#include "spi24l01.h"
unsigned char sta;
unsigned char fifo_s;
unsigned char flag,i,flag_rx=0;
unsigned char addr[5]={0,0,0,0,0};
unsigned char tx[3]={1,2,3};
unsigned char RX[3]={0,0,0};
//有效数据宽度
#define PLOAD_WIDTH 3
//地址宽度
#define ADR_WIDTH 5
//发送地址&自动应答接收地址
unsigned char ADDR[ADR_WIDTH]={1,2,3,4,5};
void init_clock(void)
{
// 检查校准信息是否被擦除
while(CALBC1_1MHZ==0xff||CALDCO_1MHZ==0XFF);
// 设置SELX的范围
DCOCTL=CALDCO_1MHZ;
// 设置SELX的范围
BCSCTL1=CALBC1_1MHZ;
//设置MCLK和SMCLK均为DCO_1MHz,8分频
BCSCTL2=DIVM_3+DIVS_3;
}
void delay_ms(unsigned int x)
{
unsigned int i,j;
for (i=0;i<x;i++)
for(j=0;j<100;j++);
}
void RX_init(void)
{
init_hwspi();
init_nrf24l01_io();
delay_ms(1);
//模式选择,设定为待机模式
CE_L;
//停止寄存器读写
CSN_H;
//设定通信通道频率RF_CH,选择信道为40
SPI_RW_Reg(W_REGISTER + RF_CH,22);
//设定接收数据通道0有效数据量,选择PLOAD_WIDTH
SPI_RW_Reg(W_REGISTER + RX_PW_P0, PLOAD_WIDTH);
//设定射频寄存器,发射功率0dBm 数据传输率2Mbps
SPI_RW_Reg(W_REGISTER + RF_SETUP, 0x07);
// //设定发送节点的地址TX_ADDR, 地址数据, 地址宽度
// SPI_Write_Buf(W_REGISTER + TX_ADDR, ADDR, ADR_WIDTH);
//设定接收节点的地址RX_ADDR_P0, 地址数据, 地址宽度
SPI_Write_Buf(W_REGISTER +RX_ADDR_P0, ADDR, ADR_WIDTH);
//设定自动应答功能EN_AA,写0x01数据通道0自动应答允许
SPI_RW_Reg(W_REGISTER + EN_AA, 0x01);
//设定接收地址允许,接收数据通道0允许
SPI_RW_Reg(W_REGISTER + EN_RXADDR, 0x01);
}
void Set_RX()
{
CE_L;
SPI_RW_Reg(W_REGISTER + CONFIG, 0x0f);
CE_H;
delay_ms(1);
}
unsigned char RX_PACKET(unsigned char * rx_buf)
{
sta= SPI_Read(STATUS);
if(sta&RX_DR)
{
CE_L;
SPI_Read_Buf(R_RX_PAYLOAD,rx_buf,PLOAD_WIDTH);
flag_rx=1;
SPI_RW_Reg(W_REGISTER+STATUS,0xff);
}
return flag_rx;
}
/*
* main.c
*/
void main(void)
{
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
init_clock();
RX_init();
SPI_Read_Buf(RX_ADDR_P0,addr,5);
Set_RX();
_EINT();
while(1)
{
i = SPI_Read(CD);
if(i<1)
{
sta= SPI_Read(STATUS);
}
else if(i>0)
{
sta= SPI_Read(STATUS);
}
sta= SPI_Read(STATUS);
if(sta&RX_DR)
{
// RX_PACKET(RX);
//清除状态寄存器的值
SPI_RW_Reg(W_REGISTER + STATUS,0xff);
fifo_s =SPI_Read(FIFO_STATUS);
}
}
}
////P1口中断服务函数
//#pragma vector=PORT1_VECTOR
//__interrupt void Port_1(void)
//{
//// if(P1IFG&BIT0)
//// {
// sta= SPI_Read(STATUS);
// if(sta&RX_DR)
// {
// RX_PACKET(RX);
// }
//// }
//}
//P1口中断服务函数
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
if(P1IFG&BIT0)
{
P1IFG &= ~BIT0;
sta=SPI_Read(STATUS);
// SPI_RW_Reg(STATUS,0xff);
}
}
求助大神了
点赞
2016-6-28 20:14
最新活动
报名直播赢【双肩包、京东卡、水杯】| 高可靠性IGBT的新选择——安世半导体650V IGBT
30套RV1106 Linux开发板(带摄像头),邀您动手挑战边缘AI~
安世半导体理想二极管与负载开关,保障物联网应用的稳健高效运行
免费申请 | 上百份MPS MIE模块,免费试用还有礼!
PI 电源小课堂|无 DC-DC 变换实现多路高精度输出反激电源
2024 瑞萨电子MCU/MPU工业技术研讨会——深圳、上海站, 火热报名中
随便看看
蓝牙协议分析_协议架构
串口调试
美信为音频系统推出完整线路输出解决方案
开关电源的带宽是不是越高越好?
无线电元器件精汇
STM32F的参考手册都到Rev10了,中文手册什么时候跟上?
大家来讨论一关于FAT16的问题"RootDirSectors= ((BPB_RootEntCnt*32) + (BPB_BytsPerSec–1)) /BPB
关于烧程序
功放在漏极偏置下的功率如何计算?
有没有谁用LPC213x硬件方式得到稳定的IIC?
2个DSP如何共享一个FIFO的数据
关于内部数据寄存器的问题
不知道有没有人遇到过不能下载的问题
图中C1503作用
Wince6.0与设备连接不上的问题
ARM Cortex-A9 MPCore 多核处理器
stm32 新版本固件库里的 FSMC NANDInitTypeDef
求ARM开发板
求游标卡尺一枚
51单片机数据采集系统设计问题(急)
电子工程世界版权所有
京B2-20211791
京ICP备10001474号-1
京公网安备 11010802033920号
回复
写回复
收藏
回复