stm32cubeIDE的使用

stm32官方出了个免费的IDE,可以很方便地配置(初始化)stm32项目。

安装相关

安装

下载地址【STM32的集成开发环境 】
(不要安装1.13.0及以上版本。新版的用不了山寨的st-link来调试程序,会卡在什么需要升级固件这里)
参考:
https://blog.csdn.net/qq_38113006/article/details/108699060
https://blog.csdn.net/qq_42038029/article/details/99735688

不要放在中文目录下执行安装程序,下面这个错误报错就是放在中文目录下运行的结果:
NSIS ERROR: error launching installer
在这里插入图片描述

st-link utility 安装

下载:https://www.st.com/zh/development-tools/stsw-link004.html
使用:https://blog.csdn.net/li520_fei/article/details/120082735

工程、芯片配置流程

https://www.cnblogs.com/pathfinder-world/p/13943911.html

黑色主题

软件自带个黑色主题,感觉够用了。
菜单Window–>Preference–>General–>Apearance–>Theme
在这里插入图片描述

占用C盘的问题

软件有个路径默认是存放在C盘的,他下载占用的空间还是挺大的,最好自己手动更改一下。
菜单Window–>Preference–>STM32Cube–>Firmware Updater–>Repository Setup
在这里插入图片描述

中文字体小的解决

在默认的配置中,假如在代码文件中写了中文,在显示时只会占一个英文字符位置,非常难看,如下图所示:
在这里插入图片描述
假如想正常显示,可以参考这里更改一个地方:【STM32开发笔记109:在STM32CubeIDE中调整字体显示】
window–>preference–>General–>Apearance–>Colors and Fonts–>Basic–>Text font, 在脚本处选择中欧字符,如下图所示:
在这里插入图片描述
这下子显示正常了。
在这里插入图片描述

中文注释乱码

【STM32CubeMX/IDE生成Code中的中文字符乱码】
【STM32CubeIDE常见问题】
假如我们在main.c或者其他它自动生成的文件中写了中文的注释,每次我们在.ioc界面中修改参数然后返回源码编辑时,原来的中文注释都会大概率部分乱码,如下图所示:
在这里插入图片描述

解决办法是添加环境变量 JAVA_TOOL_OPTIONS,设置其值为:-Dfile.encoding=UTF-8
在这里插入图片描述
注意这样设置之后,只保证后面新输入的中文不乱码,之前乱码的救不回来的。

工程导入

有时候我们在一台电脑A上面建立好工程后,需要把工程代码拷贝到电脑B继续用。那么工程文件夹拷贝到电脑B后,该如何使用?
这里有两种办法。

import Existing Projects into Workspace

推荐使用这种方式
从菜单 File–>Import
在这里插入图片描述
可以勾选Copy projects into workspace,这样代码就会被拷贝进工作空间,方便管理。
在这里插入图片描述

Import an Existing STM32CubeMX Configuration File(.ioc)

不推荐使用这个。因为这种方式是只会导入它STM32CubeMx相关的代码部分。也就是说,自己写的东西、添加的头文件啥的都不会导入进来。一般来说不是我们想要的结果。
从菜单 File–>Import an Existing STM32CubeMX Configuration File(.ioc)
在这里插入图片描述

flash相关

读写保护

在stm32cubeide中,貌似没有直接提供 Flash_EnableReadProtection 这个函数,而是需要自己实现。
参考:[STM32G031 程序设置读保护]【如何禁止STM32通过SWD和ISP升级保护自己的产品 HAL_FLASH_Program】
注意:

1.一定要执行 HAL_FLASH_OB_Launch()这个函数,而且在第一次执行之后,还需要芯片整个断电、重新上电才能生效。假如只是单纯的按复位的话,芯片会一动不动,像坏了一样,记得,要重新上电。
2.千万、千万、千万不要轻易选择level2,选择了之后,是永久性的,就回不去了,外部器件完全无法读写芯片了。我就是这样,把一块芯片搞费了。唉。 【STM32烧熔丝】

