实时时钟芯片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);//BCD
                reg |= 0x20;//bit5置1
            }else//AM
            {
                reg |= DecToBCD(hour);//BCD
                reg &= 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);//写入0x5A
        DS1302_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,输出的效果:
在这里插入图片描述
模式切换自如,可知各函数的功能正常。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/319134.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Aigtek超声功率放大器的选型技巧及参数指标有哪些

超声功率放大器是一种广泛应用于声学测量、医疗成像、声纳等领域的装置&#xff0c;其作用是将输入信号的功率放大到需要的水平。在选型超声功率放大器时&#xff0c;需要考虑一些关键的技巧和参数指标&#xff0c;以确保选择合适的设备来满足特定的需求。 首先&#xff0c;需要…

【java八股文】之Spring系列篇

1、你怎么理解Spring&#xff1f; Spring是个轻量级的框架&#xff0c;简化了应用的开发程序&#xff0c;提高开发人员的系统维护性&#xff0c;不过配置消息比较繁琐&#xff0c;所以后面才出选了SpringBoot的框架。 Spring的核心组件 &#xff1a; Spring Core 、 Spring Con…

【Python数据可视化】matplotlib之设置子图:绘制子图、子图共享x轴坐标

文章传送门 Python 数据可视化matplotlib之绘制常用图形&#xff1a;折线图、柱状图&#xff08;条形图&#xff09;、饼图和直方图matplotlib之设置坐标&#xff1a;添加坐标轴名字、设置坐标范围、设置主次刻度、坐标轴文字旋转并标出坐标值matplotlib之增加图形内容&#x…

CDSP和CISP证书,选择哪个?

&#x1f3af;CDSP和CISP是两种与信息安全领域相关的专业认证。它们有一些相似之处&#xff0c;但也存在一些显著的区别。本文将详细介绍CDSP认证和CISP认证的相同点和区别。 &#x1f451;CDSP和CISP的相同点&#xff1a; 1.行业认可&#xff1a;CDSP和CISP都是行业广泛认可的…

机器视觉系统选型-参数—景深

镜头在垂直方向上&#xff0c;能清晰成像的空间距离(清晰成像范围)&#xff0c;称为景深

强化学习应用(八):基于Q-learning算法的无人车配送路径规划(通过Python代码)

一、Q-learning算法介绍 Q-learning是一种强化学习算法&#xff0c;用于解决基于环境的决策问题。它通过学习一个Q-table来指导智能体在不同状态下采取最优动作。下面是Q-learning算法的基本步骤&#xff1a; 1. 定义环境&#xff1a;确定问题的状态和动作空间&#xff0c;并…

MyBatis第二课,灰度发布,@Results注解,使用xml书写mysql

目录 打印MyBatis的日志配置&#xff1a; 灰度发布:指发布环境&#xff0c;比如发布环境有200台机器&#xff0c;发布的时候是一批一批的机器的发布 2.删除与修改 使用Results注解&#xff0c;这样就和上面的别名一个意思&#xff0c;column是数据库的列 自动转驼峰&#…

H5网站封装成App的高效转换之旅

在移动互联网时代&#xff0c;App&#xff08;应用程序&#xff09;和H5&#xff08;HTML5网站&#xff09;是两种常见的移动解决方案。App通常提供更流畅的用户体验和更丰富的功能&#xff0c;而H5网站则以其开发成本低、更新快捷和无需安装等优势受到青睐。尽管如此&#xff…

Apache-Common-Pool2中对象池的使用方式

最近在工作中&#xff0c;对几个产品的技术落地进行梳理。这个过程中发现一些朋友对如何使用Apache的对象池存在一些误解。所以在写作“业务抽象”专题的空闲时间里&#xff0c;本人觉得有必要做一个关于对象池的知识点和坑点讲解。Apache Common-Pool2 组件最重要的功能&#…

【快速解决】保姆级Anaconda安装教程

目录 第一步 ​编辑第二步 ​编辑第三步 第四步 第五步 第六步 ​编辑 第七步 第八步 第九步 第一步 在anaconda清华大学开源软件镜像站下载anaconda。点击这里进入 我这里选的是windows-x86_64。 第二步 下载好以后进行安装 第三步 第四步 第五步 选择…

