我正在尝试使用通过spi连接到atmega8s的两个nRF24L01无线电模块进行通信。
我所能做的就是写一些nRF寄存器,但不能发送数据。当我读取无线电状态寄存器时,它返回十进制14或有时0或有时十进制30。
这是我的atmega8代码:
#include <mega8.h>
#include <C:\cvavr\BIN\nRF24L01\nrf24l012.h>
#include <stdio.h>
#include <pcf8576d.h>
#define _CH 1 // Channel 0..125
#define _Address_Width 5 // 3..5
#define _Buffer_Size 32 // 1..32
// Declare your global variables here
unsigned char global_var=0;
void NRF24L01_Receive(char Buf[_Buffer_Size]) {
NRF24L01_CE_HIGH;
delay_us(130);
while ((NRF24L01_Get_Status() & _RX_DR) != _RX_DR);
NRF24L01_CE_LOW;
NRF24L01_Read_RX_Buf(Buf, _Buffer_Size);
NRF24L01_Clear_Interrupts();
}
void NRF24L01_Send(char* Buf) {
NRF24L01_Write_TX_Buf(Buf, _Buffer_Size);
NRF24L01_RF_TX();
while ((NRF24L01_Get_Status() & _TX_DS) != _TX_DS) ;
NRF24L01_Clear_Interrupts();
}
// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
char buffer[32];
char state = NRF24L01_Get_Status();
lcd_erase();
lcd_printf("INT ");
lcd_print(state);
if(state==0) NRF24L01_Read_RX_Buf(buffer,32);
lcd_print(buffer[0]);
delay_ms(100);
NRF24L01_Clear_Interrupts();
}
// SPI interrupt service routine
interrupt [SPI_STC] void spi_isr(void)
{
}
void main(void)
{
// Declare your local variables here
char i;
unsigned char bffr[5];
unsigned char Buf[_Buffer_Size];
unsigned char Data[5]={3,9,5,8,4};
unsigned char Address_p0[_Address_Width] = { 0xf0,0xf0,0xf0,0xf0,0xe1 };
unsigned char Address_p1[_Address_Width] = { 0xf0,0xf0,0xf0,0xf0,0xd2 };
unsigned char Address_p2[1]={0xc3};
unsigned char Address_p3[1]={0xc4};
unsigned char Address_p4[1]={0xc5};
unsigned char Address_p5[1]={0xc6};
spi_int1_init();
TWI_init_master();
delay_ms(300);
lcd_erase();
lcd_printf("start");
delay_ms(1200);
NRF24L01_Init(_TX_MODE, _CH, _1Mbps, Address_p0, _Address_Width, _Buffer_Size);
NRF24L01_WriteReg(W_REGISTER | EN_RXADDR,0x03);
NRF24L01_Set_RX_Pipe (0,Address_p0,_Address_Width, _Buffer_Size);
NRF24L01_Set_RX_Pipe (1,Address_p1,_Address_Width, _Buffer_Size);
NRF24L01_Set_TX_Address(Address_p0,_Address_Width);
NRF24L01_Set_RX_Pipe (2,Address_p2,1,0);
NRF24L01_Set_RX_Pipe (3,Address_p3,1,0);
NRF24L01_Set_RX_Pipe (4,Address_p4,1,0);
NRF24L01_Set_RX_Pipe (5,Address_p5,1,0);
NRF24L01_WriteReg(W_REGISTER | EN_AA,0X3F);
NRF24L01_WriteReg(W_REGISTER | EN_RXADDR,0x03);
NRF24L01_WriteReg(W_REGISTER | RF_CH, 0x0c);
NRF24L01_WriteReg(W_REGISTER | RF_SETUP,0X03);
NRF24L01_WriteReg(W_REGISTER | CONFIG,0X0E);
NRF24L01_WriteReg(W_REGISTER | SETUP_RETR,0X28);
global_var = NRF24L01_Get_Status();
//global_var=SPI(234);
lcd_erase();
lcd_print(global_var);
delay_ms(1000);
global_var = NRF24L01_ReadReg(CONFIG);
lcd_erase();
lcd_print(global_var);
delay_ms(1000);
lcd_erase();
NRF24L01_ReadRegBuf(TX_ADDR,bffr,5);
for(i=0;i<5;i++)
lcd_print(bffr[i]);
delay_ms(1000);
global_var = NRF24L01_ReadReg(FIFO_STATUS);
lcd_erase();
lcd_printf("ffo ");
lcd_print(global_var);
delay_ms(1000);
NRF24L01_Send(Data);
global_var = NRF24L01_Get_Status();
lcd_erase();
lcd_print(global_var);
delay_ms(1000);
global_var = NRF24L01_ReadReg(FIFO_STATUS);
lcd_erase();
lcd_printf("mioh ");
lcd_print(global_var);
delay_ms(1000);
while (1);
}
这是我的nrf24l012.h
#include <delay.h>
#include <C:\cvavr\BIN\nRF24L01\nrf24l011.h>
/*
* SPI pins:
* MOSI: DDB3
* MISO: DDB4
* SCK : DDB5
* CSN : DDB2
* CE : DDB1
*/
void spi_int1_init(void){
// Input/Output Ports initialization
// Port B initialization
// Function: Bit7=In Bit6=In Bit5=Out Bit4=In Bit3=Out Bit2=Out Bit1=In Bit0=In
DDRB=(0<<DDB7) | (0<<DDB6) | (1<<DDB5) | (0<<DDB4) | (1<<DDB3) | (1<<DDB2) | (1<<DDB1) | (0<<DDB0);
// State: Bit7=T Bit6=T Bit5=0 Bit4=T Bit3=0 Bit2=0 Bit1=T Bit0=T
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);
// External Interrupt(s) initialization
// INT0: Off
// INT1: On
// INT1 Mode: Falling Edge
GICR|=(1<<INT1) | (0<<INT0);
MCUCR=(1<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
GIFR=(1<<INTF1) | (0<<INTF0);
// SPI initialization
// SPI Type: Master
// SPI Clock Rate: 2000.000 kHz
// SPI Clock Phase: Cycle Start
// SPI Clock Polarity: Low
// SPI Data Order: MSB First
SPCR=(1<<SPIE) | (1<<SPE) | (0<<DORD) | (1<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (0<<SPR0);
SPSR=(0<<SPI2X);
// Clear the SPI interrupt flag
#asm
in r30,spsr
in r30,spdr
#endasm
// Global enable interrupts
#asm("sei")
}
//Function to send and receive data for both master and slave
unsigned char SPI(unsigned char data)
{
// Load data into the buffer
SPDR = data;
//Wait until transmission complete
while(!(SPSR & (1<<SPIF) ));
SPSR = (1<<SPIF);
// Return received data
return(SPDR);
}
/* CE is set to output */
#define NRF24L01_CE_OUT DDRB |= (1<<DDB1) ;
#define NRF24L01_CE_HIGH PORTB |= (1<<DDB1) ;
#define NRF24L01_CE_LOW PORTB &= ~(1<<DDB1);
#define NRF24L01_CSN_HIGH PORTB |= (1<<DDB2) ;
#define NRF24L01_CSN_LOW PORTB &= ~(1<<DDB2);
/**
Read a register
@param Reg Register to read
@return Registry Value
*/
char NRF24L01_ReadReg(char Reg) {
char Result;
NRF24L01_CSN_LOW;
SPI(Reg);
Result = SPI(NOP); // "NOP" in here just roles as a dummy data byte nothing more.
NRF24L01_CSN_HIGH;
return Result;
}
/**
Returns the STATUS register and then modify a register
@param Reg Register to change
@param Value New value
@return STATUS Register
*/
char NRF24L01_WriteReg(char Reg, char Value) {
char Result;
NRF24L01_CSN_LOW;
Result = SPI(Reg);
SPI(Value);
NRF24L01_CSN_HIGH;
return Result;
}
/**
Returns the STATUS register and then read "n" registers
@param Reg Register to read
@param Buf Pointer to a buffer
@param Size Buffer Size
@return STATUS Register
*/
char NRF24L01_ReadRegBuf(char Reg, char *Buf, int Size) {
int i;
char Result;
NRF24L01_CSN_LOW;
Result = SPI(Reg);
for (i = 0; i < Size; i++) {
Buf[i] = SPI(NOP);
}
NRF24L01_CSN_HIGH;
return Result;
}
/**
Returns the STATUS register and then write "n" registers
@param Reg Registers to change
@param Buf Pointer to a buffer
@param Size Buffer Size
@return STATUS Register
*/
char NRF24L01_WriteRegBuf(char Reg, char *Buf, int Size) {
int i;
char Result;
NRF24L01_CSN_LOW;
Result = SPI(Reg);
for (i = 0; i < Size; i++) {
SPI(Buf[i]);
}
NRF24L01_CSN_HIGH;
return Result;
}
/**
Returns the STATUS register
@return STATUS Register
*/
char NRF24L01_Get_Status(void) {
char Result;
NRF24L01_CSN_LOW;
Result = SPI(NOP);
NRF24L01_CSN_HIGH;
return Result;
}
/**
Returns the carrier signal in RX mode (high when detected)
@return CD
*/
char NRF24L01_Get_CD(void) {
return (NRF24L01_ReadReg(CD) & 1);
}
/**
Select power mode
@param Mode = _POWER_DOWN, _POWER_UP
@see _POWER_DOWN
@see _POWER_UP
*/
void NRF24L01_Set_Power(char Mode) {
char Result;
Result = NRF24L01_ReadReg(CONFIG) & 0b01111101; // Read Conf. Reg. AND Clear bit 1 (PWR_UP) and 7 (Reserved)
NRF24L01_WriteReg(W_REGISTER | CONFIG, Result | Mode);
}
/**
Select the radio channel
@param CH = 0..125
*/
void NRF24L01_Set_CH(char CH) {
NRF24L01_WriteReg(W_REGISTER | RF_CH, (CH & 0b01111111)); // Clear bit 8
}
/**
Select Enhanced ShockBurst ON/OFF
Disable this functionality to be compatible with nRF2401
@param Mode = _ShockBurst_ON, _ShockBurst_OFF
@see _ShockBurst_ON
@see _ShockBurst_OFF
*/
void NRF24L01_Set_ShockBurst(char Mode) {
NRF24L01_WriteReg(W_REGISTER | SETUP_RETR, Mode);
NRF24L01_WriteReg(W_REGISTER | EN_AA, Mode);
}
/**
Select the address width
@param Width = 3..5
*/
void NRF24L01_Set_Address_Width(char Width) {
NRF24L01_WriteReg(W_REGISTER | SETUP_AW, (Width - 2)); // orginal was (Width & 3) -2) but is incorrect
}
/**
Select mode receiver or transmitter
@param Device_Mode = _TX_MODE, _RX_MODE
@see _TX_MODE
@see _RX_MODE
*/
void NRF24L01_Set_Device_Mode(char Device_Mode) {
char Result;
Result = NRF24L01_ReadReg(CONFIG) & 0b01111110; // Read Conf. Reg. AND Clear bit 0 (PRIM_RX) and 7 (Reserved)
NRF24L01_WriteReg(W_REGISTER | CONFIG, Result | Device_Mode);
}
/**
Enables and configures the pipe receiving the data
@param PipeNum Number of pipe
@param Address Address
@param AddressSize Address size
@param PayloadSize Buffer size, data receiver
*/
void NRF24L01_Set_RX_Pipe(char PipeNum, char *Address, int AddressSize, char PayloadSize) {
char Result;
Result = NRF24L01_ReadReg(EN_RXADDR);
NRF24L01_WriteReg(W_REGISTER | EN_RXADDR, Result | (1 << PipeNum));
NRF24L01_WriteReg(W_REGISTER | (RX_PW_P0 + PipeNum), PayloadSize);
NRF24L01_WriteRegBuf(W_REGISTER | (RX_ADDR_P0 + PipeNum), Address, AddressSize);
}
/**
Disable all pipes
*/
void NRF24L01_Disable_All_Pipes(void) {
NRF24L01_WriteReg(W_REGISTER | EN_RXADDR, 0);
}
/** Returns the STATUS register and then clear all interrupts
*
* @return STATUS Register
*/
char NRF24L01_Clear_Interrupts(void) {
return NRF24L01_WriteReg(W_REGISTER | STATUS, _RX_DR | _TX_DS | _MAX_RT);
}
/**
Sets the direction of transmission
@param Address Address
@param Size Address size 3..5
*/
void NRF24L01_Set_TX_Address(char *Address, int Size) {
NRF24L01_WriteRegBuf(W_REGISTER | TX_ADDR, Address, Size);
}
/**
Empty the transmit buffer
*/
void NRF24L01_Flush_TX(void) {
NRF24L01_CSN_LOW;
SPI(FLUSH_TX);
NRF24L01_CSN_HIGH;
}
/**
Empty the receive buffer
*/
void NRF24L01_Flush_RX(void) {
NRF24L01_CSN_LOW;
SPI(FLUSH_RX);
NRF24L01_CSN_HIGH;
}
/**
Initializes the device
@param Device_Mode = _TX_MODE, _RX_MODE
@param CH = 0..125
@param DataRate = _1Mbps, _2Mbps
@param Address Address
@param Address_Width Width direction: 3..5
@param Size_Payload Data buffer size
@see _TX_MODE
@see _RX_MODE
@see _1Mbps
@see _2Mbps
*/
void NRF24L01_Init(char Device_Mode, char CH, char DataRate,
char *Address, char Address_Width, char Size_Payload) {
NRF24L01_CE_OUT; // Set Port DIR out
// Enable Enhanced ShockBurst....._ShockBurst_OFF
NRF24L01_Set_ShockBurst(_ShockBurst_ON);
// RF output power in TX mode = 0dBm (Max.)
// Set LNA gain
NRF24L01_WriteReg(W_REGISTER | RF_SETUP, 0b00000111 | DataRate);
NRF24L01_Set_Address_Width(Address_Width);
NRF24L01_Set_RX_Pipe(0, Address, Address_Width, Size_Payload);
NRF24L01_Set_CH(CH);
NRF24L01_Set_TX_Address(Address, Address_Width); // Set Transmit address
// Bits 4..6: Reflect interrupts as active low on the IRQ pin
// Bit 3: Enable CRC
// Bit 2: CRC 1 Byte
// Bit 1: Power Up
NRF24L01_WriteReg(W_REGISTER | CONFIG, 0b00001010 | Device_Mode);
delay_us(1500);
}
/**
Turn on transmitter, and transmits the data loaded into the buffer
*/
void NRF24L01_RF_TX(void) {
NRF24L01_CE_LOW;
NRF24L01_CE_HIGH;
delay_us(10);
NRF24L01_CE_LOW;
}
/**
Writes the buffer of data transmission
@param Buf Buffer with data to send
@param Size Buffer size
*/
void NRF24L01_Write_TX_Buf(char *Buf, int Size) {
NRF24L01_WriteRegBuf(W_REGISTER | W_TX_PAYLOAD, Buf, Size);
}
/**
Read the data reception buffer
@param Buf Buffer with data received
@param Size Buffer size
*/
void NRF24L01_Read_RX_Buf(char *Buf, int Size) {
NRF24L01_ReadRegBuf(R_RX_PAYLOAD, Buf, Size);
}
我无法理解这是什么问题.. 请帮帮我谢谢?!
AND HERE是nrf24l01 + .h定义
/*
* @author
* Copyright (C) 2012 Luis R. Hilario http://www.luisdigital.com
*
*/
// Bits
/**
* Data Ready RX FIFO interrupt
*/
#define _RX_DR (1<<6)
/**
* Data Sent TX FIFO interrupt
*/
#define _TX_DS (1<<5)
/**
* Maximum number of TX retransmits interrupt
*/
#define _MAX_RT (1<<4)
/** Power Down mode
*
* Minimal current consumption, SPI can be activated
*
* @see NRF24L01_Set_Power(char Mode)
*/
#define _POWER_DOWN 0
/** Power Up mode
*
* Standby-I mode
*
* @see NRF24L01_Set_Power(char Mode)
*/
#define _POWER_UP (1<<1)
/** Mode radio transmitter
*
* @see NRF24L01_Set_Device_Mode(char Device_Mode)
* @see NRF24L01_Init(char Device_Mode, char CH, char DataRate,
char *Address, char Address_Width, char Size_Payload)
*/
#define _TX_MODE 0
/** Mode radio receiver
*
* @see NRF24L01_Set_Device_Mode(char Device_Mode)
* @see NRF24L01_Init(char Device_Mode, char CH, char DataRate,
char *Address, char Address_Width, char Size_Payload)
*/
#define _RX_MODE 1
/** Air data rate = 1 Mbps
*
*
* @see NRF24L01_Init(char Device_Mode, char CH, char DataRate,
char *Address, char Address_Width, char Size_Payload)
*/
#define _1Mbps 0
/** Air data rate = 2 Mbps
*
* @see NRF24L01_Init(char Device_Mode, char CH, char DataRate,
char *Address, char Address_Width, char Size_Payload)
*/
#define _2Mbps (1<<3)
/** Enable ShockBurst
Automatic Retransmission (Up to 1 Re-Transmit on fail of AA)
Auto Acknowledgment (data pipe 0)
@see NRF24L01_Set_ShockBurst(char Mode)
*/
#define _ShockBurst_ON 1
/** Disable ShockBurst
*
@see NRF24L01_Set_ShockBurst(char Mode)
*/
#define _ShockBurst_OFF 0
// REGISTERS
#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
#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
#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
#define DYNPD 0x1C
#define FEATURE 0x1D
// COMMANDS
#define R_REGISTER 0x00
#define W_REGISTER 0x20
#define R_RX_PAYLOAD 0x61
#define W_TX_PAYLOAD 0xA0
#define FLUSH_TX 0xE1
#define FLUSH_RX 0xE2
#define REUSE_TX_PL 0xE3
#define ACTIVATE 0x50
#define R_RX_PL_WID 0x60
#define W_ACK_PAYLOAD 0xA8
#define W_TX_PAYLOAD_NOACK 0x58
#define NOP 0xFF
/*
* SPI functions for NRF24L01
*/
char NRF24L01_ReadReg(char Reg);
char NRF24L01_WriteReg(char Reg, char Value);
char NRF24L01_ReadRegBuf(char Reg, char *Buf, int Size);
char NRF24L01_WriteRegBuf(char Reg, char *Buf, int Size);
/*
* NRF24L01 functions
*/
char NRF24L01_Get_Status(void);
char NRF24L01_Get_CD(void);
void NRF24L01_Set_Power(char Mode);
void NRF24L01_Set_CH(char CH);
void NRF24L01_Set_ShockBurst(char Mode);
void NRF24L01_Set_Address_Width(char Width);
void NRF24L01_Set_Device_Mode(char Device_Mode);
void NRF24L01_Set_RX_Pipe(char PipeNum, char *Address, int AddressSize, char PayloadSize);
void NRF24L01_Disable_All_Pipes(void);
char NRF24L01_Clear_Interrupts(void);
void NRF24L01_Set_TX_Address(char *Address, int Size);
void NRF24L01_Flush_TX(void);
void NRF24L01_Flush_RX(void);
void NRF24L01_Init(char Device_Mode, char CH, char DataRate,
char *Address, char Address_Width, char Size_Payload);
void NRF24L01_RF_TX(void);
void NRF24L01_Write_TX_Buf(char *Buf, int Size);
void NRF24L01_Read_RX_Buf(char *Buf, int Size);
答案 0 :(得分:0)
你好朋友我成功了,我能够通过nrf24l01 +模块将数据发送到另一个nrf24l01 +模块,我用ATMEGA16A作为TX,ATmega8a作为RX(接收器)控制器: 我使用了一些好人编写的链接中的代码并且它工作正常但我需要更改som i / o端口以便与接收器模块的Atmega8兼容。 因为我将我的最后一个代码与这个代码进行比较,我理解我改变了rx和tx地址,并且在此代码中(运行良好)没有任何与模块的地址相关的更改并保留其默认值。 所以我的错误是错误地操纵了地址..
这里是代码工作良好的链接..
更新:当我重新访问我的代码以查看最新问题时,我理解整个问题来自nrf24l01.h文件,它声明了一个函数misdingushly它发送W_TX_PAYLOAD ORing和W_REGISTER,而nrf中不存在这样的地址所以整个过程是错了.. 错误在于声明: 'NRF24L01_Write_TX_Buf'功能 排队: NRF24L01_WriteRegBuf(W_REGISTER | W_TX_PAYLOAD,Buf,Size); 虽然这是错误的,必须更正为:
NRF24L01_WriteRegBuf(W_TX_PAYLOAD,Buf,Size); wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww