ATMega8 + nrf24l01 : помогите, не работает связь
Добавлено: Сб дек 01, 2012 01:59:37
Подскажите, куда смотреть;
итог работы на передатчике:
TX=e =1110 =1110 =1110 =1110 и т.д.
По spi успешно общаются, а как проверить передатчик - не знаю.
Ни 4, ни 5 биты не устанавливаются. Т.е. от приёмника ни ack, ни превышения попыток.
В приёмнике RX_DR тоже не устанавливается.
Без ack пробовал, тоже данных нет.
Запускаются, естественно одновременно
итог работы на передатчике:
TX=e =1110 =1110 =1110 =1110 и т.д.
По spi успешно общаются, а как проверить передатчик - не знаю.
Ни 4, ни 5 биты не устанавливаются. Т.е. от приёмника ни ack, ни превышения попыток.
В приёмнике RX_DR тоже не устанавливается.
Без ack пробовал, тоже данных нет.
Запускаются, естественно одновременно
Код: Выделить всё
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <string.h>
#include <stdlib.h>
#include "xUART.cpp"
#define SPI_DDR DDRB
#define SPI_PORT PORTB
#define SPI_MISO PB4
#define SPI_MOSI PB3
#define SPI_SCK PB5
#define SPI_SS PB2
void spi_init() {
SPI_DDR &= ~( (1<<SPI_MOSI) | (1<<SPI_MISO) | (1<<SPI_SS) | (1<<SPI_SCK) ); //input
SPI_DDR |= ( (1<<SPI_MOSI) | (1<<SPI_SS) | (1<<SPI_SCK) ); //output
SPCR = (
(1<<SPE)| // SPI Enable
(0<<SPIE)| // SPI Interrupt Enable
(0<<DORD)| // Data Order (0:MSB first / 1:LSB first)
(1<<MSTR)| // Master/Slave select
(0<<SPR1)|(1<<SPR0)| // SPI Clock Rate
(0<<CPOL)| // Clock Polarity (0:SCK low / 1:SCK hi when idle)
(0<<CPHA) // Clock Phase (0:leading / 1:trailing edge sampling)
);
SPSR = (1<<SPI2X); // Double SPI Speed Bit
}
#define TX_ADR_WIDTH 5 // 5 unsigned chars TX(RX) address width
#define TX_PLOAD_WIDTH 32 // 32 unsigned chars TX payload
//unsigned char TX_ADDRESS[TX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01}; // Define a static TX address
unsigned char TX_ADDRESS[TX_ADR_WIDTH] = {0x77,0x77,0x10,0x10,0x01}; // Define a static TX address
unsigned char rx_buf[TX_PLOAD_WIDTH] = {0}; // initialize value
unsigned char tx_buf[TX_PLOAD_WIDTH] = {0};
// SPI(nRF24L01) commands
#define READ_REG 0x00 // Define read command to register
#define WRITE_REG 0x20 // Define write command to register
#define RD_RX_PLOAD 0x61 // Define RX payload register address
#define WR_TX_PLOAD 0xA0 // Define TX payload register address
#define FLUSH_TX 0xE1 // Define flush TX register command
#define FLUSH_RX 0xE2 // Define flush RX register command
#define REUSE_TX_PL 0xE3 // Define reuse TX payload register command
#define NOP 0xFF // Define No Operation, might be used to read status register
//***************************************************
#define RX_DR 0x40
#define TX_DS 0x20
#define MAX_RT 0x10
//***************************************************
// SPI(nRF24L01) registers(addresses)
#define CONFIG 0x00 // 'Config' register address
#define EN_AA 0x01 // 'Enable Auto Acknowledgment' register address
#define EN_RXADDR 0x02 // 'Enabled RX addresses' register address
#define SETUP_AW 0x03 // 'Setup address width' register address
#define SETUP_RETR 0x04 // 'Setup Auto. Retrans' register address
#define RF_CH 0x05 // 'RF channel' register address
#define RF_SETUP 0x06 // 'RF setup' register address
#define STATUS 0x07 // 'Status' register address
#define OBSERVE_TX 0x08 // 'Observe TX' register address
#define CD 0x09 // 'Carrier Detect' register address
#define RX_ADDR_P0 0x0A // 'RX address pipe0' register address
#define RX_ADDR_P1 0x0B // 'RX address pipe1' register address
#define RX_ADDR_P2 0x0C // 'RX address pipe2' register address
#define RX_ADDR_P3 0x0D // 'RX address pipe3' register address
#define RX_ADDR_P4 0x0E // 'RX address pipe4' register address
#define RX_ADDR_P5 0x0F // 'RX address pipe5' register address
#define TX_ADDR 0x10 // 'TX address' register address
#define RX_PW_P0 0x11 // 'RX payload width, pipe0' register address
#define RX_PW_P1 0x12 // 'RX payload width, pipe1' register address
#define RX_PW_P2 0x13 // 'RX payload width, pipe2' register address
#define RX_PW_P3 0x14 // 'RX payload width, pipe3' register address
#define RX_PW_P4 0x15 // 'RX payload width, pipe4' register address
#define RX_PW_P5 0x16 // 'RX payload width, pipe5' register address
#define FIFO_STATUS 0x17 // 'FIFO Status Register' register address
...
#define writeCE_0 writeB00
#define writeCE_1 writeB01
#define writeCSN_0 writeB10
#define writeCSN_1 writeB11
#define writeIRQ_0 writeD20
#define writeIRQ_1 writeD21
unsigned char SPI_RW(unsigned char data)
{
SPDR = data;
while ((SPSR & (1<<SPIF)) == 0);
return SPDR;
}
unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value)
{
unsigned char status;
writeCSN_0; // CSN low, init SPI transaction
SPI_RW(reg); // select register
SPI_RW(value); // ..and write value to it..
writeCSN_1; // CSN high again
return(status); // return nRF24L01 status unsigned char
}
unsigned char SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
{
unsigned char sstatus,i;
writeCSN_0; // Set CSN low, init SPI tranaction
sstatus = SPI_RW(reg); // Select register to write to and read status unsigned char
for(i=0;i<bytes; i++) // then write all unsigned char in buffer(*pBuf)
{
SPI_RW(*pBuf++);
}
writeCSN_1; // Set CSN high again
return(sstatus); // return nRF24L01 status unsigned char
}
unsigned char SPI_Read(unsigned char reg)
{
unsigned char reg_val;
writeCSN_0; // CSN low, initialize SPI communication...
SPI_RW(reg); // Select register to read from..
reg_val = SPI_RW(0); // ..then read register value
writeCSN_1; // CSN high, terminate SPI communication
return(reg_val); // return register value
}
unsigned char SPI_Read_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
{
unsigned char sstatus,i;
writeCSN_0; // Set CSN low, init SPI tranaction
sstatus = SPI_RW(reg); // Select register to write to and read status unsigned char
for(i=0;i<bytes;i++)
{
pBuf[i] = SPI_RW(0); // Perform SPI_RW to read unsigned char from nRF24L01
}
writeCSN_1; // Set CSN high again
return(sstatus); // return nRF24L01 status unsigned char
}
#define MakeTX
#ifdef MakeRX
int main(void)
{
// Receiver
xUartInit();
setB0Output; // CE - B0 (Chip enable)
setB1Output; // CSN - B1 (SPI disable)
setD2Input; // IRQ - D2
spi_init();
_delay_ms(55);
writeIRQ_0;
writeCE_0;
writeCSN_1;
unsigned char sstatus=SPI_Read(STATUS);
xUartSend('R');
xUartSend('X');
xUartSend('=');
char stmp[10]={0};
itoa( sstatus , stmp , 16 );
xUartSendString( stmp ); // must be E
xUartSend(' ');
// RX Mode
writeCE_0;
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // addr TX = addr RX
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);
SPI_RW_Reg(WRITE_REG + RF_CH, 40);
SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH);
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);
writeCE_1; // Set CE pin high to enable RX device
for(;;)
{
unsigned char status = SPI_Read(STATUS); // read register STATUS's value
if(status&RX_DR) // if receive data ready (TX_DS) interrupt
{
SPI_Read_Buf(RD_RX_PLOAD, rx_buf, TX_PLOAD_WIDTH); // read playload to rx_buf
SPI_RW_Reg(FLUSH_RX,0); // clear RX_FIFO
xUartSend('_');
for(int i=0; i<32; i++)
{
itoa( rx_buf[i] , stmp , 2 );
xUartSendString( stmp );
xUartSend('.');
}
xUartSend(' ');
xUartSend(' ');
}
SPI_RW_Reg(WRITE_REG+STATUS,status); // clear RX_DR or TX_DS or MAX_RT interrupt flag
_delay_ms(1000);
}
}
#endif
#ifdef MakeTX
int main(void)
{
// TX v2
xUartInit();
setB0Output; // CE - B0 (Chip enable)
setB1Output; // CSN - B1 (SPI disable)
setD2Input; // IRQ - D2
spi_init();
_delay_ms(155);
writeIRQ_0;
writeCE_0;
writeCSN_1;
unsigned char sstatus=SPI_Read(STATUS);
xUartSend('T');
xUartSend('X');
xUartSend('=');
char stmp[10]={0};
itoa( sstatus , stmp , 16 );
xUartSendString( stmp ); // must be E
xUartSend(' ');
// TX Mode
writeCE_0;
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // Writes TX_Address to nRF24L01
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.Ack
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10 retrans...
SPI_RW_Reg(WRITE_REG + RF_CH, 40); // Select RF channel 40
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // Set PWR_UP bit, enable CRC(2 unsigned chars) & Prim:TX. MAX_RT & TX_DS enabled..
SPI_Write_Buf(WR_TX_PLOAD,tx_buf,TX_PLOAD_WIDTH);
writeCE_1;
for(;;)
{
for(int i=0; i<32; i++)
tx_buf[i] = 'a'+i;
unsigned char sstatus = SPI_Read(STATUS); // read register STATUS's value
itoa( sstatus , stmp , 2 );
xUartSend(' ');
xUartSend('=');
xUartSendString( stmp ); // must be E
xUartSend(' ');
xUartSend(' ');
xUartSend(' ');
if ( sstatus&TX_DS ) // if receive data ready (TX_DS) interrupt
{
xUartSend('!');
SPI_RW_Reg(FLUSH_TX,0);
SPI_Write_Buf(WR_TX_PLOAD,tx_buf,TX_PLOAD_WIDTH); // write playload to TX_FIFO
}
if ( sstatus&MAX_RT ) // if receive data ready (MAX_RT) interrupt, this is retransmit than SETUP_RETR
{
xUartSend('$');
SPI_RW_Reg(FLUSH_TX,0);
SPI_Write_Buf(WR_TX_PLOAD,tx_buf,TX_PLOAD_WIDTH); // disable standy-mode
}
SPI_RW_Reg(WRITE_REG+STATUS,sstatus); // clear RX_DR or TX_DS or MAX_RT interrupt flag
_delay_ms(1000);
}
}
#endif