【操作系统】在阅读论文:OrcFS: Orchestrated file system for flash storage时需要补充的基础知

在阅读论文&#xff1a;OrcFS: Orchestrated file system for flash storage是需要补充的基础知识 这篇论文是为了解决软件层次之间的信息冗余问题 To minimize the disk traffic, the file system buffers the updates and then flushes them to the disk as a single unit, …

通达信波动指数指标公式,识别盘整还是趋势

波动指数(Choppiness Index)是由澳大利亚商品交易员E.W. Dreiss开发的技术指标&#xff0c;用来判断市场是盘整还是趋势。该指标属于非方向性指标&#xff0c;不用于判断市场方向&#xff0c;而仅用于识别市场趋势。 指标的取值范围为0到100&#xff0c;数值越高&#xff0c;表…

[足式机器人]Part2 Dr. CAN学习笔记-Advanced控制理论 Ch04-12+13 不变性原理+非线性系统稳定设计

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记-Advanced控制理论 Ch04-1213 不变性原理非线性系统稳定设计 1. Invariance Princilpe-LaSalle;s Theorem不变性原理2. Nonlinear Basic Feedback Stabilization 非线性系统稳定设计 1. Invarianc…

Visual Studio Code1.67版本已正式发布,新增Rust指南

Visual Studio Code1.67版本已正式发布&#xff0c;该版本包含大量增强生产力的更新项&#xff1a; 资源管理器文件嵌套 通过这次更新&#xff0c;用于浏览和管理文件和文件夹的Visual Studio Code的资源管理器工具现在支持基于名称嵌套相关文件。 资源管理器现在支持根据文…

python学习笔记10(选择结构2、循环结构1)

&#xff08;一&#xff09;选择结构2 1、if……else……语句 #&#xff08;1&#xff09;基本格式 numbereval(input("请输入您的6位中奖号码&#xff1a;")) if number123456:print("恭喜您&#xff0c;中奖了") else:print("未中奖")#&…

JVM内存结构 vs. Java对象模型 vs. Java内存模型

文章目录 0.三者的区别1.JVM内存结构2.Java对象模型3.Java内存模型&#xff08;JMM&#xff09;3.1 为什么需要JMM3.2 JMM是规范3.3 JMM是工具类和关键字的原理3.4 最重要的三点内容 0.三者的区别 JVM内存结构&#xff1a;和Java虚拟机的运行时区域有关。 Java对象模型&#…

负荷预测 | Python基于CEEMDAN-VMD-BiGRU的短期电力负荷时间序列预测

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 提出一种分解去噪、重构分解的 CEEMDAN-VMD-BiGRU组合预测方法&#xff1a; 1 采用CEEMDAN将原始电力负荷数据分解成一组比较稳定的子序列&#xff0c;联合 小波阈值法将含有噪声的高频分量去噪&#xff0c;保留含有信…

竞赛练一练 第29期:GESP和电子学会相关题目练习

CIE一级2021.09_无奈的Jaime 小宝在房间吵闹&#xff0c;妈妈让Jaime想办法安抚小宝。Jaime在房间来回走动思考方法。最后也没想出方法只能摊开双手说 “sorry&#xff01;”。 1. 准备工作 &#xff08;1&#xff09;添加背景&#xff1a;Bedroom 3&#xff1b; &#xff0…

[解决方案]运行时错误‘53’,文件未找到:MathPage.WLL

问题描述 mathtype使用报错,运行时错误‘53’,文件未找到:MathPage.WLL 解决方案 一、首先确定自己电脑的位数(这里默认大家的电脑都是64位) 二、右击MathType桌面图标,点击“打开文件所在位置”,然后找到MathPage.WLL文件所在位置 MathPage.WLL位置:D:\mathtype\…

Video接口介绍

屏库 https://m.panelook.cn/index_cn.php Open LDI, open lvds display interface OpenLDI and LVDS是兼容的&#xff0c; 是一种电平 https://www.ti2k.com/178597.html MIPI DSI/Camera crosLink FPD-LINK(Flat panel display link)是National(TI) LVDS技术&#xff0c; …