نوشته اصلی توسط
shahrivar88
[PHP]
// Target : LPC2148
// Crystal: 12.000Mhz
// Author: ALI_BME87
#include <lpc214x.h>
#include "lcd.h"
/*-----------------------------------------------------------------------------
Global Defines
------------------------------------------------------------------------------*/
unsigned char Buffer[] = {'S', 'A', 'L', 'A', 'M'}, data_r[];
#define TX_ADR_WIDTH 5 // 5 bytes TX(RX) address width
#define TX_PLOAD_WIDTH 5 // 2 bytes TX payload
unsigned char TX_ADDRESS[TX_ADR_WIDTH] = {0xE7, 0xE7, 0xE7, 0xE7, 0xE7}; // Define a static TX address
void init_CPU (void);
void RX_MODE(void);
void TX_MODE(void);
void delay_main(void);
void delayms(unsigned int dly);
void spi_init(void);
void int_en(void);
void spi_int(void);
void EINT0_int(void) __irq;
void SPI0_int(void) __irq;
unsigned char SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes);
unsigned char SPI_Read_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes);
unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value);
unsigned char SPI_Read(unsigned char reg);
unsigned char SPI_RW(unsigned char byte);
//************************************************** **************//
// 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
//************************************************** *//
// 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 MAX_RT 0x10 // Max #of TX retrans interrupt
#define TX_DS 0x20 // TX data sent interrupt
#define RX_DR 0x40 // RX data received
//-----------------------------------------------------------------------------
//------------------------------------------------------
#define CEL IO0CLR = 1<<30 //Chip Enable OFF
#define CEH IO0SET = 1<<30 //Chip Enable ON
#define CSNL IO0CLR = 1<<31 // Chip Select ON (Active Low)
#define CSNH IO0SET = 1<<31 // Chip Select OFF (Active Low)
int main(void){
unsigned char sure_tx, i;
lcd_init();
lcd_clear();
init_CPU ();
spi_init();
int_en(); // module interrupt Initializing
// spi_int(); // SPI Interrupt
RX_MODE();
delayms(5);
// lcd_print (" READ");
sure_rx = SPI_Read(CONFIG); // read the CONFIG register
if ( (sure_tx == 0x0F)){ // make sure that the module is in RX mode
lcd_gotoxy(0,0);
lcd_print("R_MODE_OK");
}
SPI_Read_Buf (RD_RX_PLOAD, TX_ADDRESS, TX_ADR_WIDTH); // Read the register which data is in
lcd_gotoxy(1,0);
for(i=0; i<TX_ADR_WIDTH; i++){ // Display data
lcd_putchar(data_r[i]);
}
while (1){
}
}
void TX_MODE(void)
{
delay_main();
CEL;
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0E); // Set PWR_UP bit, enable CRC(2 bytes) & Prim:TX. Interrupts enabled.. Module is in TX mode
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0
SPI_RW_Reg(WRITE_REG + SETUP_AW, 0x03); // Enable 5 Byte Payload
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x01); // 250us + 86us, 1 retransmit...
SPI_RW_Reg(WRITE_REG + RF_CH, 40); // F0= 2400 + RF_CH [MHz], F0 = 2440 [MHz]
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x0F); // TX_PWR:0dBm, Datarate:1Mbps, LNA:HCURR
// SPI_RW_Reg(WRITE_REG + STATUS, 0x70); /* Clear RX_DR, TX_DS, MAX_RT Interrupt Sourse */
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_Write_Buf(WR_TX_PLOAD, Buffer, TX_PLOAD_WIDTH); // Writes data to TX payload
CEH;
delay_main();
}
/**************************************************
Function: RX_Mode();
Description:
This function initializes one nRF24L01 device to
RX Mode, set RX address, writes RX payload width,
select RF channel, datarate & LNA HCURR.
After init, CE is toggled high, which means that
this device is now ready to receive a datapacket. */
/**************************************************/
void RX_MODE(void)
{
CEL;
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0F); // Set PWR_UP bit, Module is in Standby-I mode
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0
SPI_RW_Reg(WRITE_REG + SETUP_AW, 0x03);
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // Use the same address on the RX device as the TX device
SPI_RW_Reg(WRITE_REG + RF_CH, 40); // F0= 2400 + RF_CH [MHz], F0 = 2440 [MHz]
SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH); // Select same RX payload width as TX Payload width (One Byte)
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x0F); // TX_PWR:0dBm, Datarate:1Mbps, LNA:HCURR
// SPI_RW_Reg(WRITE_REG + CONFIG, 0x7F); // Set PWR_UP bit, enable CRC(2 bytes) & Prim:RX. Interrupt disabled.., Module is in RX mode
CEH;
delay_main();
// This device is now ready to receive one packet of 1 byte payload from a TX device sending to address
// '7878787878', with auto acknowledgment, retransmit count of 10, RF channel 40 and datarate = 1Mbps.
}
void SPI0_int(void) __irq {
S0SPINT |= 1;
//SPI_RW_Reg(WRITE_REG + STATUS, 0x70); /* Clear RX_DR, TX_DS, MAX_RT Interrupt Sourse */
VICVectAddr = 0; /* Acknowledge Interrupt */
delayms(5);
}
void EINT0_int(void) __irq {
unsigned char i;
IO0CLR = 1<<21; // Beep if data received
delayms(50);
IO0SET = 1<<21; // Buzzer OFF
lcd_clear();
lcd_print("DATA RECEIVED:");
SPI_RW_Reg(WRITE_REG + STATUS, 0x70); /* Clear RX_DR, TX_DS, MAX_RT Interrupt Sourse */
EXTINT = 1; /* Clear EINT0 interrupt flag */
VICVectAddr = 0; /* Acknowledge Interrupt */
delayms(5);
}
/*-----------------------------------------------------------------------------
Module: init_CPU
Function: Initialization of CPU
------------------------------------------------------------------------------*/
void init_CPU (void){
IO0DIR = 1<<30 | 1<<31 | 1<<21; // (P0.30:CE, P0.31:CSN) as output + Buzzer
IO0SET = 1<<21;
CEL; // Disable the module at first, CE=OFF
CSNH; // CSN = 1 (CSN is a active low signal)
}
// SPI Initialazing
void spi_init(){
PINSEL0 = 1<<8 | 1<<10 | 1<<12; // Enable MOSI, MISO, SCK For SPI
S0SPCCR = 15; // PCLK = 15MHz, SPCCR0 = 15 => SCK = 1MHz
// 11:8-BITS 7-SPIE 6-LSBF 5-MSTR 4-CPOL 3-CPHA 2-BitEnable
S0SPCR = 0xA0; // 0000 1 0 1 0 0 0(8-bit transfer)
}
void int_en (){
EXTMODE=0x00; /* EINT0 is level sensitive. */
EXTPOLAR=0x00; /* EINT0 is low-active sensitive */
PINSEL0 |= 1<<2 | 1<<3; /* EINT0(P0.1) Selected */
VICVectAddr0 = (unsigned int) EINT0_int; /* set interrupt vector 0 */
VICVectCntl0 = ( 0x20 | 14 ); /* enable slot & use it for EINT0 Interrupt */
VICIntEnable |= (unsigned int) 1<<14; /* Enable EINT0 Interrupt */
}
void spi_int (){
VICVectAddr0 = (unsigned int) SPI0_int; /* set interrupt vector 0 */
VICVectCntl0 = ( 0x20 | 10 ); /* enable slot & use it for SPI0 Interrupt */
VICIntEnable |= (unsigned int) 1<<10; /* Enable SPI0 Interrupt */
}
unsigned char SPI_RW(unsigned char byte)
{
S0SPDR = byte;
while((S0SPSR & 0x80) == 0); // Wait for completion of Transmit
delay_main();
return(S0SPDR); // return data received from Slave
}
/**************************************************
Function: SPI_RW_Reg();
Description:
Writes value 'value' to register 'reg' */
/**************************************************/
unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value)
{
unsigned char status;
CSNL;
delay_main();
SPI_RW(reg); // select register
delay_main();
SPI_RW(value); // ..and write value to it..
delay_main();
CSNH;
return(status); // return nRF24L01 status byte
}
unsigned char SPI_Read_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
{
unsigned char status,byte_ctr;
// *data_r = *pBuf;
CSNL;
delay_main();
status = SPI_RW(reg); // Select register to write to and read status byte
for(byte_ctr=0;byte_ctr<bytes;byte_ctr++){
pBuf[byte_ctr] = SPI_RW(0); // Perform SPI_RW to read byte from nRF24L01
data_r[byte_ctr] = pBuf[byte_ctr];
}
delay_main();
CSNH;
return(status); // return nRF24L01 status byte
}
unsigned char SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
{
unsigned char status,byte_ctr;
CSNL;
delay_main();
status = SPI_RW(reg); // Select register to write to and read status byte
for(byte_ctr=0; byte_ctr<bytes; byte_ctr++) // then write all byte in buffer(*pBuf)
status = SPI_RW(*pBuf++);
delay_main();
CSNH;
return(status); // return nRF24L01 status byte
}
/**************************************************
Function: SPI_Read();
Description:
Read one byte from nRF24L01 register, 'reg' */
/**************************************************/
unsigned char SPI_Read(unsigned char reg)
{
unsigned char reg_val;
CSNL;
delay_main();
SPI_RW(READ_REG + reg); // Select register to read from..
reg_val = SPI_RW(0);
//lcd_putchar(0x21);
CSNH;
delay_main();
return(reg_val); // return register value
}
void delay_main(void){
__asm("NOP");
__asm("NOP");
__asm("NOP");
__asm("NOP");
__asm("NOP");
__asm("NOP");
}
void delayms(unsigned int dly){
unsigned int del;
del = dly*15000;
for(; del>0; del--);
}
[/PHP]ممنون میشم اگه کسی به من بگه جریان چیه؟؟؟
یعنی دیتا چطوری توی آرایه قرار میگیره؟ درحالی که در هیچ کجای برنامه داده رو توی data_r قرار ندادن. اما وقتی data_r را برای نمایش روی ال سی دی ارسال میکنه داده را درست نمایش میده.
خلاصه بگم در کدام خط از برنامه داده دریافتی از ماژول توی آرایه data_r قرار میگیره؟؟؟؟