你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【NUCLEO-L476RG开发】+如何快速上手你手中的开发板+驱动磐... 精华

[复制链接]
dear祝子 提问时间:2015-11-13 10:21 /
本帖最后由 dzzwoaizi 于 2015-11-13 10:38 编辑

/*--------------------------------------------*/致歉;收到论坛开发板那么长时间,由于工作太忙一直没有发表帖子,再次致歉论坛!
/*--------------------------------------------*/
闲话不说,如何快速的入手你手中的NUCLEO开发板呢!资料!绝对是资料能够让你快速入手的最简单方法。个人认为STM32能够成功不仅靠他最优的性价比,还有他的资料非常丰富,我是一个“剁手党”,比较喜欢鲁迅的“拿来主义”,下面请看如何找到你想要的资料!
第一步:打开STM32社区的界面找到资料下载
360截图20151113090908101.jpg

你会看到各种各样的资料,
例如:我们这次的板子是NUCLEO-L476RG,我们找到

360截图20151113091406801.jpg
这里面包含了所有的关于此板子的资料(PCB原理图demo都有)

360截图20151113091701088.jpg
打开后所有的资料都尽收眼底啦!赶快下载吧!

360截图20151113091922626.jpg
/-----------------------------------------------------------------------------------------------/
上面的文档对他的资料做了详细的讲解,我再次就不抄人家的的了,我之前有的M0核的M3核的STLINK驱动直接就能下载,这个板子有点怪,之前的驱动下载不了,我会在论坛最后给大家STlink驱动!
在这个文件家里就有了所有的官方历程代码,这是HAL库的,标准的外设库好像没有,我看了给出来一些资料,应该可以自己建立工程!
我在开发中就是用的这些代码写底层,稍微在修改一下就可以用了!再结合寄存器手册,在处理速度要求过快的场合,你也可以直接操作寄存器来实现各种功能!
特别注意:IAR7.3的暂时还没有支持此芯片,应该需要更高的版本,MDK5.3的是支持的,我编译过了!可以用!

26abe762d4f0471fb4bde3b65ddb493e.jpg







收藏 3 评论7 发布时间:2015-11-13 10:21

举报

7个回答
dear祝子 回答时间:2015-11-13 10:23:35
本帖最后由 dzzwoaizi 于 2015-11-13 10:43 编辑

第二节:如何驱动XN297L模块,这个模块和大众用的RNF24L01功能是一样的!都是2.4G模块,XN297L传输的距离会更远一些哦!我这里用的是QFN20L030封装的哦!还有两种分装你们可以自己搜搜哦!
下面看一些资料
1.引脚定义
360截图20151113104032271.jpg 360截图20151113104105919.jpg

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
//两种模式随便
哪一种都可以!




dear祝子 回答时间:2015-11-13 10:24:10

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语言上面的东西!最后希望论坛越办越好!!沫紫姐姐越活越年轻!
dear祝子 回答时间:2015-11-13 10:25:59
本帖最后由 dzzwoaizi 于 2015-11-13 10:45 编辑

STLINK驱动: stsw-link008.zip (506.78 KB, 下载次数: 44)
风子 回答时间:2015-11-13 10:50:06
谢谢分享.png
yanhaijian 回答时间:2015-11-13 11:16:47
楼主运气不错,拿到板子。
jiaswang 回答时间:2015-11-13 12:01:10
一封邮件炸得这么多没时间的人突然都有时间了,期待楼主分享一些高水平的应用~
disheng4688 回答时间:2015-11-13 13:04:43
学习                       

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版