void Flash_EnableReadProtection(void)
{
  FLASH_OBProgramInitTypeDef OBInit;

  __HAL_FLASH_PREFETCH_BUFFER_DISABLE();

  HAL_StatusTypeDef ret =0;

  HAL_FLASHEx_OBGetConfig(&OBInit);
  printf("RDPLevel:0x%02x\r\n", OBInit.RDPLevel);
  if(OBInit.RDPLevel == OB_RDP_LEVEL_0)
  {
    OBInit.OptionType = OPTIONBYTE_RDP;
    OBInit.RDPLevel = OB_RDP_LEVEL_1; // 千万不能用level2, level2是写了一次就不能回来了
    HAL_FLASH_Unlock();
    HAL_FLASH_OB_Unlock();

    ret = HAL_FLASHEx_OBProgram(&OBInit);
    printf("HAL_FLASHEx_OBProgram:%d\r\n", ret);

    ret = HAL_FLASH_OB_Launch(); // 要加这个,否则重启、断电重启后都不生效
    printf(" HAL_FLASH_OB_Launch:%d\r\n", ret);

    HAL_FLASH_OB_Lock();
    HAL_FLASH_Lock();
  }
  __HAL_FLASH_PREFETCH_BUFFER_ENABLE();

}

主要用到了函数HAL_FLASHEx_OBProgram ,其中的保护等级:level0-不保护
参考【stm32专题二十九:Flash 读写保护】
在这里插入图片描述
在启动了读保护之后,假如在烧写时想解除的话,参考这里:【STM32读保护】

flash的读写(断电保存数据)

https://blog.csdn.net/yannanxiu/article/details/52837411

FSMC读写外部flash

【AN2784: Using the high-density STM32F10xxx FSMC peripheral to drive external memories】

SDIO的使用

【STM32CubeMX系列09——SDIO(SD卡读写、SD卡移植FATFS文件系统)】
【stm32 CubeMx 实现SD卡/sd nand FATFS读写测试】
【STM32F1 HAL库读写SD卡的操作要点】
记得要修改函数MX_SDIO_SD_Init中的hsd.Init.BusWide = SDIO_BUS_WIDE_1B;

1、sd/tf卡的最高支持25MHz的时钟。
2、其读写的最小单位是block,1block一般是512byte。
3、在写之前不用擦除。但是不擦除的话要注意原来数据的干扰。(也有说要擦除的【stm32 SDIO tf卡 速度(stm32 sd卡读写速度)】,暂时还没确定,到时候自己测试一下)(经过测试,好像写之前不用擦除)

当尝试通过stm32的usb_device把整个系统弄成sd卡读卡器时,sdio部分,请查看下面这个文章。此时,sdio的分频系数搞成0也是可以的。
[ [已解决] STM32F407,USB(3300,MSC),SDIO,DMA,读写卡速度【已解决】 ]
假如你不外加芯片,USB_OTG_FS模式下,最快也只能达到12MBits/s,也就是1.5MB/s左右。上面文章中的是额外加了usb芯片,启用了USB_OTG_HS才有的8MB/s的速度。
在这里插入图片描述

  int8_t ret = USBD_FAIL;

  if( HAL_SD_ReadBlocks_DMA(&hsd, buf, blk_addr, blk_len) == HAL_OK )
  {
	  ret = USBD_OK;
  }

  if( USBD_OK == ret )
  {
	  while(HAL_SD_GetState(&hsd) == HAL_SD_STATE_BUSY){};

	  while( HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER ){};
  }
  
------

  int8_t ret = USBD_FAIL;

  if( HAL_SD_WriteBlocks_DMA(&hsd, buf, blk_addr, blk_len) == HAL_OK )
  {
      ret = USBD_OK;
  }

  if( USBD_OK == ret )
  {
      while(HAL_SD_GetState(&hsd) == HAL_SD_STATE_BUSY){};

      while( HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER ){};
  }

  return ret;

虚拟串口

配置:https://blog.csdn.net/weixin_64946562/article/details/128886320
使用:https://blog.csdn.net/weixin_51002159/article/details/126644375
这里简单记录一下用法:发送数据用 CDC_Transmit_FS 即可;假如想收数据,可以通过在 USB_DEVICE/APP/usbd_cdc_if.c文件中的 CDC_Receive_FS 函数中加入自己的小手段(全局变量、指针、全局函数等),来实现同步、异步的处理。CDC_Receive_FS 这个函数应该是系统在接受到数据后中断调用的,我们添加上去的函数也要注意一下,避免进行太耗时的操作。

虚拟U盘

这个帖子【 [ARM] 一直想把STM32的内部FLASH做成个小U盘,参考了不少,一直不成功 】里面有个回帖的人bg4uvr,他给出了一个解决办法【bg4uvr / stm32_usb_mass_hal 】
需要注意的是,这里的这个MSC_MEDIA_PACKET也设置成和usbd_storage_if.c中的USER_BLK_SIZ一致。
在这里插入图片描述

帖子上使用的是STM32F103C8T6,他的flash是按页排放的。假如使用STM32F407的,它的flash是按照sector来存放的,需要参考这个文章来进行函数修改:【基于hal库实现stm32内部flash的读取】
假如你只是想尝试一下,那可以学我一样直接把存储区放到内存去(由于存放在内存区,每次重新上电后都需要格式化):

//#define FLASH_START_ADDR	0x08010000	//U盘占用FLASH空间起始地址
#define USER_BLK_NBR		64			//U盘块数量
#define USER_BLK_SIZ		1024		//U盘块大小
uint8_t myBuffer[USER_BLK_NBR * USER_BLK_SIZ] = {0}; // 我的u盘

int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size)
{
  /* USER CODE BEGIN 3 */
  UNUSED(lun);

  *block_num  = USER_BLK_NBR;
  *block_size = USER_BLK_SIZ;

  return (USBD_OK);
  /* USER CODE END 3 */
}

int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
  /* USER CODE BEGIN 6 */
  UNUSED(lun);
  UNUSED(buf);
  UNUSED(blk_addr);
  UNUSED(blk_len);

  if(lun == 0)
  {
	  memcpy(buf,(uint8_t *)(myBuffer + blk_addr * USER_BLK_SIZ), blk_len * USER_BLK_SIZ);
	  return USBD_OK;
  }

  return (USBD_OK);
  /* USER CODE END 6 */
}

int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
  /* USER CODE BEGIN 7 */
  UNUSED(lun);
  UNUSED(buf);
  UNUSED(blk_addr);
  UNUSED(blk_len);

  if(lun == 0)
  {
	  memcpy(myBuffer + blk_addr * USER_BLK_SIZ, buf, blk_len * USER_BLK_SIZ);
	  return USBD_OK;
  }

  return (USBD_OK);
  /* USER CODE END 7 */
}

文件系统

我用的spi芯片为W25Q16,容量为16Mbit=2MByte.
以这个为主,基本可以直接使用: 【STM32CubeMX学习笔记(25)——FatFs文件系统使用(操作SPI Flash)】
从这里修正一下文件系统创建,但是不要用他的 GET_BLOCK_SIZE: 【为SPI FLASH移植fatFs文件系统心得 (二)】

  BYTE workBuffer[4096 * 2]; // 最好是块的两倍以上
  int len = sizeof(workBuffer);
  retUSER = f_mkfs(USERPath, FM_FAT | FM_SFD, 4096, workBuffer, len); // 第三个参数填0也可以,但是填4096会稳妥一点
  // workBuffer、第三个参数的大小设置不合理的话,有可能会导致文件一部分被擦除。

这里可以知道id 【【STM32CubeMX学习】SPI读写W25Q16】

芯片唯一码

这个文章【STM32HAL库-读取芯片维一码(UID)】里面提供了很多种方法,我觉得最方便的还是用自带的hal函数最方便

	uint32_t uuid[3];
	uuid[0] = HAL_GetUIDw0();
	uuid[1] = HAL_GetUIDw1();
	uuid[2] = HAL_GetUIDw2();

加密库

假如我们需要在stm32中使用一些常用的加密算法对数据进行验证、加密的话,可以直接使用官方的加密库
【STM32Cube的STM32加密固件库软件扩展(UM1924) 】
这个库提供了各种加密算法的函数:AES-128, AES-192, AES-256 bits、HASH: 、RSA with PKCS#1v1.5:ECC (elliptic curve cryptography)等等。
使用方法:
参考官方的使用流程
【Cryptographic library 】【Getting started with the Cryptographic Library 】

开启芯片的crc

在这里插入图片描述

下载并解压,取其三个文件夹

将下载下来的文件解压,然后把MiddleWare文件夹里面的三部分的东西拷贝到某个文件夹下:
在这里插入图片描述

在项目工程中加入其include路径、lib路径、lib文件、源文件路径

然后添加include路径、lib路径、lib文件
include路径
在这里插入图片描述
lib路径
在这里插入图片描述lib文件
在这里插入图片描述

其中lib文件要根据你的stm32芯片进行选择:【微控制器和微处理器】
在这里插入图片描述源文件路径
在这里插入图片描述

修改interface文件夹里面的cmox_low_level_template.c文件

然后把interface文件夹里面的cmox_low_level_template.c 文件重命名为cmox_low_level.c
在这里插入图片描述

并在文件内容中,增加你当前所使用的芯片的相关头文件
在这里插入图片描述

但是这样设置完之后,编译还是会有问题:
undefined reference to `__HAL_RCC_CRC_RELEASE_RESET’
在这里插入图片描述
原因是在cmox_low_level.c文件中用到了这个函数(宏定义),但是实际上我们的这个型号(stm32f103ze)的hal库中没有这个函数。直接注释掉就行。
注:在我的另外一块芯片stm32f407zg中,有这个函数。总之有的话就留着,没的话就注释。
在这里插入图片描述

开始使用

ok,接下来就可以参考例程来使用这个库了。例程放在Projects这个文件夹里面。
在这里插入图片描述

在线升级 IAP

【干货 | 详解 stm32 在线 IAP 升级】
【stm32在线升级方案】
可以利用上面提到的flash读保护、加密库,对app.bin进行加密、解密,实现对程序的隐藏,防止别人拷贝、破解我们的stm32程序。
这个暂时用不到,先挖个坑。

AB相编码器的使用

https://blog.csdn.net/LeonSUST/article/details/89520902
https://blog.csdn.net/wang328452854/article/details/50579832
但是这种模式的话,不方便实现每个脉冲都触发一次中断(其实也可以通过一个额外的中断输入引脚来实现)。看具体需求了。

串口相关

串口

https://blog.csdn.net/qq_42038029/article/details/103835984
需要注意串口的中断接收函数的用法

  // 这个函数是指开启中断接收指定字节的数据,接收够之后,就会调用用户的中断回调函数《void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)》
  //然后中断会在调用了用户回调函数之后失效。
  //因此,假如需要持续接收数据,还要在回调函数那里重新调用这个函数,开启中断接收
  HAL_UART_Receive_IT(&huart1, aRxBuffer, 1);

串口实现自定义通讯协议:

https://blog.csdn.net/u010779035/article/details/103764852#comments

通过串口printf

https://blog.csdn.net/qq_36075612/article/details/96851644
在使用时,有时候必须要加上回车符才行

  // 这样不会触发发送
  printf("=-----wtf-----=");

  // 这样才行
  printf("=-----wtf-----=\r\n");

定时器的使用
https://blog.csdn.net/u010779035/article/details/104134877
定时器的PWM捕获
https://blog.csdn.net/as480133937/article/details/99407485

can总线相关

can的使用

https://blog.csdn.net/qq_42635852/article/details/109287203
https://www.jianshu.com/p/0f6a68d1a8d7

can的工作模式:loopback、silent、loopback combined with silent

https://blog.csdn.net/flydream0/article/details/8170368

can过滤器详解

https://blog.csdn.net/flydream0/article/details/52317532
https://blog.csdn.net/qq_35480173/article/details/98878309
在这里插入图片描述

//初始化can的过滤器
void can_filter_init(void)
{
	CAN_FilterTypeDef filter;

	uint32_t stdId = 0x123;        //这里写入两个CAN id, 一个为标准canID
	uint32_t extId = 0x1800f001;   //一个扩展canID

	filter.FilterBank = 0;
	filter.FilterMode = CAN_FILTERMODE_IDLIST;
	filter.FilterScale = CAN_FILTERSCALE_32BIT;
	filter.FilterIdHigh = stdId << 5; //将基本id放到STID中
	filter.FilterIdLow = 0 | CAN_ID_STD;  //设置IDE位为0
	//左移3是因为canid最多只能有11+18=29位,所以需要去掉高32-29=3位
	//然后此时左侧的16位是对齐寄存器的STID+EXID[17:13]的,所以直接右移,取下来就行。
	filter.FilterMaskIdHigh = ((extId << 3) >> 16) & 0xffff;
	//取最右面16bit数值, 加上对IDE位设置1,将其对赋值给寄存器
	filter.FilterMaskIdLow = (extId << 3) & 0xffff | CAN_ID_EXT;
	filter.FilterFIFOAssignment = CAN_FILTER_FIFO0;
	filter.FilterActivation = ENABLE;

	if(HAL_CAN_ConfigFilter(&hcan, &filter) != HAL_OK)
	{
		Error_Handler();
	}
}

常用操作

代码补全

alt + /

生成hex

项目右键–》properties。。。
在这里插入图片描述

添加第三方源码

参考下图:右键项目properties–C/C++ General–Paths and Symbols–Includes以及SourceLocation。
记得 Includes 以及 SourceLocation,这两个都要设置,一个对应头文件,一个对应源文件。
在这里插入图片描述

IIC、I2C

I2C使用
https://blog.csdn.net/u010779035/article/details/104346201

  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值