这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » Let'sdo2025第二期活动[智能手环DIY活动]基础任务

共2条 1/1 1 跳转至

Let'sdo2025第二期活动[智能手环DIY活动]基础任务

工程师
2025-09-11 15:08:00     打赏

硬件介绍:MAX78000FTHR为快速开发平台,MAX78000  M4F处理器能够快速实施超低功耗、人工智能(AI)方案,器件集成卷积神经网络加速器。评估板包括MAX20303 PMIC,用于电池和电源管理。评估板规格为0.9in x 2.6in、双排连接器,兼容Adafruit Feather Wing外设扩展板。评估板包括各种外设,例如CMOS VGA图像传感器、数字麦克风、低功耗立体声音频CODEC、1MB QSPI SRAM、micro SD存储卡连接器、RGB指示LED和按键。


1、使用 eclipse maximsdk 的固件,学会点亮 RGB 灯

FvPqkNj3st3c3OPkKKwZvOkmSlSx

这个开发板上集成了一课3色LED,由图可知,使用了P2_0、P2_1、P2_2三个管脚,所以本任务转换为控制这三个GPIO管脚电平控制。打开官方的例程,找到GPIO例程。

/* Setup output pin. */
    gpio_out.port = MXC_GPIO_PORT_OUT;
    gpio_out.mask = MXC_GPIO_PIN_OUT;
    gpio_out.pad  = MXC_GPIO_PAD_NONE;
    gpio_out.func = MXC_GPIO_FUNC_OUT;
    MXC_GPIO_Config(&gpio_out);

    while (1) {
        /* Read state of the input pin. */
        if (MXC_GPIO_InGet(gpio_in.port, gpio_in.mask)) {
            /* Input pin was high, set the output pin. */
            MXC_GPIO_OutSet(gpio_out.port, gpio_out.mask);    //高电平
        } else {
            /* Input pin was low, clear the output pin. */
            MXC_GPIO_OutClr(gpio_out.port, gpio_out.mask);  //低电平
        }
    }

关注这段代码,这是一段控制GPIO输出的范例代码,参考这这个写法,将P2_0、P2_1、P2_2设置为输出,即可驱动OLED灯的亮灭。

image.png


2、实现 OLED 屏幕显示信息。移植了u8g2到这个开发板上,使用u8g2开源库来驱动OLED,用起来特别的方便。

移植u8g2关键是实现回调函数

#include "mxc_device.h"
#include "mxc_delay.h"
#include "gpio.h"
#include "u8g2.h"
#include "u8x8.h"
#include "oled.h"

#define MXC_GPIO_PORT_SDA MXC_GPIO2
#define MXC_GPIO_PIN_SDA  MXC_GPIO_PIN_6
#define MXC_GPIO_PORT_SCL MXC_GPIO2
#define MXC_GPIO_PIN_SCL  MXC_GPIO_PIN_7

void oled_init(void) {
	mxc_gpio_cfg_t gpio_out;
	/* Setup output pin. */
	gpio_out.port = MXC_GPIO_PORT_SDA;
	gpio_out.mask = MXC_GPIO_PIN_SDA;
	gpio_out.pad = MXC_GPIO_PAD_NONE;
	gpio_out.func = MXC_GPIO_FUNC_OUT;
	MXC_GPIO_Config(&gpio_out);
	gpio_out.port = MXC_GPIO_PORT_SCL;
	gpio_out.mask = MXC_GPIO_PIN_SCL;
	gpio_out.pad = MXC_GPIO_PAD_NONE;
	gpio_out.func = MXC_GPIO_FUNC_OUT;
	MXC_GPIO_Config(&gpio_out);
}

