实时时钟芯片DS1302单片机C语言驱动程序

2024-01-14 12:12

本文主要是介绍实时时钟芯片DS1302单片机C语言驱动程序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

实时时钟RTC相关索引

1.单片机RTC及时钟芯片的时间到底从哪一年起始?
2.STM32F103单片机内部RTC实时时钟驱动程序
3.实时时钟芯片DS1302单片机C语言驱动程序

一、DS1302简介

DS1302 是 DALLAS(达拉斯)公司推出的一款涓流充电时钟芯片。
主要特点:
1.可计算秒、分、时、日、日期、星期、月、年的能力,并有闰年补偿功能;
2.内部含有31个字节静态RAM;
3.采用串行数据传送方式,3线接口;
4.与TTL兼容,Vcc=5V;
5.时钟或RAM数据的读/写有两种传送方式:单字节传送和多字节传送方式;
6.工作电压范围宽:2.0~5.5V;
7.功耗低,2.0V时工作电流小于300nA。
8.采用8脚DIP封装或SOIC封装。
9.可选工业级温度范围:-40℃~+85℃;

DS1302的引脚如下图示意,其中X1/X2接32.768KHz的晶振,SCLK为数据时钟引脚,I/O为数据收发引脚,CE为芯片的使能引脚,Vcc1为后备电池供电引脚,Vcc2为主电源供电引脚。
在这里插入图片描述

二、驱动程序

1.读写时序

在这里插入图片描述先看上图,无论是“读单字节”时序,还是“写单字节”时序,CE需要保持高电平,且在读写数据D0~D7之前,都要先写入一个字节的“命令字节”,即Command Byte(下面会讲到),SCLK上升沿的时候,写入数据,SCLK下降沿的时候读出数据,传输方式是LSB,低位在前,因此我们可以写出DS1302读或写单个字节的程序:

