BM43包含min的函数栈

该文章介绍了一个C++实现的栈类,其中包含push、pop、top和min等方法。push和pop操作维护了两个栈,s1用于常规栈操作,s2则保持当前栈中的最小值。在push时,如果新值小于s2的顶部值,s2也会存储新值,确保能快速获取最小值。pop操作则同时从两个栈中弹出元素。

包含min函数的栈_牛客题霸_牛客网 (nowcoder.com)

 

class Solution {
  public:
    //用于栈的push 与 pop
    stack<int> s1;
    //用于存储最小min
    stack<int> s2;

    void push(int value) {
        s1.push(value);
        if (s2.empty() || s2.top() > value)
            s2.push(value);
        else
            s2.push(s2.top());
    }
    void pop() {
        s1.pop();
        s2.pop();
    }
    int top() {
        return s1.top();
    }
    int min() {
        return s2.top();
    }
};

<think>我们正在寻找或编写适用于BM8563实时时钟芯片的嵌入式系统驱动程序代码。BM8563是一个I2C接口的实时时钟芯片,常用于嵌入式系统中提供时间和日历功能。根据芯片手册,BM8563的主要特性包括:-低功耗-I2C总线接口(从地址通常为0xA2或0x51,具体取决于引脚配置)-可编程时钟输出、定时器、报警功能-时间寄存器(秒、分、时、日、星期、月、年)驱动代码通常需要实现以下功能:1.初始化I2C总线和BM85632.设置时间(写寄存器)3.读取时间(读寄存器)4.设置闹钟5.处理中断(如果使用闹钟中断)由于嵌入式系统平台多样(如STM32、ESP32、Linux嵌入式等),这里提供一个通用的C语言驱动框架,假设我们有一个I2C读写函数的基础。###BM8563驱动代码框架```c#include<stdint.h>//BM8563I2C地址(根据芯片的A0引脚连接,通常为0x51或0xA2)#defineBM8563_ADDR0x51//寄存器地址定义#defineBM8563_REG_CTRL10x00#defineBM8563_REG_CTRL20x01#defineBM8563_REG_SEC0x02#defineBM8563_REG_MIN0x03#defineBM8563_REG_HOUR0x04#defineBM8563_REG_DAY0x05#defineBM8563_REG_WEEK0x06#defineBM8563_REG_MONTH0x07#defineBM8563_REG_YEAR0x08#defineBM8563_REG_ALARM_MIN0x09#defineBM8563_REG_ALARM_HOUR0x0A#defineBM8563_REG_ALARM_DAY0x0B#defineBM8563_REG_ALARM_WEEK0x0C//时间结构体typedefstruct{uint8_tsec;uint8_tmin;uint8_thour;uint8_tday;uint8_tweek;uint8_tmonth;uint8_tyear;}bm8563_time_t;//假设我们有以下I2C读写函数(需要根据具体平台实现)voidi2c_write(uint8_tdev_addr,uint8_treg_addr,uint8_t*data,uint16_tlen);voidi2c_read(uint8_tdev_addr,uint8_treg_addr,uint8_t*data,uint16_tlen);//初始化BM8563voidbm8563_init(){//初始化控制寄存器1:开启时钟,关闭测试模式等uint8_tctrl1=0x00;//具体配置根据需求i2c_write(BM8563_ADDR,BM8563_REG_CTRL1,&ctrl1,1);}//设置时间voidbm8563_set_time(bm8563_time_t*time){uint8_tdata[7];//注意:时间寄存器从0x02开始,连续7个寄存器//数据格式:秒、分、时、日、星期、月、年data[0]=time->sec;//秒(0-59)data[1]=time->min;//分(0-59)data[2]=time->hour;//时(0-23)data[3]=time->day;//日(1-31)data[4]=time->week;//星期(0-6,0=星期日)data[5]=time->month;//月(1-12)data[6]=time->year;//年(0-99,代表2000-2099)i2c_write(BM8563_ADDR,BM8563_REG_SEC,data,7);}//读取时间voidbm8563_get_time(bm8563_time_t*time){uint8_tdata[7];i2c_read(BM8563_ADDR,BM8563_REG_SEC,data,7);//解析数据time->sec=data[0]&0x7F;//去掉VL标志位(如果VL=1,说明时钟可能停止)time->min=data[1]&0x7F;time->hour=data[2]&0x3F;//24小时制time->day=data[3]&0x3F;time->week=data[4]&0x07;time->month=data[5]&0x1F;time->year=data[6];}//设置闹钟(以分钟和小时为例,其他闹钟设置类似)voidbm8563_set_alarm(uint8_tmin,uint8_thour){//闹钟分钟寄存器(0x09)uint8_talarm_min=min&0x7F;//最高位为闹钟使能位,0表示使能uint8_talarm_hour=hour&0x3F;//最高位为闹钟使能位,0表示使能i2c_write(BM8563_ADDR,BM8563_REG_ALARM_MIN,&alarm_min,1);i2c_write(BM8563_ADDR,BM8563_REG_ALARM_HOUR,&alarm_hour,1);//如果需要设置其他闹钟(日或星期),类似操作//使能闹钟中断(控制寄存器2)uint8_tctrl2=0x02;//使能分钟闹钟中断(具体看手册)i2c_write(BM8563_ADDR,BM8563_REG_CTRL2,&ctrl2,1);}//其他功能:关闭闹钟、读取闹钟、设置定时器等可根据手册实现```###注意事项1.时间寄存器的格式:秒寄存器的最高位是VL(VoltageLow)标志,如果为1表示电源电压过低导致时间可能不准确。读取时间时通常需要屏蔽这一位。2.闹钟设置:每个闹钟寄存器(分钟、小时等)的最高位是闹钟使能位。设置为0时表示该闹钟条件使能,1则禁用。3.控制寄存器:需要根据具体功能配置(如时钟输出、定时器、中断等)。4.I2C读写函数需要根据具体的硬件平台(如STM32HAL库、ESP32IDF等)来实现。###参考-[BM8563datasheet](https://www.nxp.com/docs/en/data-sheet/PCF8563.pdf)(注意:BM8563与PCF8563兼容,通常可参考PCF8563手册)-具体实现时请以实际芯片手册为准[^1]§§相关问题§§1.如何读取BM8563的VL标志位以检测时钟是否有效?2.BM8563的I2C地址如何确定?3.如何配置BM8563的时钟输出功能?4.BM8563的定时器功能如何使用?</think>### BM8563实时时钟芯片驱动代码 BM8563是一款低功耗I2C实时时钟芯片,广泛应用于嵌入式系统。以下是适用于嵌入式平台的C语言驱动实现: ```c #include <stdint.h> /* I2C地址配置 (A0引脚决定) */ #define BM8563_ADDR 0x51 // A0接地时为0x51,接VCC时为0x53 /* 寄存器定义 */ #define REG_CTRL1 0x00 #define REG_CTRL2 0x01 #define REG_SEC 0x02 #define REG_MIN 0x03 #define REG_HOUR 0x04 #define REG_DAY 0x05 #define REG_WEEKDAY 0x06 #define REG_MONTH 0x07 #define REG_YEAR 0x08 #define REG_ALARM_MIN 0x09 #define REG_ALARM_HOUR 0x0A #define REG_ALARM_DAY 0x0B /* 时间结构体 */ typedef struct { uint8_t seconds; uint8_t minutes; uint8_t hours; uint8_t day; uint8_t weekday; uint8_t month; uint16_t year; // 完整年份 (如2023) } BM8563_Time; // I2C底层读写函数 (需平台实现) extern void I2C_Write(uint8_t dev_addr, uint8_t reg, uint8_t data); extern uint8_t I2C_Read(uint8_t dev_addr, uint8_t reg); /* 初始化RTC */ void BM8563_Init(void) { // 启动振荡器,关闭测试模式 I2C_Write(BM8563_ADDR, REG_CTRL1, 0x00); // 清除中断标志 I2C_Write(BM8563_ADDR, REG_CTRL2, 0x00); } /* 设置时间 */ void BM8563_SetTime(BM8563_Time *time) { // 转换十进制到BCD格式 uint8_t sec_bcd = ((time->seconds / 10) << 4) | (time->seconds % 10); uint8_t min_bcd = ((time->minutes / 10) << 4) | (time->minutes % 10); uint8_t hour_bcd = ((time->hours / 10) << 4) | (time->hours % 10); uint8_t day_bcd = ((time->day / 10) << 4) | (time->day % 10); uint8_t month_bcd = ((time->month / 10) << 4) | (time->month % 10); uint8_t year_bcd = ((time->year % 100) / 10) << 4 | (time->year % 10); // 写入寄存器 I2C_Write(BM8563_ADDR, REG_SEC, sec_bcd); I2C_Write(BM8563_ADDR, REG_MIN, min_bcd); I2C_Write(BM8563_ADDR, REG_HOUR, hour_bcd); I2C_Write(BM8563_ADDR, REG_DAY, day_bcd); I2C_Write(BM8563_ADDR, REG_MONTH, month_bcd); I2C_Write(BM8563_ADDR, REG_YEAR, year_bcd); } /* 读取时间 */ void BM8563_GetTime(BM8563_Time *time) { // 读取寄存器值 (BCD格式) uint8_t sec_bcd = I2C_Read(BM8563_ADDR, REG_SEC); uint8_t min_bcd = I2C_Read(BM8563_ADDR, REG_MIN); uint8_t hour_bcd = I2C_Read(BM8563_ADDR, REG_HOUR); uint8_t day_bcd = I2C_Read(BM8563_ADDR, REG_DAY); uint8_t month_bcd = I2C_Read(BM8563_ADDR, REG_MONTH); uint8_t year_bcd = I2C_Read(BM8563_ADDR, REG_YEAR); // BCD转十进制 time->seconds = (sec_bcd >> 4) * 10 + (sec_bcd & 0x0F); time->minutes = (min_bcd >> 4) * 10 + (min_bcd & 0x0F); time->hours = (hour_bcd >> 4) * 10 + (hour_bcd & 0x0F); time->day = (day_bcd >> 4) * 10 + (day_bcd & 0x0F); time->month = (month_bcd >> 4) * 10 + (month_bcd & 0x0F); time->year = 2000 + (year_bcd >> 4) * 10 + (year_bcd & 0x0F); } /* 设置闹钟 (分钟和小时) */ void BM8563_SetAlarm(uint8_t minute, uint8_t hour) { // 启用分钟闹钟 uint8_t min_reg = ((minute / 10) << 4) | (minute % 10); I2C_Write(BM8563_ADDR, REG_ALARM_MIN, min_reg); // 启用小时闹钟 uint8_t hour_reg = ((hour / 10) << 4) | (hour % 10); I2C_Write(BM8563_ADDR, REG_ALARM_HOUR, hour_reg); // 使能闹钟中断 I2C_Write(BM8563_ADDR, REG_CTRL2, 0x02); // AIE=1 } ``` ### 关键实现说明 1. **I2C接口**: - 需要实现底层`I2C_Write()`和`I2C_Read()`函数 - 地址选择:A0引脚接地时地址为$0x51$,接VCC时为$0x53$ 2. **时间格式转换**: - 使用BCD编码:$ \text{BCD} = (\text{十位数} \times 16) + \text{个位数} $ - 示例:$ 25 \text{分钟} \rightarrow 0x25 $ 3. **寄存器配置**: - 控制寄存器1 (0x00):控制芯片工作模式 - 控制寄存器2 (0x01):中断使能/标志位 - 时间寄存器 (0x02-0x08):保存时间数据 - 闹钟寄存器 (0x09-0x0B):设置闹钟时间 4. **低功耗设计**: ```c // 进入睡眠模式 void BM8563_Sleep(void) { I2C_Write(BM8563_ADDR, REG_CTRL1, 0x20); // STOP=1 } ``` ### 使用示例 ```c // 初始化 BM8563_Init(); // 设置时间 BM8563_Time new_time = { .seconds = 0, .minutes = 30, .hours = 14, .day = 15, .month = 6, .year = 2023 }; BM8563_SetTime(&new_time); // 设置14:30的闹钟 BM8563_SetAlarm(30, 14); // 读取时间 BM8563_Time current_time; BM8563_GetTime(&current_time); ``` ### 注意事项 1. **电源管理**: - 主电源断开时自动切换至备份电池 - 典型功耗:$0.25\mu A \text{ @ } 3V$ 2. **时钟校准**: - 可通过CLKOUT引脚输出校准信号 - 频率选择:$ f = \frac{32.768}{n} \text{kHz} $(n=32~8192) 3. **中断处理**: - 闹钟触发时TF位置1 - 需手动清除标志位: ```c I2C_Write(BM8563_ADDR, REG_CTRL2, 0x00); ``` 完整驱动需结合具体硬件平台的I2C控制器实现[^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值