在嵌入式开发中,我们经常需要编写函数来操作硬件寄存器。本文通过对比定时器的两个典型的函数——PWM_SetCompare1IC_GetFreq,从多个角度讲解 C 语言函数的参数与返回值设计。

1. 函数原型对比

// ① 设置 PWM 比较值
void PWM_SetCompare1(uint16_t Compare);

// ② 获取频率
uint32_t IC_GetFreq(void);
函数 返回类型 参数列表
PWM_SetCompare1 void uint16_t Compare
IC_GetFreq uint32_t void

1.1 void 在两个函数里的含义不同

在 C 语言中,void 有两个常见用途:

  • 作为返回类型:表示函数不返回任何数据。
  • 作为参数列表:表示函数不接受任何参数。

因此:

void PWM_SetCompare1(uint16_t Compare);

这里的 void返回类型,表示函数执行完后不会把任何结果返回给调用者。

uint32_t IC_GetFreq(void);

这里的 void参数列表,表示调用这个函数时不需要传任何参数。

2.数据流方向完全不同

2.1 PWM_SetCompare1:数据从外部传入函数

void PWM_SetCompare1(uint16_t Compare)
{
    TIM_SetCompare1(TIM3, Compare);
}

数据流向:

调用者
  │
  │ 传入 uint16_t Compare
  ▼
PWM_SetCompare1()
  │
  │ 把 Compare 传给 TIM_SetCompare1()
  ▼
TIM3 比较寄存器 CCR1

它需要外界告诉它:“你要把 PWM 比较值设置成多少?”所以它必须有参数。

2.2 IC_GetFreq:数据从函数内部返回给外部

uint32_t IC_GetFreq(void)
{
    return 1000000 / TIM_GetCapture1(TIM3);
}

数据流向:

TIM3 捕获寄存器
  │
  │ TIM_GetCapture1(TIM3) 读取
  ▼
IC_GetFreq()
  │
  │ 计算 1000000 / 捕获值
  ▼
return 返回给调用者

它不需要外界给它任何东西,自己从硬件寄存器里读数据、计算,然后把结果交出来。所以它必须有返回值。

3.从 C 语言函数机制理解

3.1参数:函数的输入口

C 函数通过参数接收外部数据。

void PWM_SetCompare1(uint16_t Compare)

uint16_t Compare形参,相当于函数内部的一个局部变量。

调用时:

PWM_SetCompare1(500);

这里的 500实参

C 语言参数传递是值传递,即把实参的值复制一份传给形参。函数内部对形参的修改不会影响外部变量。不过本函数中并没有修改 Compare,只是将其转交给 TIM_SetCompare1

3.2 返回值:函数的输出口

C 函数通过 return 把结果返回给调用者。

uint32_t IC_GetFreq(void)
{
    return 1000000 / TIM_GetCapture1(TIM3);
}

调用时:

uint32_t freq = IC_GetFreq();

函数执行到 return 时:

  1. 计算表达式 1000000 / TIM_GetCapture1(TIM3)
  2. 将结果作为函数返回值;
  3. 返回到调用位置;
  4. 调用者用 freq 接收结果。

如果没有返回值,调用者就无法获得频率值。

3.3 为什么一个用 void 返回,一个用 uint32_t 返回?

  • PWM_SetCompare1 的目的是执行动作(设置寄存器),不需要返回结果,所以返回类型为 void
  • IC_GetFreq 的目的是获取数据(频率值),必须将结果返回给调用者,所以返回类型为 uint32_t

4. 从嵌入式硬件操作角度理解

4.1 PWM_SetCompare1 是写寄存器

TIM_SetCompare1(TIM3, Compare);

最终写入 TIM3 的 CCR1 寄存器,用于设置 PWM 占空比。

例如,假设自动重装值 ARR = 999:

PWM_SetCompare1(500);
// 占空比 = 500 / (999 + 1) ≈ 50%

它是一个输出控制函数

4.2 IC_GetFreq 是读寄存器

return 1000000 / TIM_GetCapture1(TIM3);

先读取 TIM3 输入捕获值,再计算频率。若定时器计数频率为 1 MHz,则:

频率 = 1000000 / 捕获计数值

例如捕获值为 1000,则频率为 1000 Hz。

它是一个输入测量函数

5. 调用方式对比

5.1设置 PWM

PWM_SetCompare1(500);

调用时必须传参数,不需要接收返回值。

5.2 获取频率

uint32_t freq;
freq = IC_GetFreq();

调用时不能传参数,通常需要用变量接收返回值。

通过本文的对比分析,相信你已经理解:PWM_SetCompare1 是一个“设置/执行”类函数,需要外部传入数据;IC_GetFreq 是一个“查询/获取”类函数,需要向外部返回数据。掌握这一点,不仅有助于阅读官方库函数,更能帮助你在自己封装模块时设计出清晰、易用的接口。

如果你觉得这篇文章对你有帮助,欢迎点赞、收藏、关注我,你的支持是我持续分享的最大动力。后续我还会继续更新嵌入式开发、C 语言进阶、STM32 实战等系列内容,让我们一起进步!

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