uint8_t u8x8_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int,	void *arg_ptr) {
	switch (msg) {
	case U8X8_MSG_GPIO_AND_DELAY_INIT:
		/* only support for software I2C*/
		oled_init();			//初始化GPIO
		break;
	case U8X8_MSG_DELAY_NANO:
		/* not required for SW I2C */
		break;

	case U8X8_MSG_DELAY_10MICRO:
		/* not used at the moment */
		break;

	case U8X8_MSG_DELAY_100NANO:
		/* not used at the moment */
		break;

	case U8X8_MSG_DELAY_MILLI:
		MXC_Delay(arg_int * 1000UL);		//毫秒延时
		break;
	case U8X8_MSG_DELAY_I2C:
		/* arg_int is 1 or 4: 100KHz (5us) or 400KHz (1.25us) */
		MXC_Delay(arg_int <= 2 ? 5 : 1);	//微秒延时
		break;

	case U8X8_MSG_GPIO_I2C_CLOCK:
		if (arg_int == 0) {
			//MXC_GPIO_OutSet(MXC_GPIO_PORT_SCL, MXC_GPIO_PIN_SCL);  // 高电平
			MXC_GPIO_OutClr(MXC_GPIO_PORT_SCL, MXC_GPIO_PIN_SCL);  // 低电平
		} else {
			MXC_GPIO_OutSet(MXC_GPIO_PORT_SCL, MXC_GPIO_PIN_SCL);  // 高电平
			//MXC_GPIO_OutClr(MXC_GPIO_PORT_SCL, MXC_GPIO_PIN_SCL);  // 低电平
		}
		break;
	case U8X8_MSG_GPIO_I2C_DATA:

		if (arg_int == 0) {
			//MXC_GPIO_OutSet(MXC_GPIO_PORT_SDA, MXC_GPIO_PIN_SDA);  // 高电平
			MXC_GPIO_OutClr(MXC_GPIO_PORT_SDA, MXC_GPIO_PIN_SDA);  // 低电平
		} else {
			MXC_GPIO_OutSet(MXC_GPIO_PORT_SDA, MXC_GPIO_PIN_SDA);  // 高电平
			//MXC_GPIO_OutClr(MXC_GPIO_PORT_SDA, MXC_GPIO_PIN_SDA);  // 低电平
		}
		break;
		/*
		 case U8X8_MSG_GPIO_MENU_SELECT:
		 u8x8_SetGPIOResult(u8x8, Chip_GPIO_GetPinState(LPC_GPIO, KEY_SELECT_PORT, KEY_SELECT_PIN));
		 break;
		 case U8X8_MSG_GPIO_MENU_NEXT:
		 u8x8_SetGPIOResult(u8x8, Chip_GPIO_GetPinState(LPC_GPIO, KEY_NEXT_PORT, KEY_NEXT_PIN));
		 break;
		 case U8X8_MSG_GPIO_MENU_PREV:
		 u8x8_SetGPIOResult(u8x8, Chip_GPIO_GetPinState(LPC_GPIO, KEY_PREV_PORT, KEY_PREV_PIN));
		 break;

		 case U8X8_MSG_GPIO_MENU_HOME:
		 u8x8_SetGPIOResult(u8x8, Chip_GPIO_GetPinState(LPC_GPIO, KEY_HOME_PORT, KEY_HOME_PIN));
		 break;
		 */
	default:
		u8x8_SetGPIOResult(u8x8, 1);
		break;
	}
	return 1;
}

void u8g2_Init(u8g2_t *u8g2) {
	u8g2_Setup_ssd1306_i2c_128x64_noname_f(u8g2, U8G2_R0, u8x8_byte_sw_i2c,
			u8x8_gpio_and_delay);
	u8g2_InitDisplay(u8g2);
	u8g2_SetPowerSave(u8g2, 0);
	u8g2_ClearBuffer(u8g2);
}

u8g2_t u8g2;
int main(void) {
	mxc_gpio_cfg_t gpio_out;

	u8g2_Init(&u8g2);
	/* Setup output pin. */
	gpio_out.port = MXC_GPIO_PORT_OUT;
	gpio_out.mask = MXC_GPIO_PIN_OUT;
	gpio_out.pad = MXC_GPIO_PAD_NONE;
	gpio_out.func = MXC_GPIO_FUNC_OUT;
	MXC_GPIO_Config(&gpio_out);

	u8g2_SetFont(&u8g2, u8g2_font_smart_patrol_nbp_tr);
	u8g2_SetFontRefHeightText(&u8g2);
	u8g2_SetFontPosTop(&u8g2);
	u8g2_DrawStr(&u8g2, 0, 30, "u8g2 Soft I2C");
	u8g2_SendBuffer(&u8g2);

	while (1) {
		MXC_GPIO_OutSet(gpio_out.port, gpio_out.mask);
		MXC_Delay(5000000);
		MXC_GPIO_OutClr(gpio_out.port, gpio_out.mask);
		MXC_Delay(5000000);
	}

	return 0;
}

最终的展示效果

image.png


3、驱动 MAX30102 传感器,采集数据并通过分析,生成血氧、心率,显示到 OLED 屏幕中。

FvPqkNj3st3c3OPkKKwZvOkmSlSx

首先看图,这个开发板的I2C硬件管脚为P0_16、P0_17两个管脚,OLED屏幕和MAX30102传感器都是走I2C接口。我使用一个I2C扩展板,将两个设备都和MAX78000FTHR的P0_16、P0_17连接起来,这里遇到个问题,单独接任意一个设备,通过I2C_SCAN例程能够很好滴读出设备的I2C地址,但是同时接两个设备后,就不能正常读取到地址了,不知道为啥,按理两个设备地址不同(OLED地址为:0X3C;心率计地址为:0X57)不应该有冲突,最后只能将OLED移到P2_6、P2_7管脚,使用模拟I2C来驱动。OLED的驱动依然使用u8g2来驱动。

在网上找了位


院士
2025-09-14 22:17:05     打赏
2楼

嗯~~

心脏还在跳呢!



共2条 1/1 1 跳转至

回复

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