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

查看: 6613|回复: 7

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

[复制链接]

27

主题

498

回帖

40

蝴蝶豆

论坛元老

最后登录
2020-12-5
发表于 2015-11-13 10:21:14 | 显示全部楼层 |阅读模式
本帖最后由 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







<
回复

使用道具 举报

27

主题

498

回帖

40

蝴蝶豆

论坛元老

最后登录
2020-12-5
 楼主| 发表于 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
//两种模式随便
哪一种都可以!




回复 支持 反对

使用道具 举报

27

主题

498

回帖

40

蝴蝶豆

论坛元老

最后登录
2020-12-5
 楼主| 发表于 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语言上面的东西!最后希望论坛越办越好!!沫紫姐姐越活越年轻!
回复 支持 反对

使用道具 举报

27

主题

498

回帖

40

蝴蝶豆

论坛元老

最后登录
2020-12-5
 楼主| 发表于 2015-11-13 10:25:59 | 显示全部楼层
本帖最后由 dzzwoaizi 于 2015-11-13 10:45 编辑

STLINK驱动: stsw-link008.zip (506.78 KB, 下载次数: 44)
回复 支持 反对

使用道具 举报

33

主题

1243

回帖

0

蝴蝶豆

论坛元老

最后登录
2019-3-9
发表于 2015-11-13 10:50:06 | 显示全部楼层
谢谢分享.png
回复 支持 反对

使用道具 举报

10

主题

1651

回帖

0

蝴蝶豆

论坛元老

最后登录
2020-2-15
发表于 2015-11-13 11:16:47 | 显示全部楼层
楼主运气不错,拿到板子。
回复 支持 反对

使用道具 举报

7

主题

311

回帖

0

蝴蝶豆

高级会员

最后登录
2016-3-23
发表于 2015-11-13 12:01:10 | 显示全部楼层
一封邮件炸得这么多没时间的人突然都有时间了,期待楼主分享一些高水平的应用~
回复 支持 反对

使用道具 举报

1

主题

629

回帖

0

蝴蝶豆

金牌会员

最后登录
2020-3-7
发表于 2015-11-13 13:04:43 | 显示全部楼层
学习                       
回复 支持 反对

使用道具 举报

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版