【控制原理】查理复用
本文最后更新于35 天前,其中的信息可能已经过时,如有错误请发送邮件到tudougin@163.com

1. 什么是查理复用?

​ 查理复用是一种利用微控制器GPIO的三种状态(高、低、高阻态)来实现多个LED控制的方法,能够在 n 根引脚上控制最多 n×(n–1) 个LED。由Charlie Allen发明,特点是:

  • 无需外部芯片
  • 利用三态逻辑(高电平、低电平、高阻态)
  • 可用n个引脚控制n*(n-1)个LED

2. 工作原理

image-20250614223324903

​ 查理复用通过任意两根IO引脚间连接一个LED,并利用三态逻辑(高电平、低电平、高阻态)来控制电流方向,从而点亮指定的LED。

  1. 以点亮LED D1 为例:电流从 P0 → LED1 → P1 → 地,LED1导通
    • 设置 IO1 为高电平(输出1)
    • 设置 IO2 为低电平(输出0)
    • 设置 IO3、IO4 为高阻态(输入)
  2. 电阻的作用:每个IO串联一个电阻(例如100Ω),防止LED过电流烧毁。
  3. 同一时间只能点亮一颗LED(防止误导通),需要快速轮询刷新显示
  4. 所有未参与的IO要设置为高阻态,避免短路。

3. 示例代码

使用STM32的HAL库,通过查理复用技术,使用4个GPIO控制8颗LED轮流点亮。

  1. 硬件连接采用“查理复用”方法,将8颗LED连接在4个IO之间的不同组合方向上。
  • 例如:D1 连接 IO1(阳极)→ IO2(阴极),D2 反之,等等。
  1. 软件轮询控制流程:
  • 每次只点亮一颗LED,确保没有“串电”或短路。
  • 每颗LED点亮持续100ms,然后熄灭,进入下一颗。
  • 循环执行,实现 D1→D2→…→D8依次闪烁效果
  1. 电平控制逻辑:
  • 点亮某颗LED时:
    • 将其阳极IO设置为 推挽输出高电平
    • 将阴极IO设置为 推挽输出低电平
    • 其余两个IO设置为 输入高阻态
  • 点亮完毕后,全部IO恢复为输入状态(高阻态),为下一次点灯准备。

3.1 驱动代码

// 所有IO口初始化为输入高阻态
void Charlie_ResetAll(void) {
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    GPIO_InitStruct.Mode  = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull  = GPIO_NOPULL;

    GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3;  // 设定你的 IO
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);  // 假设都在 GPIOA
}

// 设置某一颗LED(ioHigh 为阳极,ioLow 为阴极)
void Charlie_Light(GPIO_TypeDef* port, uint16_t ioHigh, uint16_t ioLow) {
    Charlie_ResetAll();

    GPIO_InitTypeDef GPIO_InitStruct = {0};

    // 设置阳极 IO 输出高
    GPIO_InitStruct.Pin   = ioHigh;
    GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(port, &GPIO_InitStruct);
    HAL_GPIO_WritePin(port, ioHigh, GPIO_PIN_SET);

    // 设置阴极 IO 输出低
    GPIO_InitStruct.Pin   = ioLow;
    HAL_GPIO_Init(port, &GPIO_InitStruct);
    HAL_GPIO_WritePin(port, ioLow, GPIO_PIN_RESET);
}

3.2 使用实例

// IO 口定义
#define IO1 GPIO_PIN_0
#define IO2 GPIO_PIN_1
#define IO3 GPIO_PIN_2
#define IO4 GPIO_PIN_3

// 假设全部都在 GPIOA
void Charlie_TestCycle(void) {
    while (1) {
        // 点亮D1(IO1 -> IO2)
        Charlie_Light(GPIOA, IO1, IO2); HAL_Delay(100);

        // 点亮D2(IO2 -> IO1)
        Charlie_Light(GPIOA, IO2, IO1); HAL_Delay(100);

        // 点亮D3(IO2 -> IO3)
        Charlie_Light(GPIOA, IO2, IO3); HAL_Delay(100);

        // 点亮D4(IO3 -> IO2)
        Charlie_Light(GPIOA, IO3, IO2); HAL_Delay(100);

        // 点亮D5(IO3 -> IO4)
        Charlie_Light(GPIOA, IO3, IO4); HAL_Delay(100);

        // 点亮D6(IO4 -> IO3)
        Charlie_Light(GPIOA, IO4, IO3); HAL_Delay(100);

        // 点亮D7(IO4 -> IO1)
        Charlie_Light(GPIOA, IO4, IO1); HAL_Delay(100);

        // 点亮D8(IO1 -> IO4)
        Charlie_Light(GPIOA, IO1, IO4); HAL_Delay(100);
    }
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