用的是扫频法+状态机思想。
考虑假如不扫频,设地址的话,最多同时6个,还保不齐有冲突,索性扫频得了。状态机比较好看好些,只有两个状态 囧。。。
底层是 正点原子的A牌开发板东东。。。算是帮他广告了
24L01初始化为速率1M(满足我的应用场合,不求速度),硬件SPI 9Mbps(Nordic文档写最大10M,讯通的写8M),自动应答。1M下频道间隔是2M的二分之一,
可用频道较多,125。
有图有真相,工作在单工状态,主机接收,从机发送。确认接收由自动应答完成。
也尝试半双工状态,结果把人搞抓狂了,因为又要多个,又要考虑严重干扰,误操作等等问题。半双工经常尴尬的变成 主从都是接收或者都是发送。要设延时自动复位或者手动复位,索性就单工了。。。好好利用自动应答,简单有效。
(原文件名:st.jpg)
其他代码坛子里面多的是,我就放自己这部分。每次“接头”程序只发一次 32BYTE,可以自己在相应地方拓展
Header部分
#ifndef __STATE_H
#define __STATE_H
#include "sys.h"
#include "24l01.h"
#include "key.h"
#include "led.h"
#include "lcd.h"
#include "delay.h"
//Mini STM32开发板
//LED驱动代码
//ZForce@STM32
//2010/11/24
#define RF_IDLE 0x00
#define RF_INQUERY 0x01
#define RF_COMMUTE 0x02
#define RF_SLAVE_CH 0x02
#define RF_SLAVE_ID 0x02
extern u8 tmp_buf[33];
void StateMachine(u8 mode);
#endif
C部分
#include "state.h"
u8 test[100]; //测试用
void StateMachine(u8 mode)
{
static u8 sta;
static u8 RF_IDLE_CH;
u8 key = 0;
//tmp_buf[31] = 0x00; //确认复位
//test[0] = sta;
//test[1] = RF_IDLE_CH;
if(0 == mode)// MASTER 主机模式
{
LCD_ShowString(60,130,"Master Mode ");
switch(sta)
{
case RF_IDLE :
LCD_ShowString(60,150,"Scan Channel...");
LCD_ShowString(60,170," ");
LCD_ShowString(60,190," ");
LED0 = 1;
if(125 == RF_IDLE_CH) //最大值复位
{
RF_IDLE_CH = 0;
}
RX_Mode(RF_IDLE_CH);// 括号是频率
if(0 == NRF24L01_RxPacket(tmp_buf))// 当接收到数据时更改状态 返回值为0表示收到 1为未收到
{
sta = RF_COMMUTE;//更多的话这里加NRF24L01_RxPacket
}
else // 没接收到数据时保持状态
{
sta = RF_IDLE;
RF_IDLE_CH++;
}
break;
case RF_COMMUTE :
LCD_ShowString(60,150,"Commute with ");
LCD_ShowString(60,170,tmp_buf);//显示从机发送信息,例如从机身份
LED0 = 0;
key= KEY_Scan();
if(1 == key) //done
{
LCD_ShowString(60,190,"Done ");
delay_ms(5000);
LCD_ShowString(60,190," ");
sta = RF_IDLE;
}
else if(2 == key) //cancel
{
sta = RF_IDLE;
}
else
{
sta = RF_COMMUTE;
}
break;
default : break;
}
}
if(mode == 1)// SLAVE 从机模式
{
LCD_ShowString(60,130,"Slave Mode ");
key= KEY_Scan();
if(2 == key) //done
{
sta = RF_INQUERY;
}
switch(sta)
{
case RF_IDLE :
LCD_ShowString(60,150,"RF Off ");
PowerOff_Mode();
break;
case RF_INQUERY :
LED0 = 0;
LED1 = 1;
LCD_ShowString(60,150,"Inquery ");
tmp_buf[0] = 0x41; //这里可详细给32byte赋值
TX_Mode(RF_SLAVE_CH);
if(TX_OK == NRF24L01_TxPacket(tmp_buf)) //发送并且得到返回值
{
//这里可以根据需要继续发数据 NRF24L01_TxPacket
sta = RF_IDLE;
}
else
{
sta = RF_INQUERY;
}
break;
default : break;
}
}
} |
|