всем привет!
помогите плиииз портировать код nRF24L01 на аttiny84
с мк занимаюсь не очень давно, подскажите что требуется изменить в этом коде
к сожалению требуется реализация именно на этом мк.
заранее признателен
rx.c
nRF24L01.h
помогите плиииз портировать код nRF24L01 на аttiny84
с мк занимаюсь не очень давно, подскажите что требуется изменить в этом коде
к сожалению требуется реализация именно на этом мк.
заранее признателен
rx.c
Спойлер
Код: Выделить всё
#define F_CPU 8000000UL // 8 MHz
/* 9600 baud */
#define UART_BAUD_RATE 9600
#define DataLen 5 // length of data packet sent / received
#include <avr/io.h>
#include <stdio.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "uart.h"
#include "nRF24L01.h"
#include "lcd.h"
uint8_t *data;
/***************** SPI *****************************/ // Sending data between the chip and the chip nrf'ens
// Initialization
void InitSPI ( void )
{
// Set SCK (PB5), MOSI (PB3), CSN (SS & PB2) & C as outport
// NOTE! Must be set before the SPI Enable neadn
DDRB |= (1<<DDB5 ) | ( 1 << DDB3 ) | ( 1 << DDB2 ) | ( 1 << DDB1 );
/* Enable SPI, Master, set clock rate fck/16 .. can change the speed but it does so much */
SPCR |= ( 1 << SPE ) | ( 1 << MSTR );// | (1 << SPR0) | (1 << SPR1);
SETBIT(PORTB,2); // CSN IR_High to start with, we will not send anything to nrf'en yet!
CLEARBIT(PORTB,1); // CE low to start with, nrf'en will not send / receive anything yet!
}
// Send command to nrf'en on then get back a byte
char WriteByteSPI ( unsigned char CDATA )
{
// Load Byte to Data register
SPDR = CDATA ;
/* Wait for transmission complete */
while (!(SPSR & (1<<SPIF)));
// Return what was sent back by nrf'en (first time after csn-low will Statusregistert)
return SPDR ;
}
void ioinit(){
}
// When data is received / sent as goes interr uptet INT0 second-bottom running
void INT0_interrupt_init ( void )
{
DDRD &= ~(1 << DDD2); // Clear the PD2 pin
// PD2 (INT0 pin) is now an input
////PORTD |= (1 << PORTD2); // turn On the Pull-up
// PD0 is now an input with pull-up enabled
MCUCR |=(1<<ISC01); // INT0 falling edge PD2
MCUCR &=~(1<<ISC00); // INT0 falling edge PD2
GICR |=(1<<INT0); // enablar int0
sei (); // Enable global interrupts are then
}
uint8_t *WriteToNrf(uint8_t ReadWrite,uint8_t reg,uint8_t *val,uint8_t antVal) // takes in "ReadWrite" (W el R), "reg" (a record), "* Choice" (an array) & "antVal" (number integer in the variable)
{
//"ReadWrite" ("W" or "R"), "reg" (the register), "*val" (an array with the package) & "antVal" (number of integers in the package)
////cei();
if(ReadWrite == W) // W = want to write to nrf-one (R = read of it, R_REGISTER (0x00), so do not care one else function)
{
reg=W_REGISTER + reg; // example: reg = EN_AA: 0b0010 0000 + 0001 = 0b0000 0b0010 0001
}
// Static uint8_t for it to go to return an array (note the "*" on the top tool!)
static uint8_t ret[32]; // assume that the longest you want to read when they call the "R" is dataleng-far, that uses only 1 byte datalengd the want to read out 5bytes RF_Adress so write 5 here ist!
_delay_us(10); // all the delay is such that the NRF will manage! (Micro seconds)
CLEARBIT(PORTB,2); // CSN low = nrf chip starts listening
_delay_us(10);
WriteByteSPI(reg); // first SPI command after CSN was telling nrf'en which of its records to be edited as: 0b0010 0001 write to registry EN_AA
_delay_us(10);
int i;
for (i=0;i<antVal;i++)
{
if (ReadWrite == R && reg!= W_TX_PAYLOAD)
{
ret[i]=WriteByteSPI(NOP); // other and the rest of the SPI command tells the NRF which values ??in this case should be read
_delay_us(10);
}
else
{
WriteByteSPI(val[i]); // other and the rest of the SPI command tells the NRF which values ??in this case should be written to
_delay_us(10);
}
}
SETBIT(PORTB,2); // CSN IR_High = nrf chip stop listening
////sei(); // enable global interrupt
return ret; // returns an array
}
// Resets nrf'en for new communication
void reset(void)
{
_delay_us(10);
CLEARBIT(PORTB,2); // CSN Low
_delay_us(10);
WriteByteSPI(W_REGISTER + STATUS); //
_delay_us(10);
WriteByteSPI(0x70); // conditioned pulls all interrupts in the status register (to be able to listen again)
_delay_us(10);
SETBIT(PORTB,2); // CSN IR_High
}
//Function to retrieve some thing of nrf's records
uint8_t GetReg(uint8_t reg)
{
// Internal uses: USART_Transmit (GetReg (STATUS)); // Where the status of the registry to Check
_delay_us(10);
CLEARBIT (PORTB,2); // CSN Low
_delay_us(10);
WriteByteSPI(R_REGISTER+reg); // Which registry would you like to read (now with R_Register because nothing will be written to register)
_delay_us(10);
reg=WriteByteSPI(NOP); // Send NOP number of bytes you want to download (usually 1gång, but eg addr is 5 bytes!) and save isf not in the "reg", but an array using a loop
_delay_us(10);
SETBIT(PORTB,2); // CSN IR_High
return reg; // Returns the registry hopefully with bit5 = 1 (tx_ds = successful transmission)
}
// Initialize nrf'en (note the NRF must vala to sleep when this happens CE low)
void nrf24L01_init(void)
{
_delay_ms(100); // allow the radio to reach power-down if the shutdown
uint8_t val[5]; // an array of integers that sends values ??to WriteToNrf function
//EN_AA - (enable auto-acknowledgments) - Transmitter gets automatic response from receiver when successful transmission! (lovely function!)
//Only works if Transmitter has identical RF_Adress on its channel ex: RX_ADDR_Po = TX_ADDR
val[0]=0x01; //set value
WriteToNrf(W, EN_AA, val, 1); //N=write mode, EN_AA=register to write to, val=data to write, 1=number of data bytes.
//Choose number of enabled data pipes (1-5)
val[0]=0x01;
WriteToNrf(W, EN_RXADDR, val, 1); //enable data pipe 0
//RF_Adress width setup (how many bytes is the receiver address, the more the merrier 1-5)
val[0]=0x03; //0b0000 00011 = 5 bytes RF_Adress
WriteToNrf(W, SETUP_AW, val, 1);
// RF channel setup - select the frequency from 2.400 to 2.527 GHz 1MHz/steg
val[0] = 0x01 ;
WriteToNrf(W,RF_CH,val,1); // RF channel registry 0b0000 0001 = 2.401 GHz (same on the TX RX)
//RF setup - choose power mode and data speed. Here is the diference with the (+) version!!!
val[0]=0x27; //00000111 bit 3="0" 1Mbps=longer range, bit 2-1 power mode ("11" = -odB ; "00"=-18dB)
WriteToNrf(W, RF_SETUP, val, 1);
//RF_Adress setup 5 byte - Set Receiver address (set RX_ADDR_Po = TX_ADDR if EN_AA is enabled!!!)
int i=0;
for(i=0; i<5; i++){
val[i]=0x11; //ox12 x 5 to get a long and secure address.
}
WriteToNrf(W, RX_ADDR_P0, val, 5); //since we chose pipe 0 on EN_RXADDR we give this address to that channel.
//Here you can give different addresses to different channels (if they are enabled in EN_RXADDR) to listen on several different transmitters)
//TX RF_Adress setup 5 byte - Set Transmitter address (not used in a receiver but can be set anyway)
for(i=0; i<5; i++){
val[i]=0x11; //ox12 x 5 - same on the Receiver chip and the RX-RF_Address above if EN_AA is enabled!!!
}
WriteToNrf(W, TX_ADDR, val, 5);
//Payload width Setup - 1-32byte (how many bytes to send per transmission)
val[0]=0x05; //Send 5 bytes per package this time (same on receiver and transmitter)
WriteToNrf(W,RX_PW_P0,val,1);
val[0]=0x2F; //0b00l0 00011 "2" sets it up to 7SouS delay between every retry (at least Seeus at 25okbps and if payload >5bytes in 1Hbps,
//and if payload >1Sbyte in 2Hbps) "F" is number of retries (1-15, now 15)
WriteToNrf(W, SETUP_RETR, val, 1);
//CONFIG reg setup - Now it's time to boot up the Qgf and choose if it's suppose to be a transmitter or receiver
val[0]=0x1E; //0b0001 1110 - bit 0="0":transmitter bit 0="1":Receiver, bit 1="1"=power up,
//bit 4="1"= mask_Max_RT i.e. IRQ-interrupt is not triggered if transmission failed.
WriteToNrf(W, CONFIG, val, 1);
//device need 1.5ms to reach standby mode (CE=low)
_delay_ms(100);
// Sei ();
}
// The receiver opens and "Listening" in 1s
void receive_payload ( void )
{
//sei(); // Enable global interrupt
SETBIT(PORTB,1); // CE IR_High = "Listening"
_delay_ms(1000); // listening in 1s and received goes int0-interruptvektor Started
CLEARBIT(PORTB,1); // ce low back-stop listening
//cli(); // Disable the global interrupt
}
// Send the data
void transmit_payload( uint8_t *W_buff)
{
WriteToNrf(R,FLUSH_TX,W_buff,0); // send 0xE1 which flushes the registry to old data should not be on the wait to be sent when you want to send the new data! R stands for W_REGISTER not be added. sends no command efterråt because it is not needed! W_buff [] is just there to an array has to be there ...
WriteToNrf(R,W_TX_PAYLOAD,W_buff,DataLen); // send data in W_buff to nrf-one (note can not be read w_tx_payload registry!)
//sei(); // enable global interrupt already!
// USART_Transmit (GetReg (STATUS));
_delay_ms(10); // need to be really ms, not us?? YEEES! otherwise it will not work!
SETBIT(PORTB,1); // CE high = send data INT0 interruptet running when the transmission was successful and if EN_AA is on, also the response of the receiver is received
_delay_us ( 20 ); // at least 10us!
CLEARBIT(PORTB,1); // CE low
_delay_ms(10); // need to be really ms, not us?? YEEES! otherwise it will not work!
// Cli (); // Disable the global interrupt ... ajabaja, then closes USART_RX-listening to!
}
int main(void)
{
lcd_init(LCD_DISP_ON);
lcd_puts("LCD init");
_delay_ms(500);
lcd_clrscr();
InitSPI();
lcd_puts("SPI init");
_delay_ms(500);
lcd_clrscr();
ioinit();
INT0_interrupt_init();
lcd_puts("INT0 init");
_delay_ms(500);
lcd_clrscr();
nrf24L01_init();
lcd_puts("NRF init");
_delay_ms(500);
lcd_clrscr();
////uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
////lcd_puts("USART init");
////_delay_ms(500);
////lcd_clrscr();
//sei();
//Clear the screen
lcd_clrscr();
char buffer[5];
lcd_puts("STATUS:");
itoa( GetReg(STATUS), buffer, 16); // convert interger into string (decimal format)
lcd_puts(buffer); // and transmit string to UART
_delay_ms(500);
lcd_clrscr();
lcd_puts("TEST:");
itoa(0xBC, buffer, 16); // convert interger into string (decimal format)
lcd_puts(buffer); // and transmit string to UART
_delay_ms(500);
lcd_clrscr();
lcd_puts("EA_AA:");
itoa( GetReg(EN_AA), buffer, 16); // convert interger into string (decimal format)
lcd_puts(buffer); // and transmit string to UART
_delay_ms(500);
lcd_clrscr();
lcd_puts("EN_RXADDR:");
itoa( GetReg(EN_RXADDR), buffer, 16); // convert interger into string (decimal format)
lcd_puts(buffer); // and transmit string to UART
_delay_ms(500);
lcd_clrscr();
lcd_puts("SETUP_AW:");
itoa( GetReg(SETUP_AW), buffer, 16); // convert interger into string (decimal format)
lcd_puts(buffer); // and transmit string to UART
_delay_ms(500);
lcd_clrscr();
lcd_puts("RF_CH:");
itoa( GetReg(RF_CH), buffer, 16); // convert interger into string (decimal format)
lcd_puts(buffer); // and transmit string to UART
_delay_ms(500);
lcd_clrscr();
lcd_puts("RF_SETUP:");
itoa( GetReg(RF_SETUP), buffer, 16); // convert interger into string (decimal format)
lcd_puts(buffer); // and transmit string to UART
_delay_ms(500);
lcd_clrscr();
lcd_puts("RX_ADDR_P0:");
itoa( GetReg(RX_ADDR_P0), buffer, 16); // convert interger into string (decimal format)
lcd_puts(buffer); // and transmit string to UART
_delay_ms(500);
lcd_clrscr();
lcd_puts("TX_ADDR:");
itoa( GetReg(TX_ADDR), buffer, 16); // convert interger into string (decimal format)
lcd_puts(buffer); // and transmit string to UART
_delay_ms(500);
lcd_clrscr();
lcd_puts("RX_PW_P0:");
itoa( GetReg(RX_PW_P0), buffer, 16); // convert interger into string (decimal format)
lcd_puts(buffer); // and transmit string to UART
_delay_ms(500);
lcd_clrscr();
lcd_puts("SETUP_RETR:");
itoa( GetReg(SETUP_RETR), buffer, 16); // convert interger into string (decimal format)
lcd_puts(buffer); // and transmit string to UART
_delay_ms(500);
lcd_clrscr();
lcd_puts("CONFIG:");
itoa( GetReg(CONFIG), buffer, 16); // convert interger into string (decimal format)
lcd_puts(buffer); // and transmit string to UART
_delay_ms(500);
lcd_clrscr();
while(1){
reset();
int i;
for (i=0;i<5;i++)
{
buffer[i]=0x93;
}
transmit_payload(buffer);
lcd_puts("STATUS:");
itoa( GetReg(STATUS), buffer, 16); // convert interger into string (decimal format)
lcd_puts(buffer); // and transmit string to UART
_delay_ms(500);
lcd_clrscr();
}
return 0;
}
ISR(INT0_vect) // vector that is triggered when transmit_payload managed to send or when receive_payload received data NOTE: when Mask_Max_rt is set in the config register so it will not go off when MAX_RT is was reached on the mailing lodge nmisslyckats!
{
cli(); // Disable the global interrupt
CLEARBIT(PORTB ,1); // ce low back-stop listening / transmitting
SETBIT(PORTB,0); // part one
_delay_ms(500);
CLEARBIT(PORTB,0); // led off
// Receiver function to print out on usart:
data = WriteToNrf (R, R_RX_PAYLOAD, data, DataLen); // Read the received data
reset();
for (int i = 0; i <DataLen; i++)
{
lcd_putc(data[i]);
}
_delay_ms(1000);
lcd_clrscr();
sei();
}Спойлер
Код: Выделить всё
/* Memory Map */
#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
/* Bit Mnemonics */
#define MASK_RX_DR 6
#define MASK_TX_DS 5
#define MASK_MAX_RT 4
#define EN_CRC 3
#define CRCO 2
#define PWR_UP 1
#define PRIM_RX 0
#define ENAA_P5 5
#define ENAA_P4 4
#define ENAA_P3 3
#define ENAA_P2 2
#define ENAA_P1 1
#define ENAA_P0 0
#define ERX_P5 5
#define ERX_P4 4
#define ERX_P3 3
#define ERX_P2 2
#define ERX_P1 1
#define ERX_P0 0
#define AW 0
#define ARD 4
#define ARC 0
#define PLL_LOCK 4
#define RF_DR 3
#define RF_PWR 6
#define RX_DR 6
#define TX_DS 5
#define MAX_RT 4
#define RX_P_NO 1
#define TX_FULL 0
#define PLOS_CNT 4
#define ARC_CNT 0
#define TX_REUSE 6
#define FIFO_FULL 5
#define TX_EMPTY 4
#define RX_FULL 1
#define RX_EMPTY 0
#define DPL_P5 5
#define DPL_P4 4
#define DPL_P3 3
#define DPL_P2 2
#define DPL_P1 1
#define DPL_P0 0
#define EN_DPL 2
#define EN_ACK_PAY 1
#define EN_DYN_ACK 0
/* Instruction Mnemonics */
#define R_REGISTER 0x00
#define W_REGISTER 0x20
#define REGISTER_MASK 0x1F
#define ACTIVATE 0x50
#define R_RX_PL_WID 0x60
#define R_RX_PAYLOAD 0x61
#define W_TX_PAYLOAD 0xA0
#define W_ACK_PAYLOAD 0xA8
#define FLUSH_TX 0xE1
#define FLUSH_RX 0xE2
#define REUSE_TX_PL 0xE3
#define NOP 0xFF
/* Non-P omissions */
#define LNA_HCURR 0
/* P model memory Map */
#define RPD 0x09
/* P model bit Mnemonics */
#define RF_DR_LOW 5
#define RF_DR_HIGH 3
#define RF_PWR_LOW 1
#define RF_PWR_HIGH 2