尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
STM32 小白实战 04:PWM 驱动舵机与直流电机,函数声明和大小写错误排查
.摘要今天完成了 PWM 驱动舵机的参数理解与按键控制并开始编写直流电机驱动模块。重点不是新增了多少代码而是确认了几类非常典型的 C 语言工程错误函数原型拼写不一致、函数被隐式声明、变量大小写不一致、标准库函数名大小写写错、PWM 通道接口未统一以及函数名中误插入空格。舵机已验证可以按照设定角度转动电机模块的编译问题已解决实物正反转与调速效果待确认。开发环境MCUSTM32F103 系列IDEKeil μVision 5编译器ARMCC V5.06 update 7固件库STM32F10x 标准外设库调试器ST-LINK本次外设舵机、按键、OLED、直流电机驱动接口PWM 定时器TIM2舵机 PWM 输出TIM2_CH2对应 PA1按键输入PB1、PB11一、舵机 PWM 中 ARR、PSC、CCR 到底怎样对应现象定时器配置为 ARR20000-1、PSC72-1已经知道 ARR120000但不理解为什么 CCR500 被课程当作舵机 0°。TIM_TimeBaseInitStructure.TIM_Period 20000 - 1; // ARRTIM_TimeBaseInitStructure.TIM_Prescaler 72 - 1; // PSCTIM_OCInitStructure.TIM_Pulse 0; // CCR原因按 72 MHz 定时器时钟计算经过 72 分频后 CNT 计数频率为 1 MHz即每个计数为 1 μs。ARR120000所以 PWM 周期为 20 ms频率为 50 Hz。CCR 在当前参数下可直接看作高电平持续的微秒数。CCR 500 →高电平0.5 msCCR 1500 →高电平1.5 msCCR 2500 →高电平2.5 msCCR500 并不是天生代表 0°而是当前程序采用“0.5 ms→0°、1.5 ms→90°、2.5 ms→180°”的舵机映射。解决方法把角度 0180°线性映射到 CCR 5002500。void Servo_SetAngle(float Angle){PWM_SetCompare2(Angle / 180.0f * 2000.0f 500.0f);}角度CCR高电平时间占空比0°5000.5 ms2.5%90°15001.5 ms7.5%180°25002.5 ms12.5%验证结果舵机在修正后可以按照设定角度转动。图1课程中的PWM频率、占空比和分辨率计算示意。二、OLED 角度变化但舵机不跟随转动现象按键读取正常OLED 上的角度值可以递增但舵机不随角度变化。Keil 提示 Servo_SetAngle 被隐式声明。warning: #223-D: function Servo_SetAngle declared implicitly原因Servo.h 中把函数名写成 Servo_SetAngel实际定义和调用是 Servo_SetAngle。函数原型没有被正确包含ARMCC 虽继续编译但浮点参数传递可能与实际函数定义不一致。//错误void Servo_SetAngel(float Angle);//正确void Servo_SetAngle(float Angle);解决方法统一 Servo.h、Servo.c 和 main.c 中的函数名与参数类型Servo.c 同时包含 Servo.h保存后执行 Rebuild all target files。#ifndef __SERVO_H#define __SERVO_Hvoid Servo_Init(void);void Servo_SetAngle(float Angle);#endif验证结果隐式声明警告消失舵机可以按照程序设定角度正常转动。图2 Servo_SetAngle()缺少正确函数原型时的隐式声明警告。三、Motor.c 中标准库函数和变量名写错现象编写电机正反转和速度控制函数时Keil 报告 GPIO_ReSetBits 被隐式声明speed 未定义。原因STM32 标准库正确函数名是 GPIO_ResetBits函数参数定义为 Speed但代码使用 speed。C 语言严格区分大小写。解决方法统一标准库函数名和变量名。void Motor_SetSpeed(int8_t Speed){if (Speed 0){GPIO_SetBits(GPIOA, GPIO_Pin_4);GPIO_ResetBits(GPIOA, GPIO_Pin_5);PWM_SetCompare3(Speed);}else{GPIO_ResetBits(GPIOA, GPIO_Pin_4);GPIO_SetBits(GPIOA, GPIO_Pin_5);PWM_SetCompare3(-Speed);}}验证结果GPIO_ReSetBits 和 speed 对应的编译错误消失。图3 Motor.c中函数名和变量名大小写错误。四、链接阶段提示 Undefined symbol PWM_SetCompare1现象语法编译通过但链接阶段报告 Undefined symbol PWM_SetCompare1并指出由 main.o 引用。Undefined symbol PWM_SetCompare1 (referred from main.o)原因main.c 调用了 PWM_SetCompare1()但当前 PWM 模块实际提供的是通道 3 接口 PWM_SetCompare3()。声明、定义和调用的 PWM 通道没有统一。解决方法主函数通过 Motor_SetSpeed() 使用电机模块不再调用不存在的 PWM_SetCompare1()PWM.h、PWM.c 和 Motor.c 统一使用 PWM_SetCompare3。void PWM_SetCompare3(uint16_t Compare){TIM_SetCompare3(TIM2, Compare);}验证结果PWM_SetCompare1 未定义的链接错误消失工程进入后续编译检查。五、Motor.h 中函数名被空格拆开现象Motor.h 报 incomplete type、expected a ;main.c 同时提示 Motor_SetSpeed 被隐式声明。void Motor _SetSpeed(int8_t Speed);原因Motor 和 _SetSpeed 之间多了一个空格编译器无法把它识别为函数名 Motor_SetSpeed导致头文件声明无效。解决方法删除多余空格并在头文件中包含能够定义 int8_t 的头文件。#ifndef _MOTOR_H#define _MOTOR_H#include stm32f10x.hvoid Motor_Init(void);void Motor_SetSpeed(int8_t Speed);#endif验证结果该问题已经解决相关编译错误和隐式声明警告消失。直流电机实物正反转与调速效果待确认。固定排查清单出现 declared implicitly 时先检查对应 .h 是否有正确函数原型。函数声明、函数定义和函数调用的名字及参数类型必须完全一致。C 语言区分大小写重点检查 Speed/speed、Reset/ReSet。错误来自 main.o 时优先在 main.c 搜索对应调用。Undefined symbol 属于链接错误要检查函数是否真正定义、源文件是否加入工程、接口名是否统一。PWM 通道必须一致初始化 CH3就使用 TIM_SetCompare3() 和 PWM_SetCompare3()。头文件中的函数名不能包含意外空格。每个 .c 文件尽量包含自己的 .h让接口不一致尽早暴露。修改头文件或接口后执行 Rebuild all target files。软件编译通过不等于硬件验证完成电机方向、转速和供电仍需实物测试。
RELATED

