搜档网
当前位置:搜档网 › STM8软件模拟SPI与NRF24L01通信

STM8软件模拟SPI与NRF24L01通信

//========================================
// PROJECT: 24L01发送实验(软件模拟SPI)
// AUTHOR: MENGJICHENG
// MODULE: main.c
// COMPILER: STM8 Cosmic C Compiler
// DATE: 2010-9-12 16:41
//=========================================
#include "STM8S103F.h" //Registers and memory
#define u8 unsigned char
#define u16 unsigned int
#define u32 unsigned int

#define countof(a) (sizeof(a)/sizeof(*(a)))//带参数的定义
#define BufferSize (countof(Tx_Buffer)-1)//减掉一个空字符
u8 Tx_Buffer[] ="123456789";//"STM8Sxxx SPI Firmware Library Example: communication with a microSD card";

//-----------------------------------
_Bool f_250us=0;

_Bool power_pin @PB_ODR:5;
_Bool key1_pin @PC_IDR:4;
_Bool key2_pin @PD_IDR:5;
//////////////////////////////////////////
//NRF24L01脚定义
_Bool SCK_PIN @PC_ODR:5;
_Bool MOSI_PIN @PC_ODR:6;
_Bool MISO_PIN @PC_IDR:7;
_Bool IRQ_PIN @PD_IDR:3; //为低表示:1已接收到数据,数据移完时自动变为高,2发送完变低,3从发送次数超过设定值
_Bool CSN_PIN @PA_ODR:3; //为低时激活SPI发送数据(芯片的片选线,CSN为低电平芯片工作),此时可设置24L01
_Bool CE_PIN @PD_ODR:4; //低时系统进入待机模式I,为高时启动发射与接收,要保持10US
// SPI(nRF24L01) registers(addresses)
#define CONFIG 0x00 //;'Config' register address
#define EN_AA 0x01 //;'Enable Auto Acknowledgment' register address
#define EN_RXADDR 0x02 // 'Enabled RXaddresses' 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 // 'RXaddress pipe1' register address
#define RX_ADDR_P2 0x0c // 'RXaddress 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
//nRF24L01 SPI Command constant 写命令时要CSN

_PIN要为低
#define READ_REG 0x00 //read command to register
#define WRITE_REG 0x20 //write command to register
#define R_RX_PAYLOAD 0x61 //RX payload register address
#define W_TX_PAYLOAD 0xa0 //TX payload register address
#define FLUSH_TX 0xe1 //flush TX register command
#define FLUSH_RX 0xe2 //flush RX register command
#define REUSE_TX_PL 0xE3 //reuse TX payload register command
#define NOP 0xFF //No Operation, might be used to read status register

#define PAYLOAD_WIDTH 4 //发射与接收的数据个数,最高不超过32字节32*8=256
const u8 TX_ADDRESS[5]={0x12,0x34,0x56,0x78,0x9a};//默认接收通道0地址码为e7 e7 e7 e7 e7,发射地址码e7 e7 e7 e7 e7,先写低字节9a 78
u8 TX_BUF[PAYLOAD_WIDTH]={0,1,2,3};

