
#include "reg52.h"
#include "intrins.h" //_nop_()延时函数用
#define uchar unsigned char
#define uint unsigned int
sbit DATA=P1^1 //发送方管脚配置
sbit CLK1=P1^2
sbit CS=P1^3
sbit CE=P1^4
sbit DR1=P1^5
sbit PWR_UP=P1^6
sbit led1=P1^0
sbit diol=P2^5
/*sbit DATA=P2^1 //接收方管脚配置
sbit CLK1=P2^2
sbit CS=P2^3
sbit CE=P2^4
sbit DR1=P2^5
sbit PWR_UP=P1^6
sbit led1=P3^7
sbit diol=P2^0//没用扰老绝*/
sbit BIT0=ACC^0
sbit BIT7=ACC^7//
uchar TXData[14]
uchar RXData[10]
uchar Data1=0xff
uchar code table1[]={0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
uchar code table2[]={0x99,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
delay1ms(int t)
{
uint i
uint j
for(i=0i<ti++)
for(j=0j<116j++)
}
void delay10us(void)
{
uchar y
for(y=0y<10y++)
_nop_()
}
void delay100us(void)
{
uchar y
for(y=0y<100y++)
_nop_()
}
/****************************************************************************************************
/*函数:write( uchar byte)
/*功能:通过IO口写入一个字节到NRF24L01
/****************************************************************************************************/
void write(uchar byte)
{
uchar i
ACC=byte
i=8
while(i)
{
DATA=BIT7
CLK1=1// output 'uchar', MSB to MOSI
_nop_()
_nop_() // shift next bit into MSB..
ACC<<=1
CLK1=0 // Set SCK high..
i-- // ..then set SCK low again
}
}
/****************************************************************************************************
/*函数:Read(uchar reg)
/*功能:NRF24L01的读时序
/****************************************************************************************************/
uchar Read(void)
{
uchar i
i=8
while(i)
{
CLK1=1// output 'uchar', MSB to MOSI
_nop_()
_nop_() // shift next bit into MSB..
ACC<<=1
BIT0=DATA
CLK1=0 // Set SCK high..
i-- // ..then set SCK low again
}
return ACC // return register value
}
/****************************************************************************************************/
/*功能:NRF24L01初始化控制结构体
/****************************************************************************************************/
struct RFConfig
{
uchar n
uchar buf[15]
}
typedef struct RFConfig RFConfig
#define ADDR_INDEX 8 //地址起始号为 8
#define ADDR_COUNT 4 //地址占4字节
code RFConfig tconf= //发射时配置字
{
15,//配置字长度15
0x50,//接收通道2数据长度80bit(10byte)
0x50,//接收通道1数据长度80bit(10byte)
0x00,0x00,0x00,0x00,0x00,//接收通道2地址最多40bit(5byte)
0x00,0xaa,0xbb,0x12,0x34,//接收通道1地址最多40bit(5byte)
0x83,//32bit地址长度,16bit crc校验
0x6f,//单通道接收
0x04//02频道发射
}
code RFConfig rconf=//接收时配置字
{
15,
0x50,
0x50,
0x00,0x00,0x00,0x00,0x00,
0x00,0xaa,0xbb,0x12,0x34,
0x83,
0x6f,
0x05//2频道接收
}
void nrf2401_on()
{
CE=0
CS=0
PWR_UP=1
delay1ms(3)
}
void nrf2401init_receiver(void)//接收初始化
{
uchar b
CE=0
CS=1
delay10us()
for(b=0b<rconf.nb++)//rconf.n=15
{
write(rconf.buf[b])
}
CE=1
CS=0
}
void nrf2401init_transmitter(void)//发射初始化
{
uchar b
CE=0
CS=1
delay10us()
for(b=0b<rconf.nb++)//rconf.n和tconf.n相等
{
write(tconf.buf[b])
}
CS=0
}
void nrf2401set_rxmode(void)//接收初始化后快速进入接收状态
{
CE=0
CS=1
delay10us()
write(rconf.buf[14])//写入命令0x05
CE=1
CS=0
}
void nrf2401set_txmode(void)//发射初始化后快速进入发射状态
{
CE=0
CS=1
delay10us()
write(tconf.buf[14])//写入命令0x04
CE=1
CS=0
}
void tx_packet(uchar m)//m=1发射数据包选table1,m=2选table2
{
uchar i
TXData[0]=0xaa//要不要补1个地址码0x00?不用,前面已设32bit地址长度,
TXData[1]=0xbb
TXData[2]=0x12
TXData[3]=0x34
if (m==1)
{
for(i=4i<14i++)
{TXData[i]=table1[i-4]}
}
else
{
for(i=4i<14i++)
{TXData[i]=table2[i-4]}
}
CS=0CE=1
delay10us()
for(i=0i<14i++)
{
write(TXData[i])
}
CE=0
}
/*void tx_packet(void)//发射数据包
{
uchar i
TXData[0]=0xaa//要不要补1个地址码0x00?不用,前面已设32bit地址长度,
TXData[1]=0xbb
TXData[2]=0x12
TXData[3]=0x34
for(i=4i<14i++)
{TXData[i]=table2[i-4]}
CS=0CE=1
delay10us()
for(i=0i<14i++)
{
write(TXData[i])
}
CE=0
}*/
void recevice_packet(void)//接收数据包
{
uchar i
for(i=0i<10i++)
{
RXData[i]=Read()
}
}
//发射方先发一个数据包,其中第5个数据(TXData[4])为0x88,然后进入接收状态,若收到的数据包第5个数是0x99,则点亮发光二极管
//接收方先进入接收状态,若收到的数据包第5个数是0x88,则点亮LED并发送一个数据包,其中第5个是0x99
void main(void)//发射方主程序
{
nrf2401_on()
nrf2401init_transmitter()
nrf2401set_txmode//进入发射状态
tx_packet(1)//发射数据包1第4个数据为0x88
nrf2401init_receiver()
nrf2401set_rxmode()//进入接收状态
while(DR1!=1)
recevice_packet()//接收数据包
diol=1//开通锁存器
if(RXData[4]==0x99)//如果收到正确遥数据0x99,则灯亮说明通信成功
{
led1=0
}
while(1)
}
/*void main(void)//接收方主程序
{
nrf2401_on()
nrf2401init_receiver()
nrf2401set_rxmode()//进入接收状态
while(DR1!=1)
recevice_packet()//接收数据包
diol=1//开通锁存器
if(RXData[4]==0x88)//如果收到正确遥数据0x88,则灯亮说明通信成功
{
led1=0
}
nrf2401init_transmitter()
nrf2401set_txmode//进入发射状态
delay1ms(10)//延时,让发送方准备好
tx_packet(2)//发射数据包2,第4个数据为0x99
while(1)
}*/
这个御团是nordic公司的一款51内核的芯片,烧录通过spi接口,淘宝上面有卖编程器的,nordic自己的仿真器很贵,一般个人很难支付得起。如果要开发的话编程器肯定得搞一个,提醒一句网上的编程器质量不是很高,毕竟这个芯片用的人还比较少。nrf24lu1有usb模块支持信纯低速usb2.0可以做无线键鼠之类的接收器滑拆咐,应用范围还是很广泛的
摘要:设计了基于nRF24L01无线数据传输芯片和Fusion StartKit开发板的智能探测系统。通过开启nRF24L01的ACK PAYLOAD功能实现车载伍察系统与上位机之间的双向通信,采用Actel公司带有APB3总线的8051S软核在Fusion StartKit开发板上构建片上系统,使用MFC编写Windows环境下的人机交互界面,实现了具有实时数据传送、自动避障、远程 *** 控等功能的智能探测系统。目前一些恶劣或危险的环境人类仍然无法置身其中进行现场检测,如出现险情的矿井地道、地形崎岖的岩洞等,很难取得现场的参数。在这种情况下只有借助于智能探测装置。因智能小车控制方便、行动灵活,对比其他载体工具更容易胜任探测任务,因此成为各种探测仪器的首选工具。
本文设计的智能探测系统以小车为载体,将所测得的现场参数通过nRF24L01无线模块实时传回上位机,具有快速灵活的特点;在实际工作时可左右转向和后退,自动躲避障碍物;同时该小车 *** 控方便,可通过MFC搭建的人机交互界面利用鼠标和键盘对小车进行远程控制。
1、系统总体结构设计
该系统基于Actel FPGA实现,采用两块Fusi。nStartkit开发板,一块作为车载控制板,另一块作为中转板。车载控制板负责采集温度、湿度、板载电压、当前路况以及人体检测等现场信息,驱动小车运行,同时通过无线发送现场信息以及接收上位机的控制命令。中转板负责将接收到的无线信号通过串口转发给PC机,同时将PC机由串口返回的控制指令利用无线模块发送给车载控制板。PC机上采用MFC编写人机交互界面,显示小车所在环境的相关信息,同时提供鼠标、键盘等完善的 *** 控手段。系统结构如图1所示。
图1 系统结构框图
腔型茄2、系统硬件设计
2、1无线数据传输芯片nRF24L01
2.1.1芯片简介H
nRF24L01是挪威NorDic公司的单片2.4 GHz无线收发一体芯片,有多达125个频道可供选择,支持1 Mb/s和2 Mb/s传输速率。该芯片采用SPI接口进行数据读写和参数配置租隐,以寄存器映射方式对各个寄存器进行管理,同时具有自动重传、动态有效信息长度(DPL)、应答信号携带有效信息(ACK PAYLOAD)等高级功能。
2.1.2功能
动态有效信息长度(DPL)指的是发送端的nRF24L01芯片通过写人有效数据区的数据长度决定当前一帧数据的大小,而接收端则通过接收到的数据帧中的控制域信息而不是寄存器中定义的数据长度提取有效数据。这个功能极大地提高了无线信道的使用率,同时减少了冗余数据的传播,降低了数据在空中滞留的时间和数据被污染的概率。配合nRF24L0l的CRC校验和自动重传功能,在有效地降低数据误码率的同时保证了数据传输的时效性。
应答信号携带有效信息(ACK PAYLOAD)指nRF24L01芯片在开启自动重传和DPL的基础上实现的双向通信功能。图2为一对无线模块之间的一次携带应答有效信息的数据传输过程。主发送模块(PTX)发送完第1帧数据后,自动置为接收模式,等待主接收模块(PRX)发送应答信号或携带有效数据的应答信号。主接收模块收到主发送模块发送的第1个数据帧后,若此时有需要附加的有效数据,则在发送完ACK信号后继续发送有效数据。而主发送模块收到ACK信号后继续接收有效信号,直到空中没有残留的无线信号再开始发送第2帧信号。
使用ACK PAYLOAD可以实现车载系统和PC机的双向通信,该功能很好地解决了手动切换无线收发状态导致双方互相等待的问题,同时只在需要对车载控制板进行控制的时刻附带应答有效信息,可以减少不必要的通信过程,大大提高了系统稳定性。
图2携带ACK PAYLOAD的1次数据传输示意图
2.1.3实现功能的配置方法
要实现nRF24L01的ACK PAYLOAD功能需要经过以下步骤:首先进行无线模块的基本配置,包括发送接收模式的选择(CONFIG)、开启自动重传功能(EN_AA)、接收地址使能(EN_ADDR)、设置重传时问不为零(SET-UP RETR)等;然后同时开启DPL和ACK PAYLOAD功能,要实现这两个功能,必须在完成第一步之后用nRF24L01白带的ACTIVATE命令加上0x73数据开启默认隐藏的两个寄存器FEATURE和DYNPD。通过对这两个寄存器的设置就可以实现数据的双向通信。但要注意,接收端开启DPL后要使用R_RX PL WID命令读取当前数据帧的有效数据长度,同时使用W ACK PAY-LOAD命令将ACK PAYLOAD写入FIFO。
2.2 Core 80515架构
Core 8051S是Actel公司推出的基于APB3总线的8051lP核,兼容8051的全部指令,同时又具备许多51单片机所没有的独特功能:
(1)具有可配置的JTAG接口调试功能,可利用Flash_Pro下载器作为其调试工具;优化指令执行速度,内部设置流水线,可实现单个时钟周期执行一条指令,且是普通51单片机的12倍。
(2)采用APB3外设总线结构和SER寄存器内存映射方式管理外设,将外部扩展的64 KB数据空间中的最高4 KB作为APB3外设的寄存器内存映射地址,每个APB3外设占据256 B的地址,因此最多可添加16个外设。
(3)使用CoreConsole软件以图形化界面的方式添加Core8051S以及其他外设,既直观又方便。
图3是以CoreConsole开发的、基于Core805lS和APB3总线的50PC系统的典型架构。该软件的开发流程与Altera公司基于NIOS Ⅱ处理器的soPc开发流程类似,同时又具有其独特优势:在系统不复杂、控制部分远多于计算处理时,使用Core805⊥s可灵活迅速地进行开发,通过安装ISA—Actel5 1为Keil提供调试驱动可直接使用Keil编写代码并进行在线程序调试,而优化后的指令执行速度可满足大部分应用的要求。
图3 CoreConsole下基于Core8051S的开发实例
本系统设计步骤:
(1)利用CoreConsole以图形化方式设计片上系统所需的总线及外设,包括SPI、PWM、GP10、UART等模块;配置各模块与APB3总线之间的连接关系,正确分配外设地址;然后生成.Ⅴ文件导人Actel集成开发环境Libero。
(2)使用Libero的Flash Memory System Builder将Fu_S10n内部的Flash模块配置为Core8051S的外部程序空问。如果有必要还可以将Fusi。n StartKit开发板上的SRAM作为Core8051S的外部数据空间使用。
(3)将工程编译综合后下载到开发板上,通过Keil编写程序并进行调试。
3、系统软件设计
3.1车载控制系统软件设计
车载系统是本系统的核心部分,它担负着现场环境探测,远距离数据传输以及未知区域检测等重要功能。因此该部分的设计对可靠性和稳定性要求较高。系统的软件流程图如图4所示。
图4车载控制系统流程图
车载系统软件包含两部分功能:采集现场各种参数和实现各种运行模式。通过温湿度传感器和人体红外传感器采集温湿度值以及现场环境是否有人信号;通过无线返;回参数决定当前小车的运行模式,包括自动运行模式、半遥控模式和全遥控模式。自动运行模式下小车会根据采集到的光电对管组信息分析当前的路况,从而作出相应运行路径修正处理;半遥控模式下通过鼠标控制Windows界面的参数来控制小车的行动;全遥控模式下通过 *** 控键盘可直接 *** 控小车运行。
车载系统自动运行时,通过内部算法进行路径选择和障碍规避。由于光电对管组信息相对较少,故采用查表映射法进行舵机电机驱动控制,即将光电对管组采集到的信息进行分类,根据不同的信息赋予小车不同的电机和舵机驱动值,而光电对管组采集得到的信息为6 bit数据,也就是数值为0~63,将其作为数组的下标,在数组内容中根据下标所表征的类型设置不同的经验值,通过大量的运行测试即可得到比较理想的参数。车载系统检测到小障碍物时,查表得到舵机电机参数,转过一定角度绕开障碍物继续运行;检测到较大障碍物且无法绕过时,车载系统倒车回到安全区域继续运行。
由于光电对管组存在干扰信号,在算法上进行了如下滤波处理:利用记忆功能将前几次的行进路线保存,通过与当前输出状态的比对,判断是否为干扰信息以决定是否摒弃当前控制量。
以上算法保证了车载系统在运行中出错概率降到最低。
3.2人机交互界面设计
A机交互界面是采用微软基础类(MFC)开发的基于对活框架构的应用程序。采用CMSComm类处理中转板与PC之间的串口通信,同时通过截获软件系统的消息传递函数来实现对键盘值的判断。
本文详细介绍了nRF24L01无线芯片的DPL和ACKPAYLOAD等功能,实现了车载系统与上位机之间的双向通信,使用Actel公司的CoreConsole工具构建SoPC片上系统,同时设计了PC机上人机交互界面,完善了系统的运行和控制,实现了具有实时数据传送、自动避障、远程 *** 控等功能的智能探测系统
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)