相关推荐

C++与libcurl构建工业级网络通信模块实战指南

C++与libcurl构建工业级网络通信模块实战指南

1. 项目概述:为什么选择C与CURL构建工业级通信?在工业自动化、物联网网关、边缘计算这些对稳定性和性能有严苛要求的领域,网络通信模块往往是整个系统的“大动脉”。我见过太多项目,初期为了快速验证,用Python脚本或者…

📅 2026/9/11 0:45:17
5个实战技巧:掌握Poco跨引擎UI自动化测试框架

5个实战技巧:掌握Poco跨引擎UI自动化测试框架

5个实战技巧:掌握Poco跨引擎UI自动化测试框架 【免费下载链接】Poco A cross-engine test automation framework based on UI inspection 项目地址: https://gitcode.com/gh_mirrors/poc/Poco Poco是一个基于UI检查的跨引擎测试自动化框架,专为游…

📅 2026/9/9 17:34:17
S3C2440 GPIO驱动开发与Linux子系统解析

S3C2440 GPIO驱动开发与Linux子系统解析

1. GPIO基础概念与S3C2440硬件特性GPIO(General Purpose Input/Output)是嵌入式系统中最基础也最重要的外设接口之一。在S3C2440这款经典的ARM9处理器上,GPIO控制器管理着多达130个可编程的通用IO引脚。这些引脚可以通过寄存器配置为输入或输出模式,实现…

📅 2026/8/23 17:18:37
MORE NEWS

更多资讯

📰

DeepSeek Harness 入门很简单(三)——DeepSeek Harness接入工具、MCP、Skill

前言 上篇文章 全面解析了 DeepSeek Harness 的通用配置与 Agent 预设机制。通用设置涵盖权限策略、模型接入及插件系统三大模块;预设方面详细对比了 DeepSeek 内置的四种 Agent 模式——标准模式、极简模式、PTC 模式和创造模式。尤其值得一提的是,创造…

📰

APF 人工势场:把“走向目标”和“远离障碍”写成一组力

APF 人工势场:把“走向目标”和“远离障碍”写成一组力摘要|本文介绍人工势场法在移动机器人局部规划中的基本思想,结合 MATLAB 实现解析吸引力、排斥力、目标点选择、速度控制与运动学更新,并讨论局部极小和参数敏感性等实际问题…

📰

【Java面试八股】Java基础篇|数据类型、面向对象、关键字、反射、注解、异常、新特性、序列化、设计模式、IO

Java 文章目录Java基础篇数据类型面向对象关键字浅拷贝深拷贝反射注解异常Objectjava新特性序列化设计模式I/ONative基础篇 java的特点 平台无关性面向对象内存管理 Java的优点缺点 优点 跨平台支持面向对象拥有强大的生态系统内存管理:自动垃圾回收机制多线程支持…

📰

《基于协同过滤算法的劳动纠纷法律援助推荐系统》

一、前言 劳动纠纷高发,普通劳动者找律师难、维权成本高、信息不对称。本系统围绕管理员、用户、律师三角色,基于协同过滤算法为用户智能推荐匹配律师,支持在线聊天咨询、线下预约、文书模板下载、AI 智能问答、数据可视化等完整功能。亮点在…

📰

SpringBoot+Vue母婴商城:前后端分离毕设项目设计与实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

家庭资源管理系统:量化管理提升家庭幸福指数

1. 家庭资源管理系统的核心价值现代家庭面临着前所未有的资源管理挑战。根据2023年家庭经济研究所的调查数据显示,83%的双职工家庭表示在财务、时间分配和情感维系方面存在管理压力。我设计这套家庭经营体系,正是为了解决这些痛点问题。这个系统最核心的…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