嵌入式开发c语言学习教程:从基础到硬件控制,实例代码可复用

admin 综合编程开发技术 3


想做嵌入式开发的朋友,是不是总觉得 C 语言和硬件结合那块特别难?看着别人写的控制传感器、驱动电机的代码,自己却不知道从哪儿下手?其实啊,嵌入式里的 C 语言用法,虽然比纯软件编程多了点硬件相关的东西,但底子还是咱们学的那些基础语法,今天兔子哥就从基础讲到硬件控制,给的实例代码都是能直接复用的,一起往下看吧!

嵌入式 C 语言和普通 C 语言,到底差在哪儿?


很多人刚开始学的时候,会问嵌入式 C 和我们平时学的 C 语言有啥不一样?说白了,主要是多了和硬件打交道的部分,但基础语法一模一样。
比如变量、循环、函数这些,在哪种 C 语言里都一样用。不一样的地方在于:
  • 嵌入式里经常用无符号类型,比如 unsigned char、unsigned int,因为硬件寄存器的值一般都是非负的。
  • 会大量用到位操作,比如移位、与或非,因为控制硬件时经常要操作寄存器的某一位或某几位。
  • 函数可能会有中断服务函数,硬件触发某个事件时(比如按键按下),会自动跳转到这个函数执行。

举个简单的位操作例子,要把寄存器的第 3 位设置为 1,其他位不变,代码可以这么写:
c运行
#define GPIO_REG (*(volatile unsigned int *)0x40010000) // 寄存器地址GPIO_REG |= (1 << 3); // 第3位置1,其他位不变

这种写法在嵌入式里到处都是,刚开始可能看着别扭,写多了就习惯了。

怎么用 C 语言控制硬件?先从 GPIO 开始


GPIO 就是通用输入输出口,嵌入式开发里最常用的硬件接口了,控制 LED、读取按键状态都靠它。
要控制 GPIO,一般分三步:
  1. 使能 GPIO 时钟:就像给硬件通电,不然你怎么操作都没用,不同芯片的时钟寄存器地址不一样,但用法类似。
  2. 配置 GPIO 模式:是输入还是输出,比如 LED 一般接输出模式,按键接输入模式。
  3. 读写 GPIO 端口:输出模式下写 1 或 0 控制电平,输入模式下读电平判断状态。

给个 LED 闪烁的实例代码框架,这个代码改改寄存器地址,在 STM32、51 单片机上都能用:
c运行
// 假设LED接在GPIOA的第5位#define GPIOA_CLOCK (*(volatile unsigned int *)0x40020000)#define GPIOA_MODE  (*(volatile unsigned int *)0x40020004)#define GPIOA_ODR   (*(volatile unsigned int *)0x40020014)void LED_Init() {GPIOA_CLOCK |= (1 << 0); // 使能GPIOA时钟GPIOA_MODE &= ~(3 << 10); // 清除原来的配置GPIOA_MODE |= (1 << 10);  // 设置为输出模式}void LED_On() {GPIOA_ODR |= (1 << 5); // 第5位置1,LED亮}void LED_Off() {GPIOA_ODR &= ~(1 << 5); // 第5位清0,LED灭}// 主函数里循环亮灭int main() {LED_Init();while(1) {LED_On();Delay_ms(500); // 延时500毫秒LED_Off();Delay_ms(500);}}

这里的 Delay_ms 函数,不同芯片实现不一样,但你可以直接用芯片厂商提供的库函数,或者自己写个简单的延时,这个代码框架是通用的。

传感器数据怎么读?通信协议是关键


嵌入式开发里经常要读传感器数据,比如温湿度、光照强度,这时候就得用到 I2C、SPI 这些通信协议,用 C 语言实现这些协议其实不难。
以 I2C 为例,它只有两根线,一根时钟线 SCL,一根数据线 SDA,通信时要严格按照协议规定的时序来。下面是 I2C 启动信号的代码,这个函数在很多传感器读取中都能复用:
c运行
void I2C_Start() {SDA_HIGH(); // 数据线拉高SCL_HIGH(); // 时钟线拉高Delay_us(5); // 延时一小会儿SDA_LOW();  // 数据线拉低,启动信号Delay_us(5);SCL_LOW();  // 时钟线拉低,准备发送数据}

有个朋友做温湿度传感器项目时,就是用了这个启动信号函数,再加上传感器手册里的读写指令,很快就把数据读出来了。他说其实协议看着复杂,拆成一个个小函数就简单了,比如启动、停止、发送字节、接收字节,每个函数做好了,拼起来就行。

中断怎么用?让硬件自己 “说话”


有时候我们希望硬件发生某个事件时,程序能立刻响应,比如按键按下时马上执行某个操作,这时候就需要用到中断。
配置中断的步骤大概是:
  1. 使能中断时钟,和 GPIO 时钟类似。
  2. 配置中断触发方式,比如上升沿触发、下降沿触发。
  3. 编写中断服务函数,里面放要执行的操作。
  4. 使能中断,相当于打开开关。

比如外部中断的配置代码,这个结构在很多场景都能用:
c运行
void EXTI_Init() {// 使能中断时钟RCC->APB2ENR |= (1 << 14);// 配置中断触发方式为下降沿EXTI->FTSR |= (1 << 0);// 使能中断线0EXTI->IMR |= (1 << 0);// 使能NVIC中断NVIC_EnableIRQ(EXTI0_IRQn);}// 中断服务函数,名字要和启动文件里的一致void EXTI0_IRQHandler() {if(EXTI->PR & (1 << 0)) { // 检查是否是线0触发// 这里放中断要执行的操作,比如翻转LEDLED_Toggle();EXTI->PR |= (1 << 0); // 清除中断标志位}}

中断服务函数要尽量短,别放太多代码,不然会影响其他操作,这是很多新手容易犯的错。
兔子哥觉得,学嵌入式 C 语言,最重要的是多动手,拿到一块开发板,对着 datasheet 看寄存器地址,然后写代码去操作,看到 LED 真的闪起来,按键真的有反应,那种成就感是看书比不了的。给的这些代码,你可以保存下来,换个项目改改寄存器地址和参数就能用,能省不少事。
刚开始别贪多,先把 GPIO、中断、简单的通信协议搞明白,再慢慢学复杂的外设。遇到问题多看看芯片手册,那上面写得比谁都清楚。希望这些能帮到你,有啥卡壳的地方,随时来问兔子哥哈。

标签: 驱动电机 一模一样

发布评论 1条评论)

  • Refresh code

评论列表

2025-10-26 02:15:22

嵌入式C语言、基础到硬件、实例代码可复用。