关于stm32f103ve与stc之间的无线通信
最近在做毕设,但是苦于水平有限,调试不出来,我要做的是stm32与stc之间通过nrf24l01进行无线通信,但是我调试了大半个月还是做不出来,不晓得哪里出错了,请大神们指点,主机用stm32,程序用的是野火的,从机用stcstm程序main.c
#include "stm32f10x.h"
#include "SPI_NRF.h"
#include "usart1.h"
u8 status; //用于判断接收/发送状态
u8 txbuf={0,1,2,3}; //发送缓冲
u8 rxbuf; //接收缓冲
int i=0;
int main(void)
{
SPI_NRF_Init();
/* 串口1初始化 */
USART1_Config();
printf("\r\n 这是一个 NRF24L01 无线传输实验 \r\n");
printf("\r\n 这是无线传输 主机端 的反馈信息\r\n");
printf("\r\n 正在检测NRF与MCU是否正常连接。。。\r\n");
/*检测NRF模块与MCU的连接*/
status = NRF_Check();
/*判断连接状态*/
if(status == SUCCESS)
printf("\r\n NRF与MCU连接成功!\r\n");
else
printf("\r\nNRF与MCU连接失败,请重新检查接线。\r\n");
while(1)
{
printf("\r\n 主机端 进入自应答发送模式\r\n");
NRF_TX_Mode();
/*开始发送数据*/
status = NRF_Tx_Dat(txbuf);
/*判断发送状态*/
switch(status)
{
case MAX_RT:
printf("\r\n 主机端 没接收到应答信号,发送次数超过限定值,发送失败。 \r\n");
break;
case ERROR:
printf("\r\n 未知原因导致发送失败。 \r\n");
break;
case TX_DS:
printf("\r\n 主机端 接收到 从机端 的应答信号,发送成功! \r\n");
break;
}
printf("\r\n 主机端 进入接收模式。 \r\n");
NRF_RX_Mode();
/*等待接收数据*/
status = NRF_Rx_Dat(rxbuf);
/*判断接收状态*/
switch(status)
{
case RX_DR:
for(i=0;i<4;i++)
{
printf("\r\n 主机端 接收到 从机端 发送的数据为:%d \r\n",rxbuf);
txbuf =rxbuf;
}
break;
case ERROR:
printf("\r\n 主机端 接收出错。 \r\n");
break;
}
}
}
SPI_NRF.c程序
#include "SPI_NRF.h"
#include "usart1.h"
u8 RX_BUF; //接收数据缓存
u8 TX_BUF; //发射数据缓存
u8 TX_ADDRESS = {0x34,0x43,0x10,0x10,0x01};// 定义一个静态发送地址
u8 RX_ADDRESS = {0x34,0x43,0x10,0x10,0x01};
void Delay(__IO u32 nCount)
{
for(; nCount != 0; nCount--);
}
/*
* 函数名:SPI_NRF_Init
* 描述:SPI的 I/O配置
* 输入:无
* 输出:无
* 调用:外部调用
*/
void SPI_NRF_Init(void)
{
SPI_InitTypeDefSPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/*使能GPIOB,GPIOD,复用功能时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE|RCC_APB2Periph_AFIO, ENABLE);
/*使能SPI1时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
/*配置 SPI_NRF_SPI的 SCK,MISO,MOSI引脚,GPIOA^5,GPIOA^6,GPIOA^7 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用功能
GPIO_Init(GPIOA, &GPIO_InitStructure);
/*配置SPI_NRF_SPI的CE引脚,GPIOA^2和SPI_NRF_SPI的 CSN 引脚: NSS GPIOA^8*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/*配置SPI_NRF_SPI的IRQ引脚,GPIOA^3*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;//上拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* 这是自定义的宏,用于拉高csn引脚,NRF进入空闲状态 */
NRF_CSN_HIGH();
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //双线全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主模式
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //数据大小8位
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //时钟极性,空闲时为低
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //第1个边沿有效,上升沿为采样时刻
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由软件产生
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;//8分频,9MHz
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //高位在前
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
/* Enable SPI1*/
SPI_Cmd(SPI1, ENABLE);
}
/*
* 函数名:SPI_NRF_RW
* 描述:用于向NRF读/写一字节数据
* 输入:写入的数据
* 输出:读取得的数据
* 调用:内部调用
*/
u8 SPI_NRF_RW(u8 dat)
{
/* 当 SPI发送缓冲器非空时等待 */
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
/* 通过 SPI2发送一字节数据 */
SPI_I2S_SendData(SPI1, dat);
/* 当SPI接收缓冲器为空时等待 */
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
/* Return the byte read from the SPI bus */
return SPI_I2S_ReceiveData(SPI1);
}
/*
* 函数名:SPI_NRF_WriteReg
* 描述:用于向NRF特定的寄存器写入数据
* 输入:reg:NRF的命令+寄存器地址。
dat:将要向寄存器写入的数据
* 输出:NRF的status寄存器的状态
* 调用:内部调用
*/
u8 SPI_NRF_WriteReg(u8 reg,u8 dat)
{
u8 status;
NRF_CE_LOW();
/*置低CSN,使能SPI传输*/
NRF_CSN_LOW();
/*发送命令及寄存器号 */
status = SPI_NRF_RW(reg);
/*向寄存器写入数据*/
SPI_NRF_RW(dat);
/*CSN拉高,完成*/
NRF_CSN_HIGH();
/*返回状态寄存器的值*/
return(status);
}
/*
* 函数名:SPI_NRF_ReadReg
* 描述:用于从NRF特定的寄存器读出数据
* 输入:reg:NRF的命令+寄存器地址。
* 输出:寄存器中的数据
* 调用:内部调用
*/
u8 SPI_NRF_ReadReg(u8 reg)
{
u8 reg_val;
NRF_CE_LOW();
/*置低CSN,使能SPI传输*/
NRF_CSN_LOW();
/*发送寄存器号*/
SPI_NRF_RW(reg);
/*读取寄存器的值 */
reg_val = SPI_NRF_RW(NOP);
/*CSN拉高,完成*/
NRF_CSN_HIGH();
return reg_val;
}
/*
* 函数名:SPI_NRF_ReadBuf
* 描述:用于从NRF的寄存器中读出一串数据
* 输入:reg:NRF的命令+寄存器地址。
pBuf:用于存储将被读出的寄存器数据的数组,外部定义
bytes: pBuf的数据长度
* 输出:NRF的status寄存器的状态
* 调用:外部调用
*/
u8 SPI_NRF_ReadBuf(u8 reg,u8 *pBuf,u8 bytes)
{
u8 status, byte_cnt;
NRF_CE_LOW();
/*置低CSN,使能SPI传输*/
NRF_CSN_LOW();
/*发送寄存器号*/
status = SPI_NRF_RW(reg);
/*读取缓冲区数据*/
for(byte_cnt=0;byte_cnt<bytes;byte_cnt++)
pBuf = SPI_NRF_RW(NOP); //从NRF24L01读取数据
/*CSN拉高,完成*/
NRF_CSN_HIGH();
return status; //返回寄存器状态值
}
/*
* 函数名:SPI_NRF_WriteBuf
* 描述:用于向NRF的寄存器中写入一串数据
* 输入:reg:NRF的命令+寄存器地址。
pBuf:存储了将要写入写寄存器数据的数组,外部定义
bytes: pBuf的数据长度
* 输出:NRF的status寄存器的状态
* 调用:外部调用
*/
u8 SPI_NRF_WriteBuf(u8 reg ,u8 *pBuf,u8 bytes)
{
u8 status,byte_cnt;
NRF_CE_LOW();
/*置低CSN,使能SPI传输*/
NRF_CSN_LOW();
/*发送寄存器号*/
status = SPI_NRF_RW(reg);
/*向缓冲区写入数据*/
for(byte_cnt=0;byte_cnt<bytes;byte_cnt++)
SPI_NRF_RW(*pBuf++); //写数据到缓冲区
/*CSN拉高,完成*/
NRF_CSN_HIGH();
return (status); //返回NRF24L01的状态
}
/*
* 函数名:NRF_RX_Mode
* 描述:配置并进入接收模式
* 输入:无
* 输出:无
* 调用:外部调用
*/
void NRF_RX_Mode(void)
{
NRF_CE_LOW();
SPI_NRF_WriteBuf(NRF_WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTH);//写RX节点地址
SPI_NRF_WriteReg(NRF_WRITE_REG+EN_AA,0x01); //使能通道0的自动应答
SPI_NRF_WriteReg(NRF_WRITE_REG+EN_RXADDR,0x01);//使能通道0的接收地址
SPI_NRF_WriteReg(NRF_WRITE_REG+RF_CH,CHANAL); //设置RF通信频率
SPI_NRF_WriteReg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度
SPI_NRF_WriteReg(NRF_WRITE_REG+RF_SETUP,0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启
SPI_NRF_WriteReg(NRF_WRITE_REG+CONFIG, 0x0f);//配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式
/*CE拉高,进入接收模式*/
NRF_CE_HIGH();
}
/*
* 函数名:NRF_TX_Mode
* 描述:配置发送模式
* 输入:无
* 输出:无
* 调用:外部调用
*/
void NRF_TX_Mode(void)
{
NRF_CE_LOW();
SPI_NRF_WriteBuf(NRF_WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH); //写TX节点地址
SPI_NRF_WriteBuf(NRF_WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTH); //设置TX节点地址,主要为了使能ACK
SPI_NRF_WriteReg(NRF_WRITE_REG+EN_AA,0x01); //使能通道0的自动应答
SPI_NRF_WriteReg(NRF_WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址
SPI_NRF_WriteReg(NRF_WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次
SPI_NRF_WriteReg(NRF_WRITE_REG+RF_CH,CHANAL); //设置RF通道为CHANAL
SPI_NRF_WriteReg(NRF_WRITE_REG+RF_SETUP,0x0f);//设置TX发射参数,0db增益,2Mbps,低噪声增益开启
SPI_NRF_WriteReg(NRF_WRITE_REG+CONFIG,0x0e); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,发射模式,开启所有中断
/*CE拉高,进入发送模式*/
NRF_CE_HIGH();
Delay(0xffff); //CE要拉高一段时间才进入发送模式
}
/*
* 函数名:NRF_Check
* 描述:主要用于NRF与MCU是否正常连接
* 输入:无
* 输出:SUCCESS/ERROR 连接正常/连接失败
* 调用:外部调用
*/
u8 NRF_Check(void)
{
u8 buf={0xC2,0xC2,0xC2,0xC2,0xC2};
u8 buf1;
u8 i;
/*写入5个字节的地址.*/
SPI_NRF_WriteBuf(NRF_WRITE_REG+TX_ADDR,buf,5);
/*读出写入的地址 */
SPI_NRF_ReadBuf(TX_ADDR,buf1,5);
/*比较*/
for(i=0;i<5;i++)
{
if(buf1!=0xC2)
break;
}
if(i==5)
return SUCCESS ; //MCU与NRF成功连接
else
return ERROR ; //MCU与NRF不正常连接
}
/*
* 函数名:NRF_Tx_Dat
* 描述:用于向NRF的发送缓冲区中写入数据
* 输入:txBuf:存储了将要发送的数据的数组,外部定义
* 输出:发送结果,成功返回TXDS,失败返回MAXRT或ERROR
* 调用:外部调用
*/
u8 NRF_Tx_Dat(u8 *txbuf)
{
u8 state;
/*ce为低,进入待机模式1*/
NRF_CE_LOW();
/*写数据到TX BUF 最大 32个字节*/
SPI_NRF_WriteBuf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);
/*CE为高,txbuf非空,发送数据包 */
NRF_CE_HIGH();
/*等待发送完成中断 */
while(NRF_Read_IRQ()!=0);
/*读取状态寄存器的值 */
state = SPI_NRF_ReadReg(STATUS);
/*清除TX_DS或MAX_RT中断标志*/
SPI_NRF_WriteReg(NRF_WRITE_REG+STATUS,state);
SPI_NRF_WriteReg(FLUSH_TX,NOP); //清除TX FIFO寄存器
/*判断中断类型*/
if(state&MAX_RT) //达到最大重发次数
return MAX_RT;
else if(state&TX_DS) //发送完成
return TX_DS;
else
return ERROR; //其他原因发送失败
}
/*
* 函数名:NRF_Rx_Dat
* 描述:用于从NRF的接收缓冲区中读出数据
* 输入:rxBuf:用于接收该数据的数组,外部定义
* 输出:接收结果,
* 调用:外部调用
*/
u8 NRF_Rx_Dat(u8 *rxbuf)
{
u8 state;
NRF_CE_HIGH(); //进入接收状态
/*等待接收中断*/
while(NRF_Read_IRQ()!=0);
NRF_CE_LOW(); //进入待机状态
/*读取status寄存器的值*/
state=SPI_NRF_ReadReg(STATUS);
/* 清除中断标志*/
SPI_NRF_WriteReg(NRF_WRITE_REG+STATUS,state);
/*判断是否接收到数据*/
if(state&RX_DR) //接收到数据
{
SPI_NRF_ReadBuf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据
SPI_NRF_WriteReg(FLUSH_RX,NOP); //清除RX FIFO寄存器
return RX_DR;
}
else
return ERROR; //没收到任何数据
}
stc程序
#include <STC12LE520X.h>
#include <intrins.h>
typedef unsigned char uchar;
typedef unsigned char uint;
//****************************************IO端口定义***************************************
sbit MISO =P1^3;
sbit MOSI =P1^4;
sbit SCK =P1^5;
sbit CE =P1^7;
sbit CSN =P1^6;
sbit IRQ =P3^2;
//*****************************指示灯,用于状态指示*****************************************
sbit LED1 =P1^2; //高电平时亮
sbit LED2 =P3^7;
sbit KEY1 =P1^0; //按键1,和GND短接后有效
sbit KEY2 =P3^3; //按键2,和GND短接后有效
//*********************以下IO在本程序中没有使用到,用户可以结合自己实际应用加以利用*********
sbit TXD =P3^1; //uart 串口 输出
sbit RXD =P3^0; //uart 串口 输入
sbit P11 =P1^1;
sbit P34 =P3^4;
sbit P35 =P3^5;
//*********************************************相关变量*************************************
chartf, RxBuf,TxBuf;
char buf={0x3f,0x06,0x5b,0x4f,0x5f,0x6f};
char i;
//*********************************************NRF24L01*************************************
#define TX_ADR_WIDTH 5 // 5 uints TX address width
#define RX_ADR_WIDTH 5 // 5 uints RX address width
#define TX_PLOAD_WIDTH32 // 20 uints TX payload
#define RX_PLOAD_WIDTH32 // 20 uints TX payload
uint const TX_ADDRESS= {0x34,0x43,0x10,0x10,0x01}; //本地地址
uint const RX_ADDRESS= {0x34,0x43,0x10,0x10,0x01}; //接收地址
#define CHANAL 40///
//***************************************NRF24L01寄存器指令*******************************************************
#define READ_REG 0x00 // 读寄存器指令
#define WRITE_REG 0x20 // 写寄存器指令
#define RD_RX_PLOAD 0x61 // 读取接收数据指令
#define WR_TX_PLOAD 0xA0 // 写待发数据指令
#define FLUSH_TX 0xE1 // 冲洗发送 FIFO指令
#define FLUSH_RX 0xE2 // 冲洗接收 FIFO指令
#define REUSE_TX_PL 0xE3 // 定义重复装载数据指令
#define NOP 0xFF // 保留
//*************************************SPI(nRF24L01)寄存器地址****************************************************
#define CONFIG 0x00// 配置收发状态,CRC校验模式以及收发状态响应方式
#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// 频道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接收数据长度
#define RX_PW_P1 0x12// 接收频道0接收数据长度
#define RX_PW_P2 0x13// 接收频道0接收数据长度
#define RX_PW_P3 0x14// 接收频道0接收数据长度
#define RX_PW_P4 0x15// 接收频道0接收数据长度
#define RX_PW_P5 0x16// 接收频道0接收数据长度
#define FIFO_STATUS 0x17// FIFO栈入栈出状态寄存器设置
//**************************************************************************************
void Delay(unsigned int s);
void inerDelay_us(unsigned int n);
void init_NRF24L01(void);
uint SPI_RW(uint uchar);
uchar SPI_Read(uchar reg);
void SetRX_Mode(void);
uint SPI_RW_Reg(uchar reg, uchar value);
uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);
unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);
void nRF24L01_TxPacket(unsigned char * tx_buf);
void init_serialcomm();//串口初始化
void SBUFSend();//发送
void SBUFRev();//接受数据
void SetTX_Mode(void);
void init_serialcomm()
{
TMOD=0x20; //定时器1,方式2
TH1=0xfd;//波特率设定
TL1=0xfd;//
PCON=0x00; //串口波特率不加倍
TR1=1; //启动Timer 1
SCON=0x50; //mode 2 开始接收
}
void SBUFSend()
{
SBUF=buf; //把数据存放到SBUF寄存器里
while(TI==0); //等待数据发送完
TI=0; //置0,保证下次数据发送
}
void SBUFRev()
{
while(RI==0); //等待接收完数据
buf=SBUF; //提取数据到P2口
RI=0; //置0,保证下次接收数据
}
//*****************************************长延时*****************************************
void Delay(unsigned int s)
{
unsigned int i;
for(i=0; i<s; i++);
for(i=0; i<s; i++);
}
//******************************************************************************************
uint bdata sta; //状态标志
sbit RX_DR =sta^6;
sbit TX_DS =sta^5;
sbit MAX_RT =sta^4;
/******************************************************************************************
/*延时函数
/******************************************************************************************/
void inerDelay_us(unsigned int n)
{
for(;n>0;n--)
_nop_();
}
//****************************************************************************************
/*NRF24L01初始化
//***************************************************************************************/
void init_NRF24L01(void)
{
inerDelay_us(100);
CE=0; // chip enable
CSN=1; // Spi disable
SCK=0; // Spi clock line init high
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写本地地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); //频道0自动 ACK应答允许
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);//允许接收地址只有频道0,如果需要多频道可以参考Page21
SPI_RW_Reg(WRITE_REG + RF_CH, CHANAL); // 设置信道工作为2.4GHZ,收发必须一致
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x0f); //设置发射速率为1MHZ,发射功率为最大值0dB
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC ,主接收
}
/****************************************************************************************************
/*函数:uint SPI_RW(uint uchar)
/*功能:NRF24L01的SPI写时序
/****************************************************************************************************/
uint SPI_RW(uint uchar)
{
uint bit_ctr;
for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
{
MOSI = (uchar & 0x80); // output 'uchar', MSB to MOSI
uchar = (uchar << 1); // shift next bit into MSB..
SCK = 1; // Set SCK high..
uchar |= MISO; // capture current MISO bit
SCK = 0; // ..then set SCK low again
}
return(uchar); // return read uchar
}
/****************************************************************************************************
/*函数:uchar SPI_Read(uchar reg)
/*功能:NRF24L01的SPI时序
/****************************************************************************************************/
uchar SPI_Read(uchar reg)
{
uchar reg_val;
CSN = 0; // CSN low, initialize SPI communication...
SPI_RW(reg); // Select register to read from..
reg_val = SPI_RW(0); // ..then read registervalue
CSN = 1; // CSN high, terminate SPI communication
return(reg_val); // return register value
}
/****************************************************************************************************/
/*功能:NRF24L01读写寄存器函数
/****************************************************************************************************/
uint SPI_RW_Reg(uchar reg, uchar value)
{
uint status;
CSN = 0; // CSN low, init SPI transaction
status = SPI_RW(reg); // select register
SPI_RW(value); // ..and write value to it..
CSN = 1; // CSN high again
return(status); // return nRF24L01 status uchar
}
/****************************************************************************************************/
/*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
/*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数
/****************************************************************************************************/
uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
{
uint status,uchar_ctr;
CSN = 0; // Set CSN low, init SPI tranaction
status = SPI_RW(reg); // Select register to write to and read status uchar
for(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)
pBuf = SPI_RW(0); //
CSN = 1;
return(status); // return nRF24L01 status uchar
}
/*********************************************************************************************************
/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数
/*********************************************************************************************************/
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
{
uint status,uchar_ctr;
CSN = 0; //SPI使能
status = SPI_RW(reg);
for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //
SPI_RW(*pBuf++);
CSN = 1; //关闭SPI
return(status); //
}
/****************************************************************************************************/
/*函数:void SetRX_Mode(void)
/*功能:数据接收配置
/****************************************************************************************************/
void SetRX_Mode(void)
{
CE=0;
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC ,主接收
CE = 1;
inerDelay_us(500); //延时不能太短
}
void SetTX_Mode(void)
{
CE=0;
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC ,主接收
CE = 1;
inerDelay_us(500); //延时不能太短
}
/******************************************************************************************************/
/*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
/*功能:数据读取后放如rx_buf接收缓冲区中
/******************************************************************************************************/
unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
{
unsigned char revale=0;
sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况
if(RX_DR) // 判断是否接收到数据
{
CE = 0; //SPI使能
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
revale =1; //读取数据完成标志
}
SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志
return revale;
}
/***********************************************************************************************************
/*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)
/*功能:发送 tx_buf中数据
/**********************************************************************************************************/
void nRF24L01_TxPacket(unsigned char * tx_buf)
{
CE=0; //StandBy I模式
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址
SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送
CE=1; //置高CE,激发数据发送
inerDelay_us(10);
}
//************************************主函数************************************************************
void main(void)
{
init_NRF24L01();//初始化
init_serialcomm();//初始化
P1M1=P1M1&0xfb;P1M0=P1M0|0x04; //设置P1.2为内部上拉输出,如果不设置,LED指示灯会很暗
P3M1=P1M1&0x7f;P3M0=P1M0|0x80; //设置P3.7为内部上拉输出
LED1=1; LED2=1;
Delay(6000);
while(1)
{
if(KEY1==0) //是否有按键标志KEY1:1.0
{
Delay(500);
tf = 1 ; LED1=1;LED2=0;
TxBuf = 0x29 ;
}
if(KEY2==0) //是否有按键标志 KEY2: 3.3
{
Delay(500);
tf = 1 ; LED1=0;LED2=1;
TxBuf = 0x30 ;
}
if (tf==1)
{
SetTX_Mode();
nRF24L01_TxPacket(TxBuf); // 当有按键后,不同按键发送不同数据
SPI_RW_Reg(WRITE_REG+STATUS,0XFF);
TxBuf = 0xff; //发送完后将TxBuf设定成0xFF,以作状态恢复
TxBuf = 0xff;
tf=0;
Delay(1000);
}
SetRX_Mode();
if(nRF24L01_RxPacket(RxBuf))
{
if(RxBuf==0x01)
{
LED1=1;LED2=0;
}
if(RxBuf==0x02)
{
LED1=0;LED2=1;
}
Delay(10000);
for(i=0;i<4;i++)
{
//RxBuf++;
//发送给串口
buf=RxBuf++;//
SBUFSend();
}
RxBuf=0; RxBuf=0;RxBuf=0;RxBuf=0;
}
LED1=0;LED2=0;
}
}
新手乱说,debug
通信先用电脑串口调试住手调通。 我敢打包票没人看你这坨代码 dashashi 发表于 2012-5-3 18:17 static/image/common/back.gif
我敢打包票没人看你这坨代码
那我应该怎么办啊 贴代码别人哪有时间给你查呢
关键看无线芯片配置ok没
页:
[1]