本帖最后由 dzzwoaizi 于 2015-11-13 10:38 编辑 /*--------------------------------------------*/致歉;收到论坛开发板那么长时间,由于工作太忙一直没有发表帖子,再次致歉论坛! /*--------------------------------------------*/ 闲话不说,如何快速的入手你手中的NUCLEO开发板呢!资料!绝对是资料能够让你快速入手的最简单方法。个人认为STM32能够成功不仅靠他最优的性价比,还有他的资料非常丰富,我是一个“剁手党”,比较喜欢鲁迅的“拿来主义”,下面请看如何找到你想要的资料! 第一步:打开STM32社区的界面找到资料下载 你会看到各种各样的资料, 例如:我们这次的板子是NUCLEO-L476RG,我们找到 这里面包含了所有的关于此板子的资料(PCB原理图demo都有) 打开后所有的资料都尽收眼底啦!赶快下载吧! /-----------------------------------------------------------------------------------------------/ 上面的文档对他的资料做了详细的讲解,我再次就不抄人家的的了,我之前有的M0核的M3核的STLINK驱动直接就能下载,这个板子有点怪,之前的驱动下载不了,我会在论坛最后给大家STlink驱动! 在这个文件家里就有了所有的官方历程代码,这是HAL库的,标准的外设库好像没有,我看了给出来一些资料,应该可以自己建立工程! 我在开发中就是用的这些代码写底层,稍微在修改一下就可以用了!再结合寄存器手册,在处理速度要求过快的场合,你也可以直接操作寄存器来实现各种功能! 特别注意:IAR7.3的暂时还没有支持此芯片,应该需要更高的版本,MDK5.3的是支持的,我编译过了!可以用! |
第二节:如何驱动XN297L模块,这个模块和大众用的RNF24L01功能是一样的!都是2.4G模块,XN297L传输的距离会更远一些哦!我这里用的是QFN20L030封装的哦!还有两种分装你们可以自己搜搜哦!
下面看一些资料
1.引脚定义
2.按照惯例驱动芯片需要6个IO口和VCC.GND。也就是8根线就能解决了。
这里SPI是模拟的,你也可以用硬件SPI,但是要是移植到另一个板子那就麻烦了!
首先确定一下利用那6个IO口吧!
简单一点!就用PC0~PC5吧!反正是模拟SPI,用哪个口都无所谓、
再看配置,
IRQ ——> PC0 ;//设置为输入IO口
MISO ——> PC1 ;//设置为输入IO口
MOSI ——> PC2 ;//设置为推挽输出IO口
SCK ——> PC3 ;//设置为推挽输出IO口
CSN ——> PC4 ; //设置为推挽输出IO口
CE ——> PB5 ; //设置为推挽输出IO口
相必IO口配置大家都会把!不会的话就看看官方demo,设置完后别忘了输出口全部为低电平哦!
3。下面看看SPI怎么模拟吧!
//写一个字节
void SpiWrite(u8 Dat)
{
u8 i;
for(i=0; i<8; i++)
{
if(Dat & 0x80) Rf_MOSI=1;
else Rf_MOSI=0;
Rf_SCK=1;
RfDelayUs(2);
Rf_SCK=0;
Dat<<=1;
}
}
//读一个字节
void SpiWrite(u8 Dat)
{
u8 i;
for(i=0; i<8; i++)
{
if(Dat & 0x80) Rf_MOSI=1;
else Rf_MOSI=0;
Rf_SCK=1;
RfDelayUs(2);
Rf_SCK=0;
Dat<<=1;
}
}
这两个函数就完成了8位的读写数据,简单吧!这里的Rf_MOSI和Rf_SCK等都是IO操作,下面就不在提示了!
如何读N个数据和写N个数据呢!简单的,看下面代码
//读N个数据,
//Addr:地址 Rdat:读出的数据保存的地址,Length:长度
void SpiReadDat(u8 Addr, u8 *Rdat, u8 Length)
{
u8 i;
Rf_CSN=0;
SpiWrite(Addr);
for(i=0; i<Length; i++) Rdat=SpiRead();
Rf_CSN=1;
}
//写N个数据
//Addr:地址 Rdat:写的数组首地址,Length:长度
void SpiWriteDat(u8 Addr, u8 *Rdat, u8 Length)
{
u8 i;
Rf_CSN=0;
SpiWrite(Addr);
for(i=Length; i>0; i--)
{
SpiWrite(*Rdat++);
}
Rf_CSN=1;
}
3.XN297L有两种模式,一种是普通型的,一种是增强行的!
普通型:只管发送数据,不管接收方收没收到数据,
增强型:发送数据后等待接收方的应答信号,没收到后会自动重发,(如果还没收到)达到从发字数就就不在重发,如果收到,再继续发送其他的数据!
4.配置底层!
/******************************************************************************
XN297L_Initial
Initial RF in ENHANCE_MODE
******************************************************************************/
void RF_ENHANCE_MODE_Init(void)
{
u8 BB_cal_data[] = {0x0A,0x6D,0x67,0x9C,0x46}; //XN297L
u8 RF_cal_data[] = {0xF6,0x37,0x5D}; //XN297L
u8 RF_cal2_data[] = {0x45,0x21,0xEF,0x2C,0x5A,0x40}; //XN297L
u8 Dem_cal_data[] = {0x01}; //XN297L
u8 Dem_cal2_data[] = {0x0B,0xDF,0X02}; //XN297L
Rf_CE=0;
ucCurrent_Channel = DEFAULT_CHANNEL;
/*********************use xn297 Enhance*********************/
SpiWriteReg(RST_FSPI, 0x5A); //SoftWare Reset
SpiWriteReg(RST_FSPI, 0xA5);
SpiWriteReg(FLUSH_TX, 0);
SpiWriteReg(FLUSH_RX, 0);
SpiWriteReg(WRITE_REG + STATUS, 0x70);
SpiWriteReg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0
while( SpiReadReg(READ_REG + EN_RXADDR) != 0x01);
SpiWriteReg(WRITE_REG + SETUP_AW, 0x03); // address witdth is 5 bytes
while( SpiReadReg(READ_REG + SETUP_AW) != 0x03);
SpiWriteReg(WRITE_REG + RF_CH, DEFAULT_CHANNEL); // select RF channel 2440MHz
while( SpiReadReg(READ_REG + RF_CH) != DEFAULT_CHANNEL);
SpiWriteReg(WRITE_REG + RX_PW_P0, BUFSIZE); // 6 bytes
while( SpiReadReg(READ_REG + RX_PW_P0) != BUFSIZE);
SpiWriteDat(WRITE_REG + TX_ADDR, RfId, 5); // writes TX_Address to XN297
SpiWriteDat(WRITE_REG + RX_ADDR_P0, RfId, 5); // RX_Addr0 same as TX_Adr for AutoAck
SpiWriteDat(WRITE_REG + BB_CAL, BB_cal_data, sizeof(BB_cal_data));
SpiWriteDat(WRITE_REG + RF_CAL2, RF_cal2_data, sizeof(RF_cal2_data));
SpiWriteDat(WRITE_REG + DEM_CAL, Dem_cal_data, sizeof(Dem_cal_data));
SpiWriteDat(WRITE_REG + RF_CAL, RF_cal_data, sizeof(RF_cal_data));
SpiWriteDat(WRITE_REG + DEM_CAL2, Dem_cal2_data, sizeof(Dem_cal2_data));
SpiWriteReg(WRITE_REG + DYNPD, 0x00); //YUAN LAI 0X01
SpiWriteReg(WRITE_REG +FEATURE, 0x00); //²»Ê¹ÄÜspi¿ØÖÆCE
SpiWriteReg(WRITE_REG + RF_SETUP, RF_POWER);
SpiWriteReg(WRITE_REG + SETUP_RETR, RETRY_MAX); // retry max is 5
SpiWriteReg(WRITE_REG + EN_AA, 0x01); // Enable auto.Ack:pipe0
//SpiWriteReg(ACTIVATE, 0x73);
if(BUFSIZE < 33)
{
SpiWriteReg(WRITE_REG +FEATURE, 0x00); // 32byte mode
}
else
{
SpiWriteReg(WRITE_REG +FEATURE, 0x18); // 64byte mode
}
//SpiWriteReg(ACTIVATE, 0x73);
}//end RF_Init
/******************************************************************************
XN297L_Initial
Initial RF in NORMAL_MODE
******************************************************************************/
void RF_NORMAL_MODE_Init(void)
{
u8 BB_cal_data[] = {0x0A,0x6D,0x67,0x9C,0x46}; //XN297L
u8 RF_cal_data[] = {0xF6,0x37,0x5D}; //XN297L
//u8 RF_cal2_data[] = {0x45,0x21,0xEF,0xAC,0x5A,0x50}; //XN297L
u8 RF_cal2_data[] = {0x45,0x21,0xEF,0x2C,0x5A,0x40};
u8 Dem_cal_data[] = {0x00}; //XN297L
u8 Dem_cal2_data[] = {0x0B,0xDF,0X02}; //XN297L
Rf_CE=0;
ucCurrent_Channel = DEFAULT_CHANNEL;
/*********************use xn297 NORMAL*********************/
SpiWriteReg(RST_FSPI, 0x5A); //SoftWare Reset
SpiWriteReg(RST_FSPI, 0xA5);
SpiWriteReg(FLUSH_TX, 0);
SpiWriteReg(FLUSH_RX, 0);
SpiWriteReg(WRITE_REG + STATUS, 0x70);
SpiWriteReg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0
while( SpiReadReg(READ_REG + EN_RXADDR) != 0x01);
SpiWriteReg(WRITE_REG + SETUP_AW, 0x03); // address witdth is 5 bytes
while( SpiReadReg(READ_REG + SETUP_AW) != 0x03);
SpiWriteReg(WRITE_REG + RF_CH, DEFAULT_CHANNEL); // select RF channel 2440MHz
while( SpiReadReg(READ_REG + RF_CH) != DEFAULT_CHANNEL);
SpiWriteReg(WRITE_REG + RX_PW_P0, BUFSIZE); // 6 bytes
while( SpiReadReg(READ_REG + RX_PW_P0) != BUFSIZE);
SpiWriteDat(WRITE_REG + TX_ADDR, RfId, 5); // writes TX_Address to XN297
SpiWriteDat(WRITE_REG + RX_ADDR_P0, RfId, 5); // RX_Addr0 same as TX_Adr for AutoAck
SpiWriteDat(WRITE_REG + BB_CAL, BB_cal_data, sizeof(BB_cal_data));
SpiWriteDat(WRITE_REG + RF_CAL2, RF_cal2_data, sizeof(RF_cal2_data));
SpiWriteDat(WRITE_REG + DEM_CAL, Dem_cal_data, sizeof(Dem_cal_data));
SpiWriteDat(WRITE_REG + RF_CAL, RF_cal_data, sizeof(RF_cal_data));
SpiWriteDat(WRITE_REG + DEM_CAL2, Dem_cal2_data, sizeof(Dem_cal2_data));
SpiWriteReg(WRITE_REG + DYNPD, 0x00); //YUAN LAI 0X01
SpiWriteReg(WRITE_REG +FEATURE, 0x00);
SpiWriteReg(WRITE_REG + RF_SETUP, RF_POWER);
SpiWriteReg(WRITE_REG + SETUP_RETR, 0x00); // Disable Retrans
SpiWriteReg(WRITE_REG + EN_AA, 0x00); // Disable auto.Ack:pipe0
if(BUFSIZE < 33)
{
SpiWriteReg(WRITE_REG +FEATURE, 0x00); // 32byte mode
}
else
{
SpiWriteReg(WRITE_REG +FEATURE, 0x18); // 64byte mode
}
}//end RF_Init
//两种模式随便
哪一种都可以!
5.主程序怎么处理呢?
void main(void )
{
SPI_Init();
delay_10us(1000);
#ifdef TRANS_NORMAL_MODE
RF_NORMAL_MODE_Init();//定义你想要的模式
#else
RF_ENHANCE_MODE_Init();
/* PTX Mode */
#ifdef RF_PTX
TX_Mode();
while(1)
{
u8 TransResult = 0;
TransResult = RF_Transmit(TxBuf, BUFSIZE);
if(TransResult & TX_DS) // Indicate receive ack successfully in Enhance mode
{
Led_TX = ~Led_TX;
}
else
{
Led_TX = 1;
}
delay_10us(2000);
}//end while
#endif
/* PRX Mode */
#ifdef RF_PRX
RX_Mode();
Led_RX = 0;
while(1)
{
u8 TransResult = 0;
TransResult = RF_Receive(RxBuf, BUFSIZE);
if(TransResult)
{
static u8 cnt;
cnt++;
Led_RX = ~Led_RX;
if(cnt>=90)
{
Led_TX = 1;
}
}
}
}
//————————————————————————————————————————————————————//
讲解一下 RF_Transmit(TxBuf, BUFSIZE);RF_Receive(RxBuf, BUFSIZE);这两个函数是发送盒接收函数,里面有处理流程,代码如下:
其实这个函数发射和接受都写到一起的!#ifdef RF_PTX 就是选择你是做发送还是接受。定义了就发送,没定义就是接收!
Led_RX 和 Led_TX 是两个状态灯,正常通信他会一直闪动,没通信的话就处于常亮状态、!
/******************************************************************************
XN297_RX
Receive data from RF
******************************************************************************/
u8 RF_Receive(u8 *buf, u8 lenth)
{
if(IRQ_STATUS)
{
return 0;
}
Rf_CE=0;
SpiReadDat(R_RX_PAYLOAD, buf, lenth);
SpiWriteReg(FLUSH_RX, 0);
SpiWriteReg(WRITE_REG + STATUS, 0x70);
Rf_CE=1;
return lenth;
}
/******************************************************************************
XN297_RX
Receive data from RF
******************************************************************************/
u8 RF_Receive(u8 *buf, u8 lenth)
{
if(IRQ_STATUS)
{
return 0;
}
Rf_CE=0;
SpiReadDat(R_RX_PAYLOAD, buf, lenth);
SpiWriteReg(FLUSH_RX, 0);
SpiWriteReg(WRITE_REG + STATUS, 0x70);
Rf_CE=1;
return lenth;
}
结束语:整个代码就这么简单,没什么吧,除了用了IO定义,其他的都是C语言上面的东西!最后希望论坛越办越好!!沫紫姐姐越活越年轻!
STLINK驱动:
XN297手册: