这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » Let'Sdo第二期智能手环DIY——点亮RGB灯

共3条 1/1 1 跳转至

Let'Sdo第二期智能手环DIY——点亮RGB灯

工程师
2025-09-24 17:13:48     打赏

       在查看控制器板卡原理图后可以发现板卡板载了三个RGB LED灯。一个是通过芯片I/O直接控制的RGB LED灯;另外一个是通过电源管理芯片MAX20303BEWN+间接控制的;最后一个是连接在另外一个32位微控制器MAX32625IWY的引脚上。前两个RGB LED灯对应的原理图分别如下

image.png

image.png

       其中第一个是MAX78000直接控制的RGB LED灯,红色LED灯对应的引脚号是P2_0;绿色LED灯对应的引脚号是P2_1;蓝色LED灯对应的引脚号是P2_2。第二个是MAX20303BEWN+芯片控制的RGB LED灯,可以通过IIC间接控制。

       第一个RGB LED灯的控制可以直接通过Hello_World例程的源码进行控制,创建好Hello_World的例程后,main函数的源码如下:

    int count = 0;

    printf("Hello World!\n");

    while (1) {
        LED_On(LED1);
        MXC_Delay(500000);
        LED_Off(LED1);
        MXC_Delay(500000);
        printf("count : %d\n", count++);
    }

        可以看出对应的RGB LED灯对应的GPIO引脚直接被定义成LED1了。查看LED1的定义如下

image.png

       可以看出LED1对应的是红色LED灯;LED2对应的是绿色的LED灯;LED3对应的是蓝色的LED灯。其各自的宏定义的数字对应各自的I/O引脚号。RGB LED灯的亮灭是通过函数LED_On和LED_Off控制的,并且也进行了封装。源码只有对LED1的亮灭控制,所以为了点亮所有的RGB LED灯,所以修改源码为

    int count = 0;

    printf("Hello World!\n");

    while (1) {
        LED_On(LED1);
        MXC_Delay(500000);
        LED_Off(LED1);
        
        LED_On(LED2);
        MXC_Delay(500000);
        LED_Off(LED2);
        
        LED_On(LED3);
        MXC_Delay(500000);
        LED_Off(LED3);
        
        printf("count : %d\n", count++);
    }

       其作用是先让红绿蓝灯各自亮一定的时间。效果如下

       回过头来看main函数时发现没有时钟初始化和GPIO引脚初始化等就可以直接控制RGB LED灯了。看工程没有包含其他的.c文件,所以肯定在main函数被调用之前调用了某个函数来初始化它们。再看工程的.o文件有led.o和board.o两个文件,led.o就不用多说了,是控制LED灯的;而board.o文件一般是用作板载资源的初始化的,所以可能存在board.c,并且初始化了相关的资源。再看工程包含的Includes文件夹有对应的.h工程文件路径,所以可以通过这个路径找到对应的.c文件,而路径是软件安装路径的子文件夹下。通过在软件安装路径下所搜board可以找到对应的.c文件,一定要注意板卡的类型为FTHR_RevA,所以要看这个文件夹下的board.c文件。打开后可以在Board_Init函数看到LED的初始化源码

    if ((err = LED_Init()) != E_NO_ERROR) {
        MXC_ASSERT_FAIL();
        return err;
    }

       而LED_Init函数的源码在led.c文件中,可以通过同样的方式搜索到led.c的文件,对应的源码如下

int LED_Init(void)
{
    int retval = E_NO_ERROR;
    unsigned int i;

    /* setup GPIO for the LED */
    for (i = 0; i < num_leds; i++) {
        LED_Off(i); // Set the output value

        if (MXC_GPIO_Config(&led_pin[i]) != E_NO_ERROR) {
            retval = E_UNKNOWN;
        }
    }

    return retval;
}

      其中先是关闭所有的LED灯,然后对其引脚进行初始化,初始化的配置参数在led_pin数组中,而led_pin数组的定义和赋初值在board.c中,对应的源码如下

const mxc_gpio_cfg_t led_pin[] = {
    { MXC_GPIO2, MXC_GPIO_PIN_0, MXC_GPIO_FUNC_OUT, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIOH, MXC_GPIO_DRVSTR_0},
    { MXC_GPIO2, MXC_GPIO_PIN_1, MXC_GPIO_FUNC_OUT, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIOH, MXC_GPIO_DRVSTR_0},
    { MXC_GPIO2, MXC_GPIO_PIN_2, MXC_GPIO_FUNC_OUT, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIOH, MXC_GPIO_DRVSTR_0},
};

       通过前两个数组元素的初值,可以看到对应LED灯的完整引脚号P2_x(0,1,2)。

       然后是控制接在芯片MAX20303的RGB LED灯了。简单的方式是创建一个FTHR_I2C的例程。

image.png

      创建后的源码如下

    MXC_Delay(MXC_DELAY_MSEC(500)); //Wait for PMIC to power-up
    printf("\n******** Featherboard I2C Demo *********\n");

    printf("\nThis demo uses I2C to change the state of the\n");
    printf("on-board Power Management IC's RGB LED every second.\n");

    printf("\nYou should observe the LED cycling through it's\n");
    printf("eight color states.\n");

    int error, i = 0;

    //Setup the I2CM
    error = MXC_I2C_Init(PMIC_I2C, 1, 0);

    if (error != E_NO_ERROR) {
        printf("-->Failed master\n");
        while (1) {}
    } else {
        printf("\n-->I2C Initialization Complete");
    }

    MXC_I2C_SetFrequency(PMIC_I2C, I2C_FREQ);

    // Set the LED current strength
    mxc_i2c_req_t reqMaster;
    reqMaster.i2c = PMIC_I2C;
    reqMaster.addr = PMIC_SLAVE_ADDR;
    reqMaster.tx_buf = tx_buf;
    reqMaster.tx_len = INIT_LEN;
    reqMaster.rx_buf = NULL;
    reqMaster.rx_len = 0;
    reqMaster.restart = 0;

    tx_buf[0] = LED_CFG_REG_ADDR;
    tx_buf[1] = 1; //Set LED current to 1mA

    if ((error = MXC_I2C_MasterTransaction(&reqMaster)) != 0) {
        printf("Error writing: %d\n", error);
        while (1) {}
    }

    while (1) {
        MXC_Delay(MXC_DELAY_SEC(1));
        SetLEDs(i);
        i = (i + 1) % 8; //Cycle through 8 LED Colors
    }

       其中可以在while循环中看到设置LED亮灭函数为SetLEDs,而SetLEDs函数源码如下

void SetLEDs(int state)
{
    int error;
    // Set the LED Color
    mxc_i2c_req_t reqMaster;
    reqMaster.i2c = PMIC_I2C;
    reqMaster.addr = PMIC_SLAVE_ADDR;
    reqMaster.tx_buf = tx_buf;
    reqMaster.tx_len = LED_SET_LEN;
    reqMaster.rx_buf = NULL;
    reqMaster.rx_len = 0;
    reqMaster.restart = 0;

    tx_buf[0] = LED_SET_REG_ADDR;
    tx_buf[1] = (uint8_t)((state & PMIC_LED_BLUE) << 5); //Set Blue LED?
    tx_buf[2] = (uint8_t)((state & PMIC_LED_RED) << 4); //Set Red LED?
    tx_buf[3] = (uint8_t)((state & PMIC_LED_GREEN) << 3); //Set Green LED?

    if ((error = MXC_I2C_MasterTransaction(&reqMaster)) != 0) {
        printf("Error writing: %d\n", error);
        while (1) {}
    }
}

       可以看到是通过某个字节的某一位来控制RGB LED灯的亮灭的。下载后的效果如下




关键词: 智能     手环    

工程师
2025-09-25 15:14:17     打赏
2楼

理解得挺完整的。


助工
2025-09-25 21:37:11     打赏
3楼

这位选手很强,期待其它作品


共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]