实时时钟芯片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

相关文章

Go语言中使用JWT进行身份验证的几种方式

《Go语言中使用JWT进行身份验证的几种方式》本文主要介绍了Go语言中使用JWT进行身份验证的几种方式,包括dgrijalva/jwt-go、golang-jwt/jwt、lestrrat-go/jw... 目录简介1. github.com/dgrijalva/jwt-go安装:使用示例:解释:2. gi

Go 语言中的 Struct Tag 的用法详解

《Go语言中的StructTag的用法详解》在Go语言中,结构体字段标签(StructTag)是一种用于给字段添加元信息(metadata)的机制,常用于序列化(如JSON、XML)、ORM映... 目录一、结构体标签的基本语法二、json:"token"的具体含义三、常见的标签格式变体四、使用示例五、使用

Go语言使用slices包轻松实现排序功能

《Go语言使用slices包轻松实现排序功能》在Go语言开发中,对数据进行排序是常见的需求,Go1.18版本引入的slices包提供了简洁高效的排序解决方案,支持内置类型和用户自定义类型的排序操作,本... 目录一、内置类型排序:字符串与整数的应用1. 字符串切片排序2. 整数切片排序二、检查切片排序状态:

基于Go语言实现Base62编码的三种方式以及对比分析

《基于Go语言实现Base62编码的三种方式以及对比分析》Base62编码是一种在字符编码中使用62个字符的编码方式,在计算机科学中,,Go语言是一种静态类型、编译型语言,它由Google开发并开源,... 目录一、标准库现状与解决方案1. 标准库对比表2. 解决方案完整实现代码(含边界处理)二、关键实现细

如何合理管控Java语言的异常

《如何合理管控Java语言的异常》:本文主要介绍如何合理管控Java语言的异常问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍2、Thorwable类3、Error4、Exception类4.1、检查异常4.2、运行时异常5、处理方式5.1. 捕获异常

C语言中的常见进制转换详解(从二进制到十六进制)

《C语言中的常见进制转换详解(从二进制到十六进制)》进制转换是计算机编程中的一个常见任务,特别是在处理低级别的数据操作时,C语言作为一门底层编程语言,在进制转换方面提供了灵活的操作方式,今天,我们将深... 目录1、进制基础2、C语言中的进制转换2.1 从十进制转换为其他进制十进制转二进制十进制转八进制十进

$在R语言中的作用示例小结

《$在R语言中的作用示例小结》在R语言中,$是一个非常重要的操作符,主要用于访问对象的成员或组件,它的用途非常广泛,不仅限于数据框(dataframe),还可以用于列表(list)、环境(enviro... 目录1. 访问数据框(data frame)中的列2. 访问列表(list)中的元素3. 访问jav

使用Python实现实时金价监控并自动提醒功能

《使用Python实现实时金价监控并自动提醒功能》在日常投资中,很多朋友喜欢在一些平台买点黄金,低买高卖赚点小差价,但黄金价格实时波动频繁,总是盯着手机太累了,于是我用Python写了一个实时金价监控... 目录工具能干啥?手把手教你用1、先装好这些"食材"2、代码实现讲解1. 用户输入参数2. 设置无头浏

C语言中位操作的实际应用举例

《C语言中位操作的实际应用举例》:本文主要介绍C语言中位操作的实际应用,总结了位操作的使用场景,并指出了需要注意的问题,如可读性、平台依赖性和溢出风险,文中通过代码介绍的非常详细,需要的朋友可以参... 目录1. 嵌入式系统与硬件寄存器操作2. 网络协议解析3. 图像处理与颜色编码4. 高效处理布尔标志集合

Go语言开发实现查询IP信息的MCP服务器

《Go语言开发实现查询IP信息的MCP服务器》随着MCP的快速普及和广泛应用,MCP服务器也层出不穷,本文将详细介绍如何在Go语言中使用go-mcp库来开发一个查询IP信息的MCP... 目录前言mcp-ip-geo 服务器目录结构说明查询 IP 信息功能实现工具实现工具管理查询单个 IP 信息工具的实现服