/******************************************************************************** 函数名:DS1302_WriteByte* 功  能:写1个字节* 参  数:data:写入的数据* 返回值:无* 说  明:SCLK上升沿时,写入数据,LSB
*******************************************************************************/
void DS1302_WriteByte(uint8_t data)
{uint8_t i;DS1302_IOModeOut();//IO为输出模式for (i = 0; i < 8; i++){		DS1302_SCLK_L();(data & 0x01) ? (DS1302_IOOutput_H()) : (DS1302_IOOutput_L());data >>= 1;//右移1位,准备发送下一位DS1302_SCLK_H();//上升沿发出}
}
/******************************************************************************** 函数名:DS1302_ReadByte* 功  能:读1个字节* 参  数:无* 返回值:data:写入的数据* 说  明:SCLK下降沿时,读取数据,LSB
*******************************************************************************/
uint8_t DS1302_ReadByte(void)
{uint8_t i;uint8_t data = 0;for (i = 0; i < 8; i++){DS1302_SCLK_H();DS1302_IOModeIn();//IO为输入模式data >>= 1;DS1302_SCLK_L();//下降沿data |= (DS1302_IORead() ? 0x80 : 0x00);}return data;
}

其中,引脚定义如下,可根据实际情况,改成自己使用的单片机引脚,笔者使用的是SM32F103C8T6:

#define DS1302_CE_H()					HAL_GPIO_WritePin(DS1302_CE_GPIO_Port, DS1302_CE_Pin, GPIO_PIN_SET)
#define DS1302_CE_L()					HAL_GPIO_WritePin(DS1302_CE_GPIO_Port, DS1302_CE_Pin, GPIO_PIN_RESET)#define DS1302_SCLK_H()					HAL_GPIO_WritePin(DS1302_SCLK_GPIO_Port, DS1302_SCLK_Pin, GPIO_PIN_SET)
#define DS1302_SCLK_L()					HAL_GPIO_WritePin(DS1302_SCLK_GPIO_Port, DS1302_SCLK_Pin, GPIO_PIN_RESET)#define DS1302_IOModeOut()				Pin_SetOutputMode(DS1302_IO_GPIO_Port, DS1302_IO_Pin, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_MEDIUM)
#define DS1302_IOModeIn()				Pin_SetInputMode(DS1302_IO_GPIO_Port, DS1302_IO_Pin, GPIO_MODE_INPUT, GPIO_NOPULL)
#define DS1302_IOOutput_H()				HAL_GPIO_WritePin(DS1302_IO_GPIO_Port, DS1302_IO_Pin, GPIO_PIN_SET)
#define DS1302_IOOutput_L()				HAL_GPIO_WritePin(DS1302_IO_GPIO_Port, DS1302_IO_Pin, GPIO_PIN_RESET)
#define DS1302_IORead()					HAL_GPIO_ReadPin(DS1302_IO_GPIO_Port, DS1302_IO_Pin)

2.命令字节

上面说到无论读还是写,都要先写入命令字节,接下来看看命令字节是什么:
在这里插入图片描述根据上图所示的描述,每次数据传输前都由命令字节开始,最高位bit7必须是1,否则DS1302会被禁用,停止工作;bit6是0的话,表示操作的是时钟/日历数据,是1的话表示操作的是RAM;bit1~bit5表示输入或输出的寄存器地址,bit0为0是写,为1是读操作,这些类似于24Cxx系列的EEPROM。传输的方式是LSB。

3.寄存器读写

3.1 基本寄存器读写

从下图寄存器地址定义表格中可看出,每个寄存器看上去有两个地址,读和写的地址不同,但实际上,结合上一小节“命令字节”每一位的描述,我们知道,命令字节的bit0位是读或写标志位,所以其实RTC的每个寄存器的地址是一样的,只是在读的时候,命令字节的bit0为1,写为0;而bit7必须为1,因此下图中RTC寄存器地址都是8或9开头的,0x81~0x8F、0x91的最高位是1,同理,CLOCK BURST、RAM及RAM BURST地址的最高位都是1;RTC和CLOCK BURST的地址,bit6都是0,表示时钟/日历的地址,而RAM、RAM BURST的地址,bit6都是1,表示RAM的地址;寄存器的真实地址,只有中间的A4/A3/A2/A1/A0位,例如,分钟寄存器的读地址,0x82=1000 0010b,对应A4/A3/A2/A1/A0为00001,因此各寄存器地址的宏定义如下:

#define WRITE					0x00//写命令
#define READ					0x01//读命令#define REG_SEC					0x80//0x80 & (0x00 << 1),秒
#define REG_MIN					0x82//0x80 & (0x01 << 1),分
#define REG_HOUR				0x84//0x80 & (0x02 << 1),时
#define REG_DATE				0x86//0x80 & (0x03 << 1),日
#define REG_MONTH				0x88//0x80 & (0x04 << 1),月
#define REG_DAY					0x8A//0x80 & (0x05 << 1),周几
#define REG_YEAR				0x8C//0x80 & (0x06 << 1),年
#define REG_WRITE_PROTECT		0x8E//0x80 & (0x07 << 1),写保护
#define REG_RAM_1               0xC0//0xC0 & (0x00 << 1),RAM的第一个字节

在这里插入图片描述另外,需要注意的是,RTC寄存器中,数据是8421格式的BCD码存储的,这种编码方式在RTC功能中很常用。RTC各寄存器种关于时间的读写驱动如下:

/******************************************************************************** 函数名:DS1302_WriteReg* 功  能:写寄存器* 参  数:reg:需要写入的寄存器地址;data:需要写入的数据* 返回值:无* 说  明:无
*******************************************************************************/
void DS1302_WriteReg(uint8_t reg, uint8_t data)
{DS1302_CE_L();DS1302_SCLK_L();DS1302_CE_H();//使能DS1302_WriteByte(reg | WRITE);DS1302_WriteByte(data);DS1302_CE_L();
}
/******************************************************************************** 函数名:DS1302_ReadReg* 功  能:读寄存器* 参  数:reg:需要写入的寄存器地址;			* 返回值:data:读取的数据* 说  明:无
*******************************************************************************/
uint8_t DS1302_ReadReg(uint8_t reg)
{uint8_t data = 0;DS1302_CE_L();DS1302_SCLK_L();DS1302_CE_H();//使能DS1302_WriteByte(reg | READ);	data = DS1302_ReadByte();DS1302_CE_L();DS1302_IOModeOut();DS1302_IOOutput_L();return data;
}
/******************************************************************************** 函数名:DS1302_GetYear* 功  能:获取年份* 参  数:无			* 返回值:年份,十进制* 说  明:将BCD码转为十进制
*******************************************************************************/
uint16_t DS1302_GetYear(void)
{uint16_t temp = 0;temp = DS1302_ReadReg(REG_YEAR);return BCDToDec(temp);
}
/******************************************************************************** 函数名:DS1302_GetWeekDay* 功  能:获取星期几* 参  数:无			* 返回值:星期几,十进制,1~7* 说  明:无
*******************************************************************************/
uint8_t DS1302_GetDay(void)
{uint8_t temp = 0;temp = DS1302_ReadReg(REG_DAY);return BCDToDec(temp & 0x07);
}
/******************************************************************************** 函数名:DS1302_GetMonth* 功  能:获取月份* 参  数:无			* 返回值:月份,十进制,1~12* 说  明:无
*******************************************************************************/
uint8_t DS1302_GetMonth(void)
{uint8_t temp = 0;temp = DS1302_ReadReg(REG_MONTH);return BCDToDec(temp & 0x1F);
}
/******************************************************************************** 函数名:DS1302_GetDate* 功  能:获取日期* 参  数:无			* 返回值:日,十进制,1~31* 说  明:无
*******************************************************************************/
uint8_t DS1302_GetDate(void)
{uint8_t temp = 0;temp = DS1302_ReadReg(REG_DATE);return BCDToDec(temp & 0x3F);
}
/******************************************************************************** 函数名:DS1302_GetHour* 功  能:获取小时* 参  数:无			* 返回值:小时,十进制,1~12或0~23* 说  明:返回的值需要结合小时模式及AM/PM位区分具体时间
*******************************************************************************/
uint8_t DS1302_GetHour(void)
{uint8_t temp = 0;temp = DS1302_ReadReg(REG_HOUR);if ((temp & 0x80) == 0x80)//12小时模式{return BCDToDec(temp & 0x1F);}else//24小时模式{return BCDToDec(temp & 0x3F);}
}
/******************************************************************************** 函数名:DS1302_GetMinute* 功  能:获取分钟* 参  数:无			* 返回值:分钟,十进制,0~59* 说  明:无
*******************************************************************************/
uint8_t DS1302_GetMinute(void)
{uint8_t temp = 0;temp = DS1302_ReadReg(REG_MIN);return BCDToDec(temp & 0x7F);
}
/******************************************************************************** 函数名:DS1302_GetSecond* 功  能:获取秒* 参  数:无			* 返回值:秒,十进制,0~59* 说  明:无
*******************************************************************************/
uint8_t DS1302_GetSecond(void)
{uint8_t temp = 0;temp = DS1302_ReadReg(REG_SEC);return BCDToDec(temp & 0x7F);
}
/******************************************************************************** 函数名:DS1302_SetYear* 功  能:写入年份* 参  数:year:年份,十进制,0~99			* 返回值:无* 说  明:将十进制转为BCD码
*******************************************************************************/
void DS1302_SetYear(uint16_t year)
{uint8_t temp = DecToBCD(year);DS1302_WriteReg(REG_YEAR, temp);	
}
/******************************************************************************** 函数名:DS1302_SetDay* 功  能:写入星期几* 参  数:day:星期几,1~7			* 返回值:无* 说  明:无
*******************************************************************************/
void DS1302_SetDay(uint8_t day)
{DS1302_WriteReg(REG_DAY, day & 0x07);	
}
/******************************************************************************** 函数名:DS1302_SetMonth* 功  能:写入月份* 参  数:month:月份,1~12			* 返回值:无* 说  明:转为BCD码
*******************************************************************************/
void DS1302_SetMonth(uint8_t month)
{uint8_t temp = DecToBCD(month);DS1302_WriteReg(REG_MONTH, temp & 0x1F);
}
/******************************************************************************** 函数名:DS1302_SetDate* 功  能:写入日* 参  数:date:日,1~31			* 返回值:无* 说  明:无
*******************************************************************************/
void DS1302_SetDate(uint8_t date)
{uint8_t temp = DecToBCD(date);DS1302_WriteReg(REG_DATE, temp & 0x3F);
}
/******************************************************************************** 函数名:DS1302_SetHour* 功  能:写入小时* 参  数:hour:小时,1~12或0~23		* 返回值:无* 说  明:无
*******************************************************************************/
void DS1302_SetHour(uint8_t hour)
{uint8_t temp = DecToBCD(hour);DS1302_WriteReg(REG_HOUR, temp & 0x3F);
}
/******************************************************************************** 函数名:DS1302_SetMinute* 功  能:写入分钟* 参  数:min:分钟,0~59		* 返回值:无* 说  明:无
*******************************************************************************/
void DS1302_SetMinute(uint8_t min)
{uint8_t temp = DecToBCD(min);DS1302_WriteReg(REG_MIN, temp & 0x7F);
}
/******************************************************************************** 函数名:DS1302_SetSecond* 功  能:写入秒* 参  数:sec:秒,0~59		* 返回值:无* 说  明:无
*******************************************************************************/
void DS1302_SetSecond(uint8_t sec)
{uint8_t temp = DecToBCD(sec);DS1302_WriteReg(REG_SEC, temp & 0x7F);
}

其中BCD码与十进制数的转换,可参考BCD码与十进制数转换C语言程序。

3.2 特殊功能读写

除了以上时钟、日历相关的寄存器外,还有一些特殊的功能,比如12/24小时模式,写保护功能等,接下来看这些功能的读写。

3.2.1 时钟停止标志位

先看80H的bit7位,这是秒寄存器的最高位,手册中的描述如下图:在这里插入图片描述当该位为1时,时钟晶振停止,为0时,时钟开始工作,而上电后该位的状态是未定义的,因此上电后需将该位清零,时钟才开始工作;如果使用DS1302,发现读取的时间一直是初始化的时间而不变,那么有可能是这一位没有清零导致的;

/******************************************************************************** 函数名:DS1302_ClearHaltFlag* 功  能:Halt标志置0* 参  数:无			* 返回值:无* 说  明:先读时间秒,再将CH位与秒组合为1字节,该位为0,时钟才开始工作
*******************************************************************************/
void DS1302_ClearHaltFlag(void)
{uint8_t temp = 0;temp = DS1302_GetSecond();temp &= 0x7F;DS1302_WriteReg(REG_SEC, temp);
}
3.2.2 12/24小时模式

小时寄存器84H的最高位是12/24小时模式选择位,功能描述如下:
在这里插入图片描述DS1302可运行于12或24小时模式下,小时寄存器的bit7位是12/24小时模式选择位,1为12小时模式,0为24小时模式;在12小时模式下,bit5表示AM/PM(上午/下午),1为下午;24小时模式下,bit5是20~23小时的第2个“10小时”;当12/24小时模式改变了,小时这个数据也必须重新初始化。
上面说,24小时模式下,bit5是20~23小时的第2个“10小时”,这一点需要好好理解一下,意思是,24小时模式下,由于数据是BCD码格式的,当小时是0-19时,这个时候的bit5是0,例如19时,bit5-bit0表示为01 1001,即8421码的19,这个时候用不到bit5;当小时大于19,为20-23时,该位就是1了,比如22,bit5-bit0表示为10 0010;该功能的读写程序如下:

/******************************************************************************** 函数名:DS1302_GetHourMode* 功  能:获取小时模式* 参  数:无			* 返回值:0,24小时模式,1,12小时模式* 说  明:bit7
*******************************************************************************/
uint8_t DS1302_GetHourMode(void)
{uint8_t temp = 0;temp = DS1302_ReadReg(REG_HOUR);   temp &= 0x80;return (temp >> 7);
}
/******************************************************************************** 函数名:DS1302_SetHourMode* 功  能:设置小时模式* 参  数:mode,0,24小时模式,1,12小时模式			* 返回值:无* 说  明:bit7,更改模式时,小时必须重新初始化,因此先读取原小时时间,再设置模式,再将小时写入寄存器
*******************************************************************************/
void DS1302_SetHourMode(uint8_t mode)
{uint8_t hour = 0;//原时间uint8_t temp = 0;//原模式uint8_t reg = 0;//写入寄存器的值temp = DS1302_GetHourMode();if (mode != temp)//修改模式{reg |= ((mode & 0x01) << 7);//模式在最高位hour = DS1302_ReadReg(REG_HOUR);//读取原寄存器的值,保存原时间        if (mode == 0)//改为24小时模式,之前是12小时模式,先判断AM/PM{if ((hour & 0x20) == 0x20)//bit5,1=PM{hour &= 0x1F;//提取0~4位的时间hour = BCDToDec(hour);//BCD转为十进制hour += 12;reg |= DecToBCD(hour);//BCD}else//AM{hour &= 0x1F;//提取0~4位的时间reg |= hour;}}else//改为12小时模式,之前是24小时模式{hour &= 0x3F;hour = BCDToDec(hour);//BCD转为十进制if (hour > 12)//PM{hour -= 12;reg |= DecToBCD(hour);//BCDreg |= 0x20;//bit5置1}else//AM{reg |= DecToBCD(hour);//BCDreg &= 0xDF;//bit5置0}}DS1302_WriteReg(REG_HOUR, reg);	}    
}
/******************************************************************************** 函数名:DS1302_SetAMPM* 功  能:设置AM/PM模式* 参  数:data,0为AM上午,1为PM下午		* 返回值:无* 说  明:小时寄存器bit5,须在12小时模式下使用
*******************************************************************************/
void DS1302_SetAMPM(uint8_t data)
{uint8_t temp = 0;temp = DS1302_ReadReg(REG_HOUR);//先把原数据读出(data == 0) ? (temp &= 0xDF) : (temp |= 0x20);DS1302_WriteReg(REG_HOUR, temp);
}
/******************************************************************************** 函数名:DS1302_GetAMPM* 功  能:读取AM/PM模式* 参  数:无		* 返回值:0为AM上午,1为PM下午* 说  明:小时寄存器bit5,须在12小时模式下使用
*******************************************************************************/
uint8_t DS1302_GetAMPM(void)
{uint8_t temp = 0;temp = DS1302_ReadReg(REG_HOUR);return ((temp & 0x20) >> 5);
}
3.3.3 写保护功能

写保护位的描述见下图:
在这里插入图片描述控制寄存器的bit7位是写保护位,bit0-bit6位强制为0,读出也是0;在对时钟或RAM寄存器进行任何写入操作前,bit7位必须置位0,如果该位为1,将无法对任何寄存器进行写入操作;该位上电初始化的状态未定义,因此在试图对器件进行写入操作前需将写保护位清零。该功能相关程序如下:

/******************************************************************************** 函数名:DS1302_WriteProtectEnable* 功  能:使能写保护* 参  数:无		* 返回值:无* 说  明:无
*******************************************************************************/
void DS1302_WriteProtectEnable(void)
{DS1302_WriteReg(REG_WRITE_PROTECT, 0x80);
}
/******************************************************************************** 函数名:DS1302_WriteProtectDisable* 功  能:禁止写保护* 参  数:无		* 返回值:无* 说  明:取消写保护功能
*******************************************************************************/
void DS1302_WriteProtectDisable(void)
{DS1302_WriteReg(REG_WRITE_PROTECT, 0x00);
}

Burst模式相关的寄存器,以及涓流充电寄存器在此不做讨论。

4.时钟初始化

首次上电时,单片机开始工作,读取RAM寄存器的值,与预设的值比较,如果值不正确,则是首次配置,初始化时间,并在RAM中写入预设的值;如果值正确,则直接读取时间寄存器的值,将时间输出即可;如果有电池供电,在主电源断开时,会继续计时,RAM寄存器中的值也会保存下来;

void DS1302_Init(void)
{uint8_t temp = 0;temp = DS1302_ReadReg(0xC0);//读RAM第一字节if (temp != 0x5A)//不正确,重新初始化{DS1302_WriteProtectDisable();//关闭写保护DS1302_ClearHaltFlag();//清除Halt标志DS1302_SetHourMode(0);//24小时模式DS1302_SetYear(24);//初始化时间24-01-11 22:30:00,Thursday,根据实际需要修改DS1302_SetDay(4);DS1302_SetMonth(1);DS1302_SetDate(11);DS1302_SetHour(22);DS1302_SetMinute(30);DS1302_SetSecond(0);DS1302_WriteReg(0xC0, 0x5A);//写入0x5ADS1302_WriteProtectEnable();//打开写保护   }
}

三、实验验证

在笔者的另一篇文章《单片机RTC及时钟芯片的时间到底从哪一年起始?》中,我们知道了DS1302复位时的初始时间是00年,一般我们在使用时,可以加上2000按照2000年处理,比如2024年,可以将年份设置为24,读出时加上2000变为2024年即可,这样可以使用到2099年;下面是上面DS1302_Init()函数初始化后,读取时间并通过串口打印输出的效果:
在这里插入图片描述
接下来测试12小时模式,设置时间时,通过DS1302_SetAMPM函数设置是上午还是下午,在输出的时间后面,通过函数DS1302_GetAMPM读取AM/PM标志,然后输出,看时间在AM/PM需要切换时是否正常:
在这里插入图片描述
还有需要验证是否有效的函数,就是12/24小时切换功能DS1302_SetHourMode函数,程序设置每隔3秒切换小时模式,24小时模式正常输出时间,12小时模式在后面输出AM/PM,输出的效果:
在这里插入图片描述
模式切换自如,可知各函数的功能正常。

这篇关于实时时钟芯片DS1302单片机C语言驱动程序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/605121

相关文章

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

基于51单片机的自动转向修复系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

MiniGPT-3D, 首个高效的3D点云大语言模型,仅需一张RTX3090显卡,训练一天时间,已开源

项目主页:https://tangyuan96.github.io/minigpt_3d_project_page/ 代码:https://github.com/TangYuan96/MiniGPT-3D 论文:https://arxiv.org/pdf/2405.01413 MiniGPT-3D在多个任务上取得了SoTA,被ACM MM2024接收,只拥有47.8M的可训练参数,在一张RTX

如何确定 Go 语言中 HTTP 连接池的最佳参数?

确定 Go 语言中 HTTP 连接池的最佳参数可以通过以下几种方式: 一、分析应用场景和需求 并发请求量: 确定应用程序在特定时间段内可能同时发起的 HTTP 请求数量。如果并发请求量很高,需要设置较大的连接池参数以满足需求。例如,对于一个高并发的 Web 服务,可能同时有数百个请求在处理,此时需要较大的连接池大小。可以通过压力测试工具模拟高并发场景,观察系统在不同并发请求下的性能表现,从而

C语言:柔性数组

数组定义 柔性数组 err int arr[0] = {0}; // ERROR 柔性数组 // 常见struct Test{int len;char arr[1024];} // 柔性数组struct Test{int len;char arr[0];}struct Test *t;t = malloc(sizeof(Test) + 11);strcpy(t->arr,

C语言指针入门 《C语言非常道》

C语言指针入门 《C语言非常道》 作为一个程序员,我接触 C 语言有十年了。有的朋友让我推荐 C 语言的参考书,我不敢乱推荐,尤其是国内作者写的书,往往七拼八凑,漏洞百出。 但是,李忠老师的《C语言非常道》值得一读。对了,李老师有个官网,网址是: 李忠老师官网 最棒的是,有配套的教学视频,可以试看。 试看点这里 接下来言归正传,讲解指针。以下内容很多都参考了李忠老师的《C语言非