公司遗留了一个STM32的开发板我是安卓开发工程师第一次接触这个。慢慢摸索点灯写下此文档作为记录不为教学。1. 环境搭建1.1.STM32CubeMXST 在 STM32CubeIDE 2.0.0 中做了一个重要改动把 CubeMX 从 IDE 里剥离出来了。官方说明写得很清楚从 2.0 开始配置工作必须在独立的 STM32CubeMX 中完成然后再把生成的工程导入 CubeIDE 来编译和调试。https://www.st.com.cn/zh/development-tools/stm32cubemx.html#get-software1.2.STM32CubeIDEhttps://www.st.com.cn/zh/development-tools/stm32cubeide.html2. 进行点灯教程的方法用 CubeMX 配置引脚 → 生成 Keil 工程 → 用 Keil 写代码、编译、用 JLink 下载。我的方法用 CubeMX 配置引脚 → 生成 CubeIDE 工程 → 用 CubeIDE 写代码、编译、用 JLink 下载。本质区别只是把 写代码和编译的软件IDE 从 Keil 换成了 CubeIDE。点灯的代码逻辑、引脚配置、下载器JLink完全一样。2.1 使用STM32CubeMX生成初始程序2.1.1 双击打开STM32CubeMX2.1.2.搜索使用的芯片STM32G431C8T6Start My project from MCUCommercial Part Number 选择STM32G431C8T6双击load2.1.3 配置需要点亮的灯PA8这里是从原理图来看的开发板CAN_LIN_G431原理图.pdf来看PA8上有一个LR1灯点击PA8设置为GPIO_OutputCubeMX 的勾选只是决定 生成初始化代码 时要不要把对应引脚配置成“输出模式”并设置初始电平。它不会限制你后面写代码时能操作哪些引脚但是没有勾选其他引脚其他引脚不会输出任何东西它们处于“高阻态”相当于断路/悬空。2.1.4 打开调试接口防止后面电脑识别不到芯片System Core - SYS - Debug 设置为 Serial Wire时钟使用默认的不动就行2.1.5 保存为STM32CudeIDE项目Project NameCubeMXIEDLighting2Project LocationD:\project\STM32选择自己像要的目录Toolchain/IDESTM32CubeIDE2.2 使用STM32CudeIDE打开项目File - Open Projects form File System…点击Directory选择刚刚保存的目录2.2.1 如果打开后没有目录按照以下步骤打开目录window - Show View - Project Explorer2.3 编写点灯代码原来的代码这段代码能跑灯会闪但不建议长期这么写。原因GPIOA-ODR 0; 会影响整个 A 端口以后加了别的外设容易出问题。空循环延时不准且编译器优化后可能失效。可读性差别人看不懂 0x1FF 是啥意思。while(1){/* USER CODE END WHILE */// 注意这行是 CubeMX 生成的标记别删但你的代码写在它后面没问题GPIOA-ODR0;// 把 GPIOA 整个端口的输出数据寄存器清零PA8 输出低电平 → 灯亮for(unsignedinti0;i0x6FFFF;i);// 空循环消耗时间实现延时约几百毫秒GPIOA-ODR0x1FF;// 把 ODR 的低 9 位设为 10x1FF 二进制 1 1111 1111PA8 输出高电平 → 灯灭for(unsignedinti0;i0x6FFF;i);// 空循环延时比上面短所以灭的时间短/* USER CODE BEGIN 3 */}建议写法while(1){/* USER CODE END WHILE */HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_RESET);// PA8输出低电平灯亮板上LED是低电平点亮HAL_Delay(500);// 保持500毫秒0.5秒HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_SET);// PA8输出高电平灯灭HAL_Delay(500);// 保持500毫秒// 循环执行灯就会一直亮0.5秒、灭0.5秒地闪烁/* USER CODE BEGIN 3 */}看一下HAL_GPIO_WritePin源码实现voidHAL_GPIO_WritePin(GPIO_TypeDef*GPIOx,uint16_tGPIO_Pin,GPIO_PinState PinState){// 参数检查确保传入的引脚号合法assert_param(IS_GPIO_PIN(GPIO_Pin));// 参数检查确保传入的状态是 SET 或 RESETassert_param(IS_GPIO_PIN_ACTION(PinState));if(PinState!GPIO_PIN_RESET)// 如果要输出高电平{// 读当前 ODR 值 → 改某一位 → 写回 ODR。GPIOx-BSRR(uint32_t)GPIO_Pin;// 用 BSRR 寄存器把对应引脚置 1高电平}else// 否则输出低电平{GPIOx-BRR(uint32_t)GPIO_Pin;// 用 BRR 寄存器把对应引脚清 0低电平}}2.4 编译代码2.5 使用Jlink下载代码