67.嵌入式C语言进阶:结构体指针实战指南——STM32外设、传感器数据访问的高效技巧

一、结构体指针是什么?

结构体指针是一个指向结构体变量的指针变量,它存储的是结构体变量的内存地址。通过结构体指针,我们可以直接访问结构体的成员,而不需要拷贝整个结构体,大大节省了内存空间。

二、核心语法规则

  1. 普通结构体变量 :使用.(点号)访问成员,例如dev.temp
  2. 结构体指针 :使用->(箭头)访问成员,例如p_dev->temp
  3. 绑定地址 :定义结构体指针后,必须绑定一个已存在的结构体变量的地址(使用&取地址符),否则会导致程序跑飞。

三、基础代码示例:理解结构体指针

我们先看一个最基础的示例,直观感受结构体指针的使用:

c 复制代码
#include <stdio.h>

// 定义设备结构体
struct Device
{
    int temp;       // 温度
    int fan_speed;  // 风扇档位
};

int main(void)
{
    // 定义结构体变量并初始化
    struct Device dev = {28, 2};
    
    // 定义结构体指针,绑定dev的地址
    struct Device *p_dev = &dev;
    
    // 通过指针访问成员
    printf("温度:%d℃\n", p_dev->temp);
    printf("风扇档位:%d\n", p_dev->fan_speed);
    
    return 0;
}

运行结果

plaintext 复制代码
温度:28℃
风扇档位:2

四、结构体指针的核心优势

  1. 节省内存:传递结构体时,只需要传递指针(4字节),而不需要拷贝整个结构体,避免了内存浪费。
  2. 高效访问:直接通过指针访问结构体成员,不需要拷贝数据,访问速度更快。
  3. 代码简洁:在大型工程中,使用结构体指针可以简化函数参数传递,让代码更易维护。

五、嵌入式实战场景:STM32外设寄存器访问

在STM32开发中,外设寄存器通常以结构体的形式定义,通过结构体指针可以直接访问寄存器,这是STM32库的核心设计思想。

示例:访问GPIO外设寄存器

c 复制代码
#include "stm32f10x.h"

// 假设我们要访问GPIOC的ODR寄存器
void GPIO_Toggle(void)
{
    // 定义GPIO_TypeDef类型的指针,指向GPIOC的基地址
    GPIO_TypeDef *p_gpio = GPIOC;
    
    // 通过指针访问ODR寄存器,翻转第13位(LED灯)
    p_gpio->ODR ^= (1 << 13);
}

在STM32的标准库中,GPIO_TypeDef是一个结构体,包含了GPIO的所有寄存器,GPIOC是这个结构体的基地址,通过指针可以直接访问各个寄存器。

六、实战场景:传感器数据访问

在传感器驱动开发中,传感器的数据通常以结构体的形式存储,通过结构体指针可以高效地访问传感器数据。

示例:DHT11温湿度传感器数据访问

c 复制代码
#include <stdio.h>

// 定义DHT11传感器数据结构体
typedef struct {
    float temperature;  // 温度
    float humidity;     // 湿度
    uint8_t check_sum;  // 校验和
} DHT11_Data;

// 定义传感器驱动函数,返回结构体指针
DHT11_Data *DHT11_ReadData(void)
{
    static DHT11_Data data;  // 静态变量,避免函数返回后数据丢失
    // 模拟读取传感器数据
    data.temperature = 25.5;
    data.humidity = 60.0;
    data.check_sum = (uint8_t)(data.temperature + data.humidity);
    return &data;
}

int main(void)
{
    // 调用驱动函数,获取传感器数据指针
    DHT11_Data *p_sensor = DHT11_ReadData();
    
    // 通过指针访问传感器数据
    printf("温度:%.1f℃\n", p_sensor->temperature);
    printf("湿度:%.1f%%\n", p_sensor->humidity);
    
    return 0;
}

七、实战场景:设备参数缓存

在嵌入式系统中,设备参数通常存储在结构体中,通过结构体指针可以高效地访问和修改参数。

示例:设备参数管理

c 复制代码
#include <stdio.h>
#include <string.h>

// 定义设备参数结构体
typedef struct {
    char device_name[20];  // 设备名称
    int baud_rate;         // 波特率
    int power_mode;        // 电源模式
    uint8_t is_connected;  // 连接状态
} Device_Params;

// 初始化设备参数
void Device_Init(Device_Params *p_params)
{
    strcpy(p_params->device_name, "SmartDevice");
    p_params->baud_rate = 115200;
    p_params->power_mode = 1;
    p_params->is_connected = 0;
}

int main(void)
{
    Device_Params params;
    Device_Init(&params);  // 传递结构体指针
    
    // 通过指针访问参数
    printf("设备名称:%s\n", params.device_name);
    printf("波特率:%d\n", params.baud_rate);
    
    return 0;
}

八、使用结构体指针的注意事项

  1. 必须绑定地址:定义结构体指针后,必须绑定一个已存在的结构体变量的地址,否则会导致程序跑飞。
  2. 避免野指针 :不要使用未初始化的指针,不要返回局部变量的指针(除非使用static修饰)。
  3. 字节对齐:结构体的大小可能会因为字节对齐而变大,在使用指针访问时要注意成员的偏移量。

九、总结

结构体指针是嵌入式C语言中非常实用的技巧,它能帮你在STM32外设访问、传感器数据处理、设备参数管理等场景中,高效地访问结构体成员,节省内存空间,简化代码逻辑。在大型工程中,结构体指针几乎是必备的技巧,掌握它能让你的嵌入式开发能力更上一层楼。

如果你觉得这篇文章对你有帮助,欢迎点赞收藏,也可以在评论区分享你使用结构体指针的实战经验!

相关推荐
2401_894915531 小时前
Geo优化系统源码部署搭建技术——PHP程序开发部署指南
开发语言·php
找磁材2 小时前
空心杯电机与永磁体
开发语言·磁性材料·钕铁硼·磁钢
我不管我就要叫小猪2 小时前
C/C++----命名空间
c语言·开发语言·c++
兮动人2 小时前
Python字符串类型
开发语言·python·python字符串类型
自由随风飘2 小时前
JAVA中的面向对象-3
java·开发语言
白白白小纯2 小时前
算法篇—返回倒数第k个节点
c语言·数据结构·算法·leetcode
小羊先生car3 小时前
RTOS-F429-HAL-(动/静态)任务的创建(2026/7/27)
开发语言·算法·c#
无忧.芙桃3 小时前
数据结构之堆
c语言·数据结构·c++·算法·
西城微科方案开发3 小时前
LCD智能婴儿秤方案
单片机·嵌入式硬件