/////////////////////////////////////////////
//
/////////////////////////////////////////////
delay_time(u16 i)
{
u16 j;
for(j=0;j{ while(!f_250us)
{
IWDG_KR=0Xaa; //清除看门狗
}
f_250us=0;
}
}
////////////////////////////////////////////////
//
////////////////////////////////////////////////
void GPIO_Init(void)
{
PA_DDR = 0b00001000; //1=Output.
PA_CR1 = 0B11111111; //需入时1=PushPull 输出时1=推挽输出
PA_CR2 = 0b00000000;
PA_ODR = 0b00001000;

PB_DDR = 0b00100000;
PB_CR1 = 0b11111111;
PB_CR2 = 0b00000000;
PB_ODR = 0b00100000;

PC_DDR = 0b01100000;
PC_CR1 = 0B11111111;
PC_CR2 = 0b00000000;
PC_ODR = 0b00000000;

PD_DDR = 0b00010000;
PD_CR1 = 0b11111111;
PD_CR2 = 0b00000000; //
PD_ODR = 0b00000000;

CE_PIN=0; // chip enable
CSN_PIN=1; // Spi disable
SCK_PIN =0;
}
//////////////////////////////////
//
//////////////////////////////////
void CLK_Init(void)
{
//Configure HSI prescaler
CLK_CKDIVR &= ~0x10; //HSIDIV[4:3]=00 [系统分频1.2.4.8],上电默认值8分频
//8mhz=16mhz/系统2分频
//Configure CPU clock prescaler
CLK_CKDIVR |= 0x00; //CPUDIV[2:0]=000: fCPU=fMASTER/[1.2.4.8.16.32.64.128]
//决定指令速度,不影响定时器
}
//////////////////////////////////
//
//////////////////////////////////
void TIM_Init(void)
{
/* //TIM2 CC2 control LED Brightness
TIM2_CCMR2 |= 0x70; //Output mode PWM2.
TIM2_CCE_PINR1 |= 0x30; //CC polarity low,enable PWM output

TIM2_ARRH = 0x00; //自动从装载寄存器/定时初值,
TIM2_ARRL = 0xff; //先装高字节

TIM2_CCR2H = 0X00; //决定PWM的占空比/utycycle control register: CCR是16BIT
TIM2_CCR2L = 0X00;

TIM2_PSCR = 0x00; //BIT[2:0] Configure TIM2 prescaler =1
TIM2_CR1 |= 0x81; //ARPE - - - OPM URS UDIS CE_PINN
//------------------------------//
// TIM3 CC1 control LED Blinking
TIM3_CCMR1 |= 0x78; //Output mode PWM2.
TIM3_CCE_PINR1 |= 0x03; //CC polarity low,enable PWM o

utput

TIM3_ARRH = 0x03;
TIM3_ARRL = 0xff; //自动从装载寄存器,先装高字节

TIM3_CCR1H = 0x02; //决定PWM的占空比/Dutycycle control register: CCR
TIM3_CCR1L = 0x00;

TIM3_PSCR |= 0x0d; //Configure TIM3 prescaler = 8192
TIM3_CR1 |= 0x81; //*/
//------------------------------//
TIM4_PSCR = 0x03; //PSC[2:0] [1.2.4.8.16.32.64.128]
TIM4_ARR = 0xfA; //定时器初值*定时器分频*系统分频/16MHZ=定时时间
//250*8*2/16mhz=250us
TIM4_IER |= 0x01; //- - - - - - - UIE(Enable TIM4 OVR interrupt)
TIM4_CR1 |= 0x81; //ARPE - - - OPM URS UDIS CE_PINN
}
/*最基本的函数,完成GPIO 模拟SPI 的功能。将输出字节(MOSI_PIN)从MSB 循环输出,
同时将输入字节(MISO_PIN)从LSB 循环移入。上升沿读入,下降沿输出。(从SCK_PIN 被初始化
为低电平可以判断出)。*/
u8 SPI_RW(u8 byte)
{ u8 bit_ctr;
for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
{ MOSI_PIN=byte & 0x80; //output 'byte' MSB to MOSI_PIN
byte <<= 1; // shift next bit into MSB..
SCK_PIN=1 ; // Set SCK_PIN high..
byte|=MISO_PIN; // capture current MISO_PIN bit
SCK_PIN=0; // then set SCK_PIN low again
}
return(byte); // return read byte
}
/*读取寄存器值的函数:基本思路就是通过READ_REG 命令(也就是0x00+寄存器地址),把
寄存器中的值读出来。对于函数来说也就是把reg 寄存器的值读到reg_val 中去*/
u8 SPI_Read(u8 reg)
{ u8 reg_val;

CSN_PIN = 0; // CSN_PIN low, initialize SPI communication...
SPI_RW(reg); // Select register to read from..
reg_val = SPI_RW(0); // ..then read registervalue
CSN_PIN = 1; // CSN_PIN high, terminate SPI communication
return(reg_val); // return register value
}
/*寄存器访问函数:用来设置24L01 的寄存器的值。基本思路就是通过WRITE_REG 命令(也
就是0x20+寄存器地址)把要设定的值写到相应的寄存器地址里面去,并读取返回值。对于
函数来说也就是把value 值写到reg 寄存器中。
需要注意的是,访问NRF24L01 之前首先要enable 芯片(CSN_PIN=0;),访问完了以后再disable
芯片(CSN_PIN=1;)。*/
u8 SPI_RW_Reg(u8 reg, u8 value)
{ u8 status;

CSN_PIN = 0; // CSN_PIN low, init SPI transaction
status = SPI_RW(reg); // select register
SPI_RW(value); // ..and write value to it..
CSN_PIN = 1; // CSN_PIN high again
return(status); // return nRF24L01 status byte
}
/*接收缓冲区访问函数:主要用来在接收时读取FIFO 缓冲区中的值。基本思路就是通过
READ_REG 命令把数据从接收FIFO(RD_RX_PLOAD)中读出并存到数组里面去*/
u8 SPI_Read_Buf(u8 reg, u8 *pBuf, u8 bytes)
{ u8 status,byte_ctr;

CSN_PIN = 0; // Set CSN_PIN low, init SPI tranaction
status = SPI_RW(reg); // Select register to write to

and read status byte
for(byte_ctr=0;byte_ctrpBuf[byte_ctr] = SPI_RW(0); // Perform SPI_RW to read byte from nRF24L01
CSN_PIN = 1; // Set CSN_PIN high again
return(status); // return nRF24L01 status byte
}
/*发射缓冲区访问函数:主要用来把数组里的数放到发射FIFO 缓冲区中。基本思路就是通过
WRITE_REG 命令把数据存到发射FIFO(WR_TX_PLOAD)中去。*/
u8 Spi_Write_Buf(u8 reg, u8 *pBuf, u8 bytes)
{ u8 status,byte_ctr;

CSN_PIN = 0; // Set CSN_PIN low, init SPI tranaction
status = SPI_RW(reg); //写命令字 and read status byte
for(byte_ctr=0; byte_ctrSPI_RW(pBuf[byte_ctr]); //把所指向的数组写入
CSN_PIN = 1; // Set CSN_PIN high again
return(status); // return nRF24L01 status byte
}
/*设定24L01 为发送方式,配置过程详见3.1 Tx 模式初始化过程。*/
void TX_Mode(void)
{ CE_PIN=0; //为低时才可设置24L01,此时处于待机模式1
SPI_RW_Reg(WRITE_REG+SETUP_AW,0x00000001);//默认地址宽度为5字节,此处3字节,要与接收地址宽度一致
Spi_Write_Buf(WRITE_REG+TX_ADDR,TX_ADDRESS,3);//发射不需要选择通道,只有一个发射通道,而接收有6个通道
Spi_Write_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,3);/*P0通道用于应答,地址必须与发送的节点地址一致,地址宽度可设定,默认为5字节,如没开应答可不用写*/
SPI_RW_Reg(WRITE_REG+EN_AA,0b00000001); //Enable Auto.Ack:Pipe0
SPI_RW_Reg(WRITE_REG+EN_RXADDR,0b00000001); //Enable Pipe0作为发射时还要开启0接收吗?可能是作为应答的接收
SPI_RW_Reg(WRITE_REG+SETUP_RETR,0b00001111); //250us+86us, retrans 16只有发射要设定
SPI_RW_Reg(WRITE_REG+RF_CH,40); //通道频率(共128频率),要与发射一致
SPI_RW_Reg(WRITE_REG+RF_SETUP,0b00001111); //0dBm, 2Mbps,LNA_HCURR
SPI_RW_Reg(WRITE_REG+CONFIG,0b01101110); //上电 CRC(2bytes) TX_DS禁止,MAX_RT允许
CE_PIN = 1; //CE置少要保持10US高电平
}
/////////////////////////////////////////////
void rf_power_down()
{
CE_PIN=0; //系统进入待机模式I
SPI_RW_Reg(WRITE_REG+CONFIG,0b01011000);//CRC=1(1byte),Power down,PTX
}
//////////////////////////////////////////////
void rf_power_up(void) //开启24L01
{
CE_PIN=0; //系统进入待机模式I
SPI_RW_Reg(WRITE_REG+CONFIG,0b01011010); //CRC=1(1byte),Power up,PTX
delay_time(8); //上电置少保持1.5ms
}
//////////////////////////////////////
//
//////////////////////////////////////
void key_scannal(void)
{ static u16 key_delay=0xffff;
static _Bool f_release ;
u16 i;

if(!key2_pin)
goto key_in;

key_delay=200; //100ms
f_release=0;
return;
key_in:
if(f_release)
return;
if(!(--key_delay==0))
return;
f_release=1;
key_delay=200; //100ms

if(key2_pin)
return;

Spi_Write_Buf(W_TX_PAYLOAD, TX_BUF, PAYLOAD_WIDTH);

//Writes data to TX payload,最多只能发射32字节
CE_PIN = 1; //CE置少要保持10US高电平
i=0x0F;
while(--i);
CE_PIN = 0; //由高到低的变化启动一次发射
return;
}
//////////////////////////////////////
//
/////////////////////////////////////
void main ( void )
{
u16 i;
u8 j;
u16 y;
_asm("sim"); //Disable interrupts
CLK_Init();
GPIO_Init();
TIM_Init();
_asm("rim");
delay_time(400); //wait 0.1 second
TX_Mode();
delay_time(400); //wait 0.1 second
//------------------------------------
while ( 1 )
{ if(f_250us)
{ f_250us=0;
key_scannal();
if(++i>0xf00)
{ i=0;
if(!IRQ_PIN) //为低时中断,有接收到数据,此段用于判断数据是否
{ j = SPI_Read(STATUS); //返回状态寄存器
if(j&0b00010000)//MAX_RT判断是否因为从发次数溢出而中断
{
PB_ODR ^= 0b00100000;
}
SPI_RW_Reg(WRITE_REG+STATUS,j);//要用软件写1后才能清除IRQ_PIN为高电平
CE_PIN = 1; //CE置少要保持10US高电平
}
}
}
}
}




//========================================
// PROJECT: 24L01接收实验(软件模拟SPI)
// AUTHOR: MENGJICHENG
// MODULE: main.c
// COMPILER: STM8 Cosmic C Compiler
// DATE: 2010-9-12 16:41
//=========================================
#include "STM8S103F.h" //Registers and memory

#define u8 unsigned char
#define u16 unsigned int
#define u32 unsigned int

//-----------------------------------
_Bool f_250us=0;

//////////////////////////////////////////
//NRF24L01脚定义
_Bool SCK_PIN @PC_ODR:5;
_Bool MOSI_PIN @PC_ODR:6;
_Bool MISO_PIN @PC_IDR:7;
_Bool IRQ_PIN @PD_IDR:3; //为低表示:1已接收到数据,2发送完变低,3从发送次数超过设定值
_Bool CSN_PIN @PA_ODR:3; //为低时激活SPI发送数据,此时可设置24L01
_Bool CE_PIN @PD_ODR:4; //低时系统进入待机模式I,为高时启动发射与接收,要保持10US
// SPI(nRF24L01) registers(addresses)
#define CONFIG 0x00 //;'Config' register address
#define EN_AA 0x01 //;'Enable Auto Acknowledgment' register address
#define EN_RXADDR 0x02 // 'Enabled RXaddresses' 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 // 'RXaddress pipe1' register address
#define RX_ADDR_P2 0x0c // 'RXaddress 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
//nRF24L01 SPI Command constant
#define READ_REG 0x00 //read command to register
#define WRITE_REG 0x20 //write command to register

#define R_RX_PAYLOAD 0x61 //RX payload register address
#define W_TX_PAYLOAD 0xa0 //TX payload register address
#define FLUSH_TX 0xe1 //flush TX register command
#define FLUSH_RX 0xe2 //flush RX register command
#define REUSE_TX_PL 0xE3 //reuse TX payload register command
#define NOP 0xFF //No Operation, might be used to read status register

#define PAYLOAD_WIDTH 4 //发射与接收的数据个数,最高不超过32字节32*8=256
const u8 RX_ADDRESS[5]={0x12,0x34,0x56,0x78,0x9a};
u8 RX_BUF[PAYLOAD_WIDTH];

/////////////////////////////////////////////
//
/////////////////////////////////////////////
delay_time(u16 i)
{
u16 j;
for(j=0;j{ while(!f_250us)
{
IWDG_KR=0Xaa; //清除看门狗
}
f_250us=0;
}
}
////////////////////////////////////////////////
//
////////////////////////////////////////////////
void GPIO_Init(void)
{
PA_DDR = 0b00001000; //1=Output.
PA_CR1 = 0B11111111; //需入时1=PushPull 输出时1=推挽输出
PA_CR2 = 0b00000000;
PA_ODR = 0b00001000;

PB_DDR = 0b00100000;
PB_CR1 = 0b11111111;
PB_CR2 = 0b00000000;
PB_ODR = 0b00100000;

PC_DDR = 0b01100000;
PC_CR1 = 0B11111111;
PC_CR2 = 0b00000000;
PC_ODR = 0b00000000;

PD_DDR = 0b00010000;
PD_CR1 = 0b11111111;
PD_CR2 = 0b00000000; //
PD_ODR = 0b00000000;
}
//////////////////////////////////
//
//////////////////////////////////
void CLK_Init(void)
{
//Configure HSI prescaler
CLK_CKDIVR &= ~0x10; //HSIDIV[4:3]=00 [系统分频1.2.4.8],上电默认值8分频
//8mhz=16mhz/系统2分频
//Configure CPU clock prescaler
CLK_CKDIVR |= 0x00; //CPUDIV[2:0]=000: fCPU=fMASTER/[1.2.4.8.16.32.64.128]
//决定指令速度,不影响定时器
}

//////////////////////////////////
//
//////////////////////////////////
void TIM_Init(void)
{
/* //TIM2 CC2 control LED Brightness
TIM2_CCMR2 |= 0x70; //Output mode PWM2.
TIM2_CCE_PINR1 |= 0x30; //CC polarity low,enable PWM output

TIM2_ARRH = 0x00; //自动从装载寄存器/定时初值,
TIM2_ARRL = 0xff;

//先装高字节

TIM2_CCR2H = 0X00; //决定PWM的占空比/utycycle control register: CCR是16BIT
TIM2_CCR2L = 0X00;

TIM2_PSCR = 0x00; //BIT[2:0] Configure TIM2 prescaler =1
TIM2_CR1 |= 0x81; //ARPE - - - OPM URS UDIS CE_PINN
//------------------------------//
// TIM3 CC1 control LED Blinking
TIM3_CCMR1 |= 0x78; //Output mode PWM2.
TIM3_CCE_PINR1 |= 0x03; //CC polarity low,enable PWM output

TIM3_ARRH = 0x03;
TIM3_ARRL = 0xff; //自动从装载寄存器,先装高字节

TIM3_CCR1H = 0x02; //决定PWM的占空比/Dutycycle control register: CCR
TIM3_CCR1L = 0x00;

TIM3_PSCR |= 0x0d; //Configure TIM3 prescaler = 8192
TIM3_CR1 |= 0x81; //*/
//------------------------------//
TIM4_PSCR = 0x03; //PSC[2:0] [1.2.4.8.16.32.64.128]
TIM4_ARR = 0xfA; //定时器初值*定时器分频*系统分频/16MHZ=定时时间
//250*8*2/16mhz=250us
TIM4_IER |= 0x01; //- - - - - - - UIE(Enable TIM4 OVR interrupt)
TIM4_CR1 |= 0x81; //ARPE - - - OPM URS UDIS CE_PINN
}


/*最基本的函数,完成GPIO 模拟SPI 的功能。将输出字节(MOSI_PIN)从MSB 循环输出,
同时将输入字节(MISO_PIN)从LSB 循环移入。上升沿读入,下降沿输出。(从SCK_PIN 被初始化
为低电平可以判断出)。*/
u8 SPI_RW(u8 byte)
{ u8 bit_ctr;

for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
{ MOSI_PIN=byte & 0x80; //output 'byte' MSB to MOSI_PIN
byte <<= 1; // shift next bit into MSB..
SCK_PIN=1 ; // 拉高SCK,nRF24L01从MOSI读入1位数据,同时从MISO输出1位数据
byte|=MISO_PIN; // capture current MISO_PIN bit
SCK_PIN=0; // then set SCK_PIN low again
}
return(byte); // return read byte
}
/*读取寄存器值的函数:基本思路就是通过READ_REG 命令(也就是0x00+寄存器地址),把
寄存器中的值读出来。对于函数来说也就是把reg 寄存器的值读到reg_val 中去*/
u8 SPI_Read(u8 reg)
{ u8 reg_val;

CSN_PIN = 0; // CSN_PIN low, initialize SPI communication...
SPI_RW(reg); // Select register to read from..
reg_val =SPI_RW(0); // ..then read registervalue
CSN_PIN =1; // CSN_PIN high, terminate SPI communication
return(reg_val); // return register value
}
/*寄存器访问函数:用来设置24L01 的寄存器的值。基本思路就是通过WRITE_REG 命令(也
就是0x20+寄存器地址)把要设定的值写到相应的寄存器地址里面去,并读取返回值。对于
函数来说也就是把value 值写到reg 寄存器中。
需要注意的是,访问NRF24L01 之前首先要enable 芯片(CSN_PIN=0;),访问完了以后再disable
芯片(CSN_PIN=1;)。*/
u8 SPI_RW_Reg(u8 reg, u8 value)
{ u8 status;

CSN_PIN = 0; // CSN_PIN low, init SPI transaction
status = SPI_RW(reg); // select regi

ster
SPI_RW(value); // ..and write value to it..
CSN_PIN = 1; // CSN_PIN high again
return(status); // return nRF24L01 status byte
}
/*接收缓冲区访问函数:主要用来在接收时读取FIFO 缓冲区中的值。基本思路就是通过
READ_REG 命令把数据从接收FIFO(RD_RX_PLOAD)中读出并存到数组里面去*/
u8 SPI_Read_Buf(u8 reg, u8 *pBuf, u8 bytes)
{ u8 status,byte_ctr;

CSN_PIN = 0; // Set CSN_PIN low, init SPI tranaction
status = SPI_RW(reg); // Select register to write to and read status byte
for(byte_ctr=0;byte_ctrpBuf[byte_ctr] = SPI_RW(0); // Perform SPI_RW to read byte from nRF24L01
CSN_PIN = 1; // Set CSN_PIN high again
return(status); // return nRF24L01 status byte
}
/*发射缓冲区访问函数:主要用来把数组里的数放到发射FIFO 缓冲区中。基本思路就是通过
WRITE_REG 命令把数据存到发射FIFO(WR_TX_PLOAD)中去。*/
u8 SPI_Write_Buf(u8 reg,u8 *pBuf,u8 bytes)
{ u8 status,byte_ctr;

CSN_PIN = 0; // Set CSN_PIN low, init SPI tranaction
status = SPI_RW(reg); //写命令字 and read status byte
for(byte_ctr=0;byte_ctrSPI_RW(pBuf[byte_ctr]); //把所指向的数组写入
CSN_PIN = 1; // Set CSN_PIN high again
return(status); // return nRF24L01 status byte
}
/*设定24L01 为接收方式,配置过程详见3.2 Rx 模式初始化过程。*/
void RX_Mode(void)
{ CE_PIN=0; //为低时才可设置24L01,此时处于待机模式1
SPI_RW_Reg(WRITE_REG+SETUP_AW,0b00000001); //默认地址宽度为5字节,此处3字节,要与发送地址宽度一致
SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,RX_ADDRESS,3);//选择接收通道0和地址号
SPI_RW_Reg(WRITE_REG+EN_AA,0b00000001); // Enable Auto.Ack:Pipe0
SPI_RW_Reg(WRITE_REG+EN_RXADDR,0b00000001); // Enable Pipe0
SPI_RW_Reg(WRITE_REG+RF_CH,40); //通道频率(共128频率),要与发射一致
SPI_RW_Reg(WRITE_REG+RX_PW_P0,PAYLOAD_WIDTH);//设定接收多少个字节,最多一帧只能接收32字节,与发射一样
SPI_RW_Reg(WRITE_REG+RF_SETUP,0b00001111); //0dBm, 2Mbps,LNA_HCURR
SPI_RW_Reg(WRITE_REG+CONFIG,0b00111111); // 上电,CRC(2bytes) RX_DR enabled..
CE_PIN = 1; //为高时处于接收状
}
/////////////////////////////////////////////
void rf_power_down()
{
CE_PIN=0; //系统进入待机模式I
SPI_RW_Reg(WRITE_REG+CONFIG,0b01011000);//CRC=1(1byte),Power down,PTX
}
//////////////////////////////////////////////
void rf_power_up(void) //开启24L01
{
CE_PIN=0; //系统进入待机模式I
SPI_RW_Reg(WRITE_REG+CONFIG,0b01011010); //CRC=1(1byte),Power up,PTX
delay_time(8); //2ms 置少保持1.5ms
}

//////////////////////////////////////
//
/////////////////////////////////////
void main ( void )
{
u16 i; u8 z;

_asm("sim"); //Disable interrupts
CLK_Init();
G

PIO_Init();
TIM_Init();

CE_PIN=0; // chip enable
CSN_PIN=1; // Spi disable
SCK_PIN=0; // Spi clock line init high

_asm("rim");
delay_time(400); //wait 0.1 second
RX_Mode();
delay_time(400); //wait 0.1 second
//------------------------------------
while ( 1 )
{ if(f_250us)
{
f_250us=0;
if(IRQ_PIN) //为高时
continue;

SPI_Read_Buf(R_RX_PAYLOAD,RX_BUF,PAYLOAD_WIDTH);
SPI_RW_Reg(WRITE_REG+STATUS,0B01110000); //要用软件写1后才能清除IRQ_PIN
if(!RX_BUF[0]==0)
goto main_loop;
_asm("nop");
if(!RX_BUF[1]==1)
goto main_loop;
_asm("nop");
if(!RX_BUF[2]==2)
goto main_loop;
_asm("nop");
if(!RX_BUF[3]==3)
goto main_loop;
_asm("nop");
/* if(!RX_BUF[4]==4)
goto main_loop;
if(!RX_BUF[5]==5)
goto main_loop;
if(!RX_BUF[6]==6)
goto main_loop;
if(!RX_BUF[7]==7)
goto main_loop;
if(!RX_BUF[8]==8)
goto main_loop;
if(!RX_BUF[9]==9)
goto main_loop;
// PB_ODR ^= 0b00100000;
// goto main_loop;


if(!RX_BUF[10]==10)
goto main_loop;
if(!RX_BUF[11]==11)
goto main_loop;
if(!RX_BUF[12]==12)
goto main_loop;
if(!RX_BUF[13]==13)
goto main_loop;
if(!RX_BUF[14]==14)
goto main_loop;
if(!RX_BUF[15]==15)
goto main_loop;
if(!RX_BUF[16]==16)
goto main_loop;
if(!RX_BUF[17]==17)
goto main_loop;
if(!RX_BUF[18]==18)
goto main_loop;
if(!RX_BUF[19]==19)
goto main_loop;
if(!RX_BUF[20]==20)
goto main_loop;
if(!RX_BUF[21]==21)
goto main_loop;
if(!RX_BUF[22]==22)
goto main_loop;
if(!RX_BUF[23]==23)
goto main_loop;
if(!RX_BUF[24]==24)
goto main_loop;
if(!RX_BUF[25]==25)
goto main_loop;
if(!RX_BUF[26]==26)
goto main_loop;
if(!RX_BUF[27]==27)
goto main_loop;
if(!RX_BUF[28]==28)
goto main_loop;
if(!RX_BUF[29]==29)
goto main_loop;
if(!RX_BUF[30]==30)
goto main_loop;
if(!RX_BUF[31]==31)
goto main_loop;*/

RX_BUF[0]=0;
RX_BUF[1]=0;
RX_BUF[2]=0;
RX_BUF[3]=0;
/* RX_BUF[4]=0;
RX_BUF[5]=0;
RX_BUF[6]=0;
RX_BUF[7]=0;
RX_BUF[8]=0;
RX_BUF[9]=0;
RX_BUF[10]=0;
RX_BUF[11]=0;
RX_BUF[12]=0;
RX_BUF[13]=0;
RX_BUF[14]=0;
RX_BUF[15]=0;
RX_BUF[16]=0;
RX_BUF[17]=0;
RX_BUF[18]=0;
RX_BUF[19]=0;
RX_BUF[20]=0;
RX_BUF[21]=0;
RX_BUF[22]=0;
RX_BUF[23]=0;
RX_BUF[24]=0;
RX_BUF[25]=0;
RX_BUF[26]=0;
RX_BUF[27]=0;
RX_BUF[28]=0;
RX_BUF[29]=0;
RX_BUF[30]=0;
RX_BUF[31]=0; */
PB_ODR ^= 0b00100000;
main_loop:
_asm("nop");
}
}
}

相关主题