打印
[应用方案]

函数指针的用法

[复制链接]
1944|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
heisexingqisi|  楼主 | 2025-2-27 11:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
实现思路
定义灯效函数:
每个灯效(如正向流水、反向流水、闪烁等)实现为一个独立的函数。

定义函数指针类型:
使用 typedef 定义一个函数指针类型,方便调用。

主循环调用函数指针:
在主循环中通过函数指针依次调用不同的灯效函数。

#include "hc32f10x.h"

// 定义函数指针类型
typedef void (*LightEffectFunc)(void);

// 延时函数
void delay(u16 n)
{
    u16 i, j;
    for (i = 0; i < n; i++)
        for (j = 0; j < n; j++);
}

// 配置系统时钟
void RCC_Configuration(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
}

// 配置 GPIO
void GPIO_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    // 配置 GPIOB 的 Pin_0 到 Pin_7 为推挽输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
                                  GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  // 推挽输出模式
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 输出速度 50MHz
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    // 初始化时将所有 LED 熄灭
    GPIO_Write(GPIOB, 0xFF); // 0xFF 表示所有引脚输出高电平(熄灭)
}

// 灯效 1:正向流水灯
void LightEffect_Forward(void)
{
    for (int i = 0; i < 8; i++)
    {
        GPIO_WriteBit(GPIOB, GPIO_Pin_0 << i, Bit_RESET); // 点亮 LED
        delay(500); // 延时
        GPIO_WriteBit(GPIOB, GPIO_Pin_0 << i, Bit_SET);   // 熄灭 LED
    }
}

// 灯效 2:反向流水灯
void LightEffect_Backward(void)
{
    for (int i = 7; i >= 0; i--)
    {
        GPIO_WriteBit(GPIOB, GPIO_Pin_0 << i, Bit_RESET); // 点亮 LED
        delay(500); // 延时
        GPIO_WriteBit(GPIOB, GPIO_Pin_0 << i, Bit_SET);   // 熄灭 LED
    }
}

// 灯效 3:闪烁灯
void LightEffect_Blink(void)
{
    for (int i = 0; i < 3; i++) // 闪烁 3 次
    {
        GPIO_Write(GPIOB, 0x00); // 点亮所有 LED
        delay(500);
        GPIO_Write(GPIOB, 0xFF); // 熄灭所有 LED
        delay(500);
    }
}

// 灯效 4:交替闪烁
void LightEffect_Alternate(void)
{
    for (int i = 0; i < 3; i++) // 交替闪烁 3 次
    {
        GPIO_Write(GPIOB, 0xAA); // 点亮奇数位 LED (0xAA = 10101010)
        delay(500);
        GPIO_Write(GPIOB, 0x55); // 点亮偶数位 LED (0x55 = 01010101)
        delay(500);
    }
}

int main()
{
    RCC_Configuration();    // 配置系统时钟
    GPIO_Configuration();   // 配置 GPIO

    // 定义函数指针数组
    LightEffectFunc lightEffects[] = {
        LightEffect_Forward,  // 正向流水灯
        LightEffect_Backward, // 反向流水灯
        LightEffect_Blink,    // 闪烁灯
        LightEffect_Alternate // 交替闪烁
    };

    int effectCount = sizeof(lightEffects) / sizeof(lightEffects[0]); // 灯效数量

    while (1)
    {
        // 依次调用不同的灯效函数
        for (int i = 0; i < effectCount; i++)
        {
            lightEffects[i](); // 通过函数指针调用灯效函数
            delay(1000);      // 灯效之间的延时
        }
    }
}
代码说明
函数指针类型定义:

typedef void (*LightEffectFunc)(void); 定义了一个函数指针类型 LightEffectFunc,指向无参数、无返回值的函数。

灯效函数:

实现了 4 种灯效:

LightEffect_Forward:正向流水灯。

LightEffect_Backward:反向流水灯。

LightEffect_Blink:所有 LED 同时闪烁。

LightEffect_Alternate:奇数位和偶数位 LED 交替闪烁。

函数指针数组:

将灯效函数的地址存储在数组 lightEffects 中,方便依次调用。

主循环:

通过 for 循环依次调用函数指针数组中的灯效函数,实现花样流水灯效果。

运行效果
上电后,LED 会依次执行以下灯效:

正向流水灯。

反向流水灯。

所有 LED 闪烁。

奇数位和偶数位 LED 交替闪烁。

每种灯效执行完毕后,会延时 1 秒,然后切换到下一种灯效。

使用特权

评论回复
沙发
heisexingqisi|  楼主 | 2025-2-27 11:57 | 只看该作者
扩展功能
增加更多灯效:

可以继续添加新的灯效函数,并将其地址加入 lightEffects 数组。

随机灯效:

使用随机数生成器选择灯效函数,实现随机切换效果。

按键控制:

通过按键切换灯效,增加交互性。

使用特权

评论回复
板凳
yangjiaxu| | 2025-2-27 13:12 | 只看该作者
点灯其实要是玩的好,效果也是不错的,而且点灯确实锻炼逻辑思路

使用特权

评论回复
地板
zerorobert| | 2025-4-5 21:01 | 只看该作者
函数指针是存储函数地址的变量,通过指针间接调用函数。

使用特权

评论回复
5
chenjun89| | 2025-4-5 21:32 | 只看该作者
函数指针和指针函数要分清楚,函数指针是指函数的入口地址,指针函数是指函数返回的变量位指针。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

144

主题

2720

帖子

2

粉丝