第十六周项目三:max带来的冲突

本文分析了一个关于函数模板冲突的问题,通过具体示例代码展示了如何区分标准库中的max函数与自定义的max函数模板,避免编译错误。

问题及代码:

/*
*Copyright (c)2015,烟台大学计算机与控制工程学院
*All rights reserved.
*文件名称: max带来的冲突  .cpp
*作    者:白云飞
*完成日期:2015年6月17日
*版 本 号:v1.0
*
*问题描述:分析下面程序出现的编译错误,给出解决的方案。
*/
#include<iostream>
using namespace std;
//定义函数模板
template<class T>
T max(T a, T b)
{
    return (a>b)?a:b;
}

int main()
{
    int x=2,y=6;
    double x1=9.123,y1=12.6543;
    cout<<"把T实例化为int:"<<std::max(x,y)<<endl;
    cout<<"把T实例化为double:"<<std::max(x1,y1)<<endl;
    return 0;
}


运行结果:

 

学习心得:

明确调用的是当前工作域中定义的max,所以要在max前加"std::"或者"::",也可以去掉using namespace std;,在main中cout等std中的名称前加std::,于是,main中调用的max,是本工作域中定义的函数模板。

内容概要:本文系统阐述了企业新闻发稿在生成式引擎优化(GEO)时代下的全渠道策略与效果评估体系,涵盖当前企业传播面临的预算、资源、内容与效果评估四大挑战,并深入分析2025年新闻发稿行业五大趋势,包括AI驱动的智能化转型、精准化传播、首发内容价值提升、内容资产化及数据可视化。文章重点解析央媒、地方官媒、综合门户和自媒体四类媒体资源的特性、传播优势与发稿策略,提出基于内容适配性、时间节奏、话题设计的策略制定方法,并构建涵盖品牌价值、销售转化与GEO优化的多维评估框架。此外,结合“传声港”工具实操指南,提供AI智能投放、效果监测、自媒体管理与舆情应对的全流程解决方案,并针对科技、消费、B2B、区域品牌四大行业推出定制化发稿方案。; 适合人群:企业市场/公关负责人、品牌传播管理者、数字营销从业者及中小企业决策者,具备一定媒体传播经验并希望提升发稿效率与ROI的专业人士。; 使用场景及目标:①制定科学的新闻发稿策略,实现从“流量思维”向“价值思维”转型;②构建央媒定调、门户扩散、自媒体互动的立体化传播矩阵;③利用AI工具实现精准投放与GEO优化,提升品牌在AI搜索中的权威性与可见性;④通过数据驱动评估体系量化品牌影响力与销售转化效果。; 阅读建议:建议结合文中提供的实操清单、案例分析与工具指南进行系统学习,重点关注媒体适配性策略与GEO评估指标,在实际发稿中分阶段试点“AI+全渠道”组合策略,并定期复盘优化,以实现品牌传播的长期复利效应。
【EI复现】基于主从博弈的新型城镇配电系统产消者竞价策略【IEEE33节点】(Matlab代码实现)内容概要:本文介绍了基于主从博弈理论的新型城镇配电系统中产消者竞价策略的研究,结合IEEE33节点系统进行建模与仿真分析,采用Matlab代码实现。研究聚焦于产消者(兼具发电与用电能力的主体)在配电系统中的竞价行为,运用主从博弈模型刻画配电公司与产消者之间的交互关系,通过优化算法求解均衡策略,实现利益最大化与系统运行效率提升。文中详细阐述了模型构建、博弈机制设计、求解算法实现及仿真结果分析,复现了EI期刊级别的研究成果,适用于电力市场机制设计与智能配电网优化领域。; 适合人群:具备电力系统基础知识和Matlab编程能力,从事电力市场、智能电网、能源优化等相关领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①学习主从博弈在电力系统中的建模方法;②掌握产消者参与电力竞价的策略优化技术;③复现EI级别论文的仿真流程与结果分析;④开展配电网经济调度与市场机制设计的相关课题研究。; 阅读建议:建议读者结合提供的Matlab代码,深入理解博弈模型的数学表达与程序实现细节,重点关注目标函数构建、约束条件处理及算法收敛性分析,可进一步拓展至多主体博弈或多时间尺度优化场景。
【BFO-BP】基于鳑鲏鱼优化算法优化BP神经网络的风电功率预测研究(Matlab代码实现)内容概要:本文研究了基于鳑鲏鱼优化算法(BFO)优化BP神经网络的风电功率预测方法,并提供了相应的Matlab代码实现。通过将生物启发式优化算法与传统BP神经网络相结合,利用鳑鲏鱼算法优化BP网络的初始权重和阈值,有效提升了模型的收敛速度与预测精度,解决了传统BP神经网络易陷入局部最优、训练效率低等问题。该方法在风电功率预测这一典型非线性时序预测任务中展现出良好的适用性和优越性,有助于提升风电并网的稳定性与调度效率。; 适合人群:具备一定机器学习与优化算法基础,从事新能源预测、电力系统调度或智能算法研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于风电场短期或超短期功率预测,提高电网调度的准确性;②作为智能优化算法与神经网络结合的典型案例,用于学习BFO等群智能算法在实际工程问题中的优化机制与实现方式;③为类似非线性系统建模与预测问题提供可复现的技术路线参考。; 阅读建议:建议读者结合Matlab代码深入理解算法实现细节,重点关注BFO算法的种群初始化、适应度函数设计、参数更新机制及其与BP网络的耦合方式,同时可通过更换数据集或对比其他优化算法(如PSO、GA)进一步验证模型性能。
当然可以!我们来 **非常详细地讲解** 第步: --- ## ✅ 目标:修改 `max30102.h` 和相关底层代码,使其适配你当前的 I²C 引脚与通信方式 你目前使用的是 **GPIO 模拟 I²C(软件 I²C)**,SCL 和 SDA 分别连接在 STM32 的某个 IO 上(比如 PB8 和 PB9),并且你已经有现成的 OLED 驱动中实现了 I²C 通信函数。 现在要让 MAX30102 芯片也能通过同样的方式通信 —— **不使用硬件 I²C,而是复用你的模拟 I²C 函数。** --- # 🧩 一、确认你的 I²C 硬件连接 假设你的接线如下(常见情况): | MAX30102 引脚 | 连接到 MCU | |---------------|-----------| | SCL | PB6 | | SDA | PB7 | | INT | PA1 | | VCC/GND | 3.3V / GND | > ⚠️ 注意:不要和 OLED 共用同一组引脚!否则会冲突! --- # 🔧 二、准备工作:确保已有可用的“通用模拟 I²C”函数 你在 `OLED.c` 中已经写了这些函数(江协科技风格): ```c void OLED_W_SCL(uint8_t BitValue); void OLED_W_SDA(uint8_t BitValue); void OLED_I2C_Start(void); void OLED_I2C_Stop(void); void OLED_I2C_SendByte(uint8_t Byte); ``` 但它们被命名为 `OLED_...`,说明是专用于 OLED 的。 👉 我们的目标是:**把这些函数抽象出来,变成“通用软件 I²C”函数,供 MAX30102 复用!** --- # ✅ 第一步:创建一个通用的软件 I²C 驱动模块(推荐做法) ### 📁 新建两个文件: - `soft_i2c.h` - `soft_i2c.c` --- ### ✅ `soft_i2c.h` —— 定义接口 ```c // soft_i2c.h #ifndef __SOFT_I2C_H #define __SOFT_I2C_H #include "stm32f10x.h" // ------------------ 用户可配置区 ------------------ // 设置 MAX30102 使用的 SCL 和 SDA 引脚 #define SOFT_I2C_SCL_PIN GPIO_Pin_6 #define SOFT_I2C_SDA_PIN GPIO_Pin_7 #define SOFT_I2C_PORT GPIOB // ------------------------------------------------- // 初始化函数 void Soft_I2C_Init(void); // 基础操作函数 void Soft_I2C_Start(void); void Soft_I2C_Stop(void); void Soft_I2C_SendByte(uint8_t byte); uint8_t Soft_I2C_RecvByte(uint8_t ack); // ack=1 发送ACK, ack=0 发送NACK uint8_t Soft_I2C_WaitAck(void); void Soft_I2C_Ack(void); void Soft_I2C_NAck(void); #endif ``` --- ### ✅ `soft_i2c.c` —— 实现通用模拟 I²C ```c // soft_i2c.c #include "soft_i2c.h" #include "Delay.h" // 必须包含延时函数 // 写 SCL 引脚电平 static void Soft_I2C_W_SCL(uint8_t bit) { if (bit) { GPIO_SetBits(SOFT_I2C_PORT, SOFT_I2C_SCL_PIN); } else { GPIO_ResetBits(SOFT_I2C_PORT, SOFT_I2C_SCL_PIN); } } // 写 SDA 引脚电平 static void Soft_I2C_W_SDA(uint8_t bit) { GPIO_InitTypeDef GPIO_InitStructure; // 配置为推挽输出 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin = SOFT_I2C_SDA_PIN; GPIO_Init(SOFT_I2C_PORT, &GPIO_InitStructure); if (bit) { GPIO_SetBits(SOFT_I2C_PORT, SOFT_I2C_SDA_PIN); } else { GPIO_ResetBits(SOFT_I2C_PORT, SOFT_I2C_SDA_PIN); } } // 读 SDA 引脚电平(需设为输入) static uint8_t Soft_I2C_R_SDA(void) { uint8_t value; GPIO_InitTypeDef GPIO_InitStructure; // 配置为上拉输入 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin = SOFT_I2C_SDA_PIN; GPIO_Init(SOFT_I2C_PORT, &GPIO_InitStructure); value = GPIO_ReadInputDataBit(SOFT_I2C_PORT, SOFT_I2C_SDA_PIN); return value; } // -------------------- I2C 协议实现 -------------------- void Soft_I2C_Start(void) { Soft_I2C_W_SDA(1); Soft_I2C_W_SCL(1); Delay_us(4); Soft_I2C_W_SDA(0); Delay_us(4); Soft_I2C_W_SCL(0); } void Soft_I2C_Stop(void) { Soft_I2C_W_SCL(0); Soft_I2C_W_SDA(0); Delay_us(4); Soft_I2C_W_SCL(1); Delay_us(4); Soft_I2C_W_SDA(1); Delay_us(4); } uint8_t Soft_I2C_WaitAck(void) { uint8_t timeout = 0; Soft_I2C_W_SDA(1); // 释放SDA Delay_us(1); Soft_I2C_W_SCL(1); Delay_us(1); while (Soft_I2C_R_SDA()) { timeout++; if (timeout > 100) { // 超时判断 Soft_I2C_Stop(); return 1; // 无应答 } } Soft_I2C_W_SCL(0); return 0; // 收到 ACK } void Soft_I2C_Ack(void) { Soft_I2C_W_SCL(0); Soft_I2C_W_SDA(0); Delay_us(2); Soft_I2C_W_SCL(1); Delay_us(2); Soft_I2C_W_SCL(0); } void Soft_I2C_NAck(void) { Soft_I2C_W_SCL(0); Soft_I2C_W_SDA(1); Delay_us(2); Soft_I2C_W_SCL(1); Delay_us(2); Soft_I2C_W_SCL(0); } void Soft_I2C_SendByte(uint8_t byte) { for (int i = 0; i < 8; i++) { Soft_I2C_W_SCL(0); if ((byte << i) & 0x80) { Soft_I2C_W_SDA(1); } else { Soft_I2C_W_SDA(0); } Delay_us(2); Soft_I2C_W_SCL(1); Delay_us(2); } Soft_I2C_W_SCL(0); } uint8_t Soft_I2C_RecvByte(uint8_t ack) { uint8_t byte = 0; Soft_I2C_W_SDA(1); // 释放总线,准备接收 for (int i = 0; i < 8; i++) { Soft_I2C_W_SCL(0); Delay_us(2); Soft_I2C_W_SCL(1); Delay_us(1); byte <<= 1; if (Soft_I2C_R_SDA()) byte |= 1; Delay_us(1); } Soft_I2C_W_SCL(0); if (ack) { Soft_I2C_Ack(); } else { Soft_I2C_NAck(); } return byte; } // 初始化 SCL/SDA 引脚 void Soft_I2C_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); Soft_I2C_W_SCL(1); Soft_I2C_W_SDA(1); } ``` --- # ✅ 第二步:修改 `max30102.h`,声明对外 API ```c // max30102.h #ifndef __MAX30102_H #define __MAX30102_H #include "stm32f10x.h" // MAX30102 寄存器地址 #define REG_INTR_STATUS_1 0x00 #define REG_INTR_STATUS_2 0x01 #define REG_INTR_ENABLE_1 0x02 #define REG_FIFO_WR_PTR 0x04 #define REG_OVF_COUNTER 0x05 #define REG_FIFO_RD_PTR 0x06 #define REG_FIFO_DATA 0x07 #define REG_FIFO_CONFIG 0x08 #define REG_MODE_CONFIG 0x09 #define REG_SPO2_CONFIG 0x0A #define REG_LED1_PA 0x0C #define REG_LED2_PA 0x0D #define REG_PILOT_PA 0x10 // I2C 地址(ADDR 接 GND → 0x57;读地址 +1) #define MAX30102_WRITE_ADDR 0xAE #define MAX30102_READ_ADDR 0xAF // 外部调用接口 void MAX30102_Init(void); void MAX30102_Reset(void); void maxim_max30102_read_fifo(uint32_t *pun_red_led, uint32_t *pun_ir_led); #endif ``` --- # ✅ 第步:修改 `max30102.c`,使用新的 `soft_i2c.c` 删除原来的底层 I²C 函数(如 `MAX30102_IIC_Start` 等),改用我们刚刚写的 `Soft_I2C_xxx()`。 ### 示例:重写 `maxim_max30102_write_reg` ```c // max30102.c #include "max30102.h" #include "soft_i2c.h" void maxim_max30102_write_reg(uint8_t reg_addr, uint8_t data) { Soft_I2C_Start(); Soft_I2C_SendByte(MAX30102_WRITE_ADDR); Soft_I2C_WaitAck(); Soft_I2C_SendByte(reg_addr); Soft_I2C_WaitAck(); Soft_I2C_SendByte(data); Soft_I2C_WaitAck(); Soft_I2C_Stop(); } ``` ### 示例:读取 FIFO 数据 ```c void maxim_max30102_read_fifo(uint32_t *pun_red_led, uint32_t *pun_ir_led) { uint8_t temp[6]; Soft_I2C_Start(); Soft_I2C_SendByte(MAX30102_WRITE_ADDR); Soft_I2C_WaitAck(); Soft_I2C_SendByte(REG_FIFO_DATA); Soft_I2C_WaitAck(); Soft_I2C_Start(); // Repeated Start Soft_I2C_SendByte(MAX30102_READ_ADDR); Soft_I2C_WaitAck(); // 读6字节 temp[0] = Soft_I2C_RecvByte(1); temp[1] = Soft_I2C_RecvByte(1); temp[2] = Soft_I2C_RecvByte(1); temp[3] = Soft_I2C_RecvByte(1); temp[4] = Soft_I2C_RecvByte(1); temp[5] = Soft_I2C_RecvByte(0); // 最后一个 NACK Soft_I2C_Stop(); // 合并为24位数据 *pun_red_led = ((uint32_t)temp[0] << 16) | ((uint32_t)temp[1] << 8) | temp[2]; *pun_ir_led = ((uint32_t)temp[3] << 16) | ((uint32_t)temp[4] << 8) | temp[5]; // 清除状态寄存器(可选) maxim_max30102_write_reg(REG_INTR_STATUS_1, 0xFF); maxim_max30102_write_reg(REG_INTR_STATUS_2, 0xFF); } ``` ### 初始化函数 ```c void MAX30102_Init(void) { Soft_I2C_Init(); // 初始化模拟 I²C 引脚 // 复位芯片 maxim_max30102_write_reg(REG_MODE_CONFIG, 0x40); Delay_ms(1); maxim_max30102_write_reg(REG_MODE_CONFIG, 0x03); // SpO2 mode maxim_max30102_write_reg(REG_SPO2_CONFIG, 0x27); // 100Hz, 400us pulse width maxim_max30102_write_reg(REG_LED1_PA, 0x24); // LED1电流 maxim_max30102_write_reg(REG_LED2_PA, 0x24); // LED2电流 maxim_max30102_write_reg(REG_FIFO_CONFIG, 0x0F); // 每样本24位,FIFO Almost Full = 17 } ``` --- # ✅ 第四步:主控板中断引脚处理(INT) 如果你把 MAX30102 的 `INT` 引脚接到 `PA1`,可以在 `menu.c` 或定时器里这样检测是否有新数据: ```c // 判断是否收到中断(有新数据) #define MAX30102_INT (!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)) // 下降沿有效 ``` 然后在采集时等待: ```c while (!MAX30102_INT); // 等待新数据 maxim_max30102_read_fifo(&red, &ir); ``` --- # ✅ 总结:你现在完成了什么? | 功能 | 是否完成 | |------|----------| | 创建独立的 `soft_i2c.c/.h` 模块 | ✅ | | 将 MAX30102 底层 I²C 替换为你自己的模拟 I²C | ✅ | | 不再依赖对方的 `delay.c` 或 `oled.c` | ✅ | | 所有通信走你定义的引脚(PB6/PB7) | ✅ | | 可与其他设备共用软件 I²C 总线(只要不同地址) | ✅ | --- ## ✅ 最终工程结构建议 ``` Project/ ├── Core/ │ ├── main.c │ └── ... ├── HardWare/ │ ├── OLED.c/.h │ ├── Key.c/.h │ ├── soft_i2c.c/.h ← 新增 │ ├── max30102.c/.h ← 修改过 │ ├── algorithm.c/.h ← Maxim算法 │ └── heart_rate_spo2.c/.h ← 你的UI封装 └── User/ └── menu.c ← 调用 Show_MAX30102_Page() ``` --- ##
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值