嵌入式進階——RTC時鐘

🎬 秋野醬:《個人主頁》
🔥 個人專欄:《Java專欄》《Python專欄》

??心若有所向往,何懼道阻且長

文章目錄

    • RTC時鐘
    • 原理圖
    • PCF8563寄存器
      • 控制與狀態寄存器
    • 設備地址
    • I2C環境初始化
    • RTC寄存器數據讀取
    • RTC寄存器數據寫入
    • RTC鬧鐘設置
    • RTC定時器設置
    • 驅動封裝
    • BCD(Binary-Coded Decimal)
    • 一些狀態分析
    • 有源晶振和無源晶振

RTC時鐘

RTC時鐘是一種實時時鐘芯片,通常與微控制器或計算機等設備配合使用,提供高精度的時間和日期信息,以便于設備進行時間相關的操作,如記錄數據、定時執行任務、鬧鐘提醒等。
RTC時鐘的應用場景非常廣泛,例如計算機主板、智能家居、物聯網設備、工業自動化等領域。在這些應用中,RTC時鐘可以提供高精度的時間戳、定時任務、日歷功能等,從而為系統提供更加可靠的時間基準。
除了時間和日期信息,一些RTC時鐘芯片還集成了溫度傳感器、電池備份等功能,以提供更加全面的服務。例如,在斷電情況下,RTC時鐘的備用電池可以維持時鐘的運行,以保證時間和日期信息的準確性。
以下是幾種常見的RTC時鐘芯片及其特點和應用場景:

  1. DS1302:DS1302是一款低功耗時鐘模塊,集成了時鐘、日歷和時鐘報警功能,能夠以BCD格式存儲時間和日期信息。它具有低功耗、簡單易用、成本低等特點,適用于需要長時間運行且功耗要求較低的應用場景。
  2. DS3231:DS3231是一款高精度的I2C RTC時鐘芯片,能夠以二進制格式存儲時間和日期信息,并具有時鐘報警、溫度補償等功能。它具有高精度、低功耗、高可靠性等特點,適用于對時鐘精度要求較高的應用場景,如電子鐘、精密計時器等。
  3. PCF8563:PCF8563是一款低功耗的I2C RTC時鐘芯片,能夠以BCD格式存儲時間和日期信息,并具有時鐘報警、時鐘輸出等功能。它具有低功耗、集成度高、工作穩定等特點,適用于需要長時間運行且功耗要求較低的應用場景。
  4. RV-4162-C7:RV-4162-C7是一款高精度的I2C RTC時鐘芯片,能夠以二進制格式存儲時間和日期信息,并具有時鐘輸出、時鐘同步、時鐘校準等功能。它具有高精度、低功耗、抗干擾能力強等特點,適用于對時鐘精度要求較高的應用場景,如高精度計時器、高精度工控系統等。
  5. MCP7940N:MCP7940N是一款低功耗的I2C RTC時鐘芯片,能夠以BCD格式存儲時間和日期信息,并具有時鐘輸出、時鐘同步、時鐘報警等功能。它具有低功耗、成本低等特點,適用于需要長時間運行且功耗要求較低的應用場景,如電子鐘、自動售貨機等。
    我們開發板中采用的是PCF8563

原理圖

在這里插入圖片描述

在這里插入圖片描述
原理圖外圍設計:

  1. 外部電池: 確保斷電后能正常工作
  2. 晶振:確保震蕩頻率準確。
  3. 肖特基二極管:防止電流倒灌。
    引腳說明:
  4. INT: 中斷引腳。當觸發到定時任務時,會觸發引腳高低電平變化。
  5. SCL和SDA:為I2C通訊的兩個引腳。用來保證MCU和RTC時鐘芯片間進行通訊的。

PCF8563寄存器

在這里插入圖片描述

控制與狀態寄存器

用來配置控制和狀態切換的寄存器。
在這里插入圖片描述
在這里插入圖片描述

設備地址

// 設備地址
#define		PCF8563_ADDR  0x51 << 1
// 存儲地址:時間的存儲地址開始位置
#define		PCF8563_REG_TD   0x02

I2C環境初始化

#include "Config.h"
#include "GPIO.h"
#include "Delay.h"#include "I2C.h"
#include "UART.h"
#include "NVIC.h"
#include "Switch.h"
/***1. 初始化IO口,將P32,P33初始化開漏OD模式
2. 初始化I2C協議 \ UARTEAXSFR();EA = 13. 通過I2C讀取RTC時鐘芯片數據
4. 通過I2C給RTC時鐘芯片寫數據
***/void GPIO_config() {P3_MODE_OUT_OD(GPIO_Pin_2 | GPIO_Pin_3);
}void UART_config(void) {// >>> 記得添加 NVIC.c, UART.c, UART_Isr.c <<<COMx_InitDefine		COMx_InitStructure;					//結構定義COMx_InitStructure.UART_Mode      = UART_8bit_BRTx;	//模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTxCOMx_InitStructure.UART_BRT_Use   = BRT_Timer1;			//選擇波特率發生器, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)COMx_InitStructure.UART_BaudRate  = 115200ul;			//波特率, 一般 110 ~ 115200COMx_InitStructure.UART_RxEnable  = ENABLE;				//接收允許,   ENABLE或DISABLECOMx_InitStructure.BaudRateDouble = DISABLE;			//波特率加倍, ENABLE或DISABLEUART_Configuration(UART1, &COMx_InitStructure);		//初始化串口1 UART1,UART2,UART3,UART4NVIC_UART1_Init(ENABLE,Priority_1);		//中斷使能, ENABLE/DISABLE; 優先級(低到高) Priority_0,Priority_1,Priority_2,Priority_3UART1_SW(UART1_SW_P30_P31);		// 引腳選擇, UART1_SW_P30_P31,UART1_SW_P36_P37,UART1_SW_P16_P17,UART1_SW_P43_P44
}
/****************  I2C初始化函數 *****************/
void	I2C_config(void)
{I2C_InitTypeDef		I2C_InitStructure;I2C_InitStructure.I2C_Mode      = I2C_Mode_Master;	//主從選擇   I2C_Mode_Master, I2C_Mode_SlaveI2C_InitStructure.I2C_Enable    = ENABLE;						//I2C功能使能,   ENABLE, DISABLEI2C_InitStructure.I2C_MS_WDTA   = DISABLE;					//主機使能自動發送,  ENABLE, DISABLEI2C_InitStructure.I2C_Speed     = 13;								//總線速度=Fosc/2/(Speed*2+4),      0~63// 400K = 24M / 2 / (Speed * 2 + 4):// 400  = 12000 / (Speed * 2 + 4)// Speed * 2   = 26I2C_Init(&I2C_InitStructure);NVIC_I2C_Init(I2C_Mode_Master,DISABLE,Priority_0);	//主從模式, I2C_Mode_Master, I2C_Mode_Slave; 中斷使能, ENABLE/DISABLE; 優先級(低到高) Priority_0,Priority_1,Priority_2,Priority_3I2C_SW(I2C_P33_P32);					//I2C_P14_P15,I2C_P24_P25,I2C_P33_P32
}#define NUMBER	7void main() {// 設備地址 read A3h and write A2hu8 dev_addr = 0x51 << 1; 	// (設備地址 << 1) | 0 = 寫地址. // 存儲地址u8 mem_addr = 0x02;// 用于接收從機傳來的數據u8 p[NUMBER];// 保存時間信息u8 second, minute, hour, day, week, month;u16 year;// 開啟擴展寄存器使能EAXSFR();GPIO_config();UART_config();I2C_config();EA = 1;//		4. 通過I2C給RTC時鐘芯片寫數據
//	void I2C_WriteNbyte(u8 dev_addr, u8 mem_addr, u8 *p, u8 number);printf("--------------------------------read\n");while(1) {//		3. 通過I2C讀取RTC時鐘芯片數據I2C_ReadNbyte(dev_addr, mem_addr, &p, NUMBER);printf("%d:%d:%d \n", (int)hour, (int)minute, (int)second);delay_ms(250);delay_ms(250);delay_ms(250);delay_ms(250);}
}

RTC寄存器數據讀取

I2C_ReadNbyte(PCF8563_ADDR, 0x02, dat, 7);
second = (dat[0] & 0x0F) + ((dat[0] >> 4) & 0x07) * 10;
minute = (dat[1] & 0x0F) + ((dat[1] >> 4) & 0x07) * 10;
hour = (dat[2] & 0x0F) + ((dat[2] >> 4) & 0x03) * 10;
day = (dat[3] & 0x0F) + ((dat[3] >> 4) & 0x03) * 10;
weekday = dat[4] & 0x07;
month = (dat[5] & 0x0F) + ((dat[5] >> 4) & 0x01) * 10;
year = ((dat[6] >> 4) & 0x0F) * 10 + (dat[6] & 0x0F);
year += ((dat[5] >> 7) & 0x01) * 100 + 1900;		

RTC寄存器數據寫入

year = 2023;
month = 12;
day = 31;
weekday = 0;
hour = 23;
minute = 59;
second = 50;
if(year >= 2100) {c = 1;
}
tmp[0] = ((second / 10) << 4) + (second % 10);
tmp[1] = ((minute / 10) << 4) + (minute % 10);
tmp[2] = ((hour / 10) << 4) + (hour % 10);
tmp[3] = ((day / 10) << 4) + (day % 10);
tmp[4] = weekday % 7;
tmp[5] = (c << 7) + ((month / 10) << 4) + (month % 10);
tmp[6] = (u8)(((year % 1000) / 10) << 4) + (u8)((year % 1000) % 10);
I2C_WriteNbyte(PCF8563_ADDR, 0x02, tmp, 7);	

RTC鬧鐘設置

通過配置寄存器來配置鬧鐘

u8 config;
// 先讀配置
I2C_ReadNbyte(PCF8563_ADDR, 0x01, &config, 1);
// 再去設置, 設置的時候別動別人的配置
config |= 0x02;
config &= ~0x08;//clear clock標記
I2C_WriteNbyte(PCF8563_ADDR, 0x01, &config, 1);
void ext_int3_call(void) {u8 tmp[7];u16 year;u8 month, day, weekday, hour, minute, second, c = 0;u8 config[1] = {0};printf("alarm \r\n");// 讀取狀態I2C_ReadNbyte(PCF8563_ADDR, 0x01, config, 1);printf("config: %d\r\n", (int)config[0]);// 判斷鬧鐘是否被激活if((config[0] >> 3) & 0x01 == 1) {//清除 alarm 標記config[0] &= ~0x08;I2C_WriteNbyte(RTC_ADDR, 0x01, config, 1);I2C_ReadNbyte(RTC_ADDR, 0x01, config, 1);printf("config: %d\r\n", (int)config[0]);}
}

RTC定時器設置

通過配置寄存器來配置定時器。
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

u8 config;
// 先讀配置
I2C_ReadNbyte(PCF8563_ADDR, 0x01, &config, 1);
// 再去設置, 設置的時候別動別人的配置
config |= 0x01;
config &= ~0x04;//clear timer標記
I2C_WriteNbyte(PCF8563_ADDR, 0x01, &config, 1);
u8 config[1] = {0};I2C_ReadNbyte(PCF8563_ADDR, 0x01, config, 1);
printf("config: %d\r\n", (int)config[0]);
if((config[0] >> 2) & 0x01 == 1) {printf("timer \r\n");config[0] &= ~0x04;I2C_WriteNbyte(PCF8563_ADDR, 0x01, config, 1);
}

驅動封裝

頭文件封裝

#ifndef __PCF8563_H__
#define __PCF8563_H__#include "config.h"
#include "I2C.h"#define PCF8563_SCL			P32
#define PCF8563_SDA			P33
#define PCF8563_INT			P37
#define PCF8563_ADDR		0x51 << 1
#define PCF8563_ADDR_W		0xA2
#define PCF8563_ADDR_R		0xA3#define PCF8563_SCL_INIT()	{P3M1 |= 0x04, P3M0 |= 0x04;}
#define PCF8563_SDA_INIT()	{P3M1 |= 0x08, P3M0 |= 0x08;}
#define PCF8563_INT_INIT()	{P3M1 &= ~0x80, P3M0 &= ~0x80;}//u16 year;
//u8 month, day, weekday, hour, minute, second
// 定義clock
typedef struct {u16 year;u8 month;u8 day;u8 weekday;u8 hour;u8 minute;u8 second;
} Clock_t;//定義alarm
typedef struct {u8 hour;u8 enableHour;u8 minute;u8 enableMinute;u8 day;u8 enableDay;u8 weekday;u8 enableWeekday;
} Alarm_t;// 國產芯片的HZ1有問題,不要使用,建議使用HZ64
enum TimerFreq{ HZ4096 = 0, HZ64 = 1, HZ1 = 2, HZ1_60 = 3};extern void PCF8563_on_alarm(void); 
extern void PCF8563_on_timer(void); void PCF8563_init(void);
void PCF8563_get_clock(Clock_t *c);
void PCF8563_set_clock(Clock_t c);void PCF8563_enable_alarm();
void PCF8563_set_alarm(Alarm_t a);
void PCF8563_disable_alarm();void PCF8563_enable_timer();
void PCF8563_set_timer(enum TimerFreq freq, u8 period);
void PCF8563_disable_timer();#endif

● 定義結構體Clock_t表示時間數據,通過這個結構體承載數據,方便讀取和設置。
● 定義結構體Alarm_t表示鬧鐘數據,通過這個結構體承載數據,方便讀取和設置。
● 定義枚舉TimerFreq限定計時器設置的范圍。

#include "PCF8563.h"
#include <stdio.h>void PCF8563_init(void) {PCF8563_SCL_INIT();PCF8563_SDA_INIT();PCF8563_INT_INIT();
}void PCF8563_get_clock(Clock_t *c) {u8 dat[7];I2C_ReadNbyte(PCF8563_ADDR, 0x02, dat, 7);c->second  = (dat[0] & 0x0F) + ((dat[0] >> 4) & 0x07) * 10;c->minute  = (dat[1] & 0x0F) + ((dat[1] >> 4) & 0x07) * 10;c->hour    = (dat[2] & 0x0F) + ((dat[2] >> 4) & 0x03) * 10;c->day 	   = (dat[3] & 0x0F) + ((dat[3] >> 4) & 0x03) * 10;c->weekday =  dat[4] & 0x07;c->month   = (dat[5] & 0x0F) + ((dat[5] >> 4) & 0x01) * 10;c->year    = ((dat[6] >> 4) & 0x0F) * 10 + (dat[6] & 0x0F);c->year   += ((dat[5] >> 7) & 0x01) * 100 + 1900;
}void PCF8563_set_clock(Clock_t clk) {u8 tmp[7];u8 c = 0;if(clk.year >= 2000) {c = 1;}tmp[0] = ((clk.second / 10) << 4) + (clk.second % 10);tmp[1] = ((clk.minute / 10) << 4) + (clk.minute % 10);tmp[2] = ((clk.hour   / 10) << 4) + (clk.hour   % 10);tmp[3] = ((clk.day    / 10) << 4) + (clk.day    % 10);tmp[4] = clk.weekday % 7;tmp[5] = (c << 7) + ((clk.month / 10) << 4) + (clk.month % 10);tmp[6] = (u8)(((clk.year % 1000) / 10) << 4) + (u8)((clk.year % 1000) % 10);I2C_WriteNbyte(PCF8563_ADDR, 0x02, tmp, 7);
}void PCF8563_enable_alarm() {u8 config;// 先讀配置I2C_ReadNbyte(PCF8563_ADDR, 0x01, &config, 1);// 再去設置, 設置的時候別動別人的配置config |= 0x02;config &= ~0x08;//clear clock標記I2C_WriteNbyte(PCF8563_ADDR, 0x01, &config, 1);
}void PCF8563_set_alarm(Alarm_t a) {u8 tmp[4];tmp[0] = ((a.minute / 10) << 4) + (a.minute % 10);if(a.enableMinute == 0) {tmp[0] += (1 << 7);}tmp[1] = ((a.hour / 10) << 4) + (a.hour % 10);if(a.enableHour == 0) {tmp[1] += (1 << 7);}tmp[2] = ((a.day / 10) << 4) + (a.day % 10);if(a.enableDay == 0) {tmp[2] += (1 << 7);}tmp[3] = a.weekday % 7;if(a.enableWeekday == 0) {tmp[3] += (1 << 7);}I2C_WriteNbyte(PCF8563_ADDR, 0x09, tmp, 4);
}void PCF8563_disable_alarm() {u8 config[1];// 先讀配置I2C_ReadNbyte(PCF8563_ADDR, 0x01, config, 1);// 再去設置, 設置的時候別動別人的配置config[0] &= ~0x02;config[0] &= ~0x08;//clear clock標記I2C_WriteNbyte(PCF8563_ADDR, 0x01, config, 1);
}void PCF8563_enable_timer() {u8 config;// 先讀配置I2C_ReadNbyte(PCF8563_ADDR, 0x01, &config, 1);// 再去設置, 設置的時候別動別人的配置config |= 0x01;config &= ~0x04;//clear timer標記I2C_WriteNbyte(PCF8563_ADDR, 0x01, &config, 1);
}void PCF8563_set_timer(enum TimerFreq freq, u8 period) {u8 config;config = freq + (1 << 7);//計數頻率 + timer enableI2C_WriteNbyte(PCF8563_ADDR, 0x0E, &config, 1);config = period; // config, periodI2C_WriteNbyte(PCF8563_ADDR, 0x0F, &config, 1);
}void PCF8563_disable_timer() {u8 config[1];// 先讀配置I2C_ReadNbyte(PCF8563_ADDR, 0x01, config, 1);// 再去設置, 設置的時候別動別人的配置config[0] &= ~0x01;config[0] &= ~0x04;//clear timer標記I2C_WriteNbyte(PCF8563_ADDR, 0x01, config, 1);
}void Ext_INT3 (void) interrupt INT3_VECTOR
{u8 config[1];// 先讀配置I2C_ReadNbyte(PCF8563_ADDR, 0x01, &config, 1);// 判斷鬧鐘是否被激活 Alarm Flag && AIEif((config[0] & 0x08) && (config[0] & 0x02)) {//清除 alarm 標記config[0] &= ~0x08;I2C_WriteNbyte(PCF8563_ADDR, 0x01, config, 1);PCF8563_on_alarm();}// 判斷計時器是否被激活 Timer Flag && TIEif((config[0] & 0x04) && (config[0] & 0x01)) {//清除 timer 標記config[0] &= ~0x04;I2C_WriteNbyte(PCF8563_ADDR, 0x01, config, 1);PCF8563_on_timer();}
}

● Ext_INT3中斷函數為當前STC8H平臺可用的。如果切換平臺需要進行對應的移植操作。

BCD(Binary-Coded Decimal)

BCD(Binary-Coded Decimal)是一種用二進制編碼表示十進制數字的格式。
在BCD格式中,每個十進制數位用4個二進制位來表示。BCD的目的是使得數字的編碼與顯示更加直觀和容易處理。在BCD格式中,每個十進制數位的取值范圍是0到9。
例如,數字5用BCD表示為0101,數字9用BCD表示為1001。這種表示方法使得每個十進制數位都獨立地編碼,方便在數字處理和顯示設備上進行操作。
10進制數轉BCD數:

// 十位取出左移4位 + 個位 (得到BCD數)
#define WRITE_BCD(val) 	((val / 10) << 4) + (val % 10)
// 將高4位乘以10 + 低四位 (得到10進制數)
#define READ_BCD(val) 	(val >> 4) * 10 + (val & 0x0F) 

一些狀態分析

PCF8563的規則:

  1. 通電后,就開始工作,內部可配置寄存器(時間,鬧鐘,定時器)
  2. 如果已經有電池,但是單片機斷電了,單片機重新通電后,單片機應該遵守PCF8563中已經配置的規則(時間,鬧鐘,定時器)

有源晶振和無源晶振

晶振可分為有源晶振與無源晶振。一般我們說的“晶振”指的是有源晶振,而無源晶振通常叫“晶體”,或者叫“諧振器”。兩者最大的區別是:
● 有源晶振自身即可起振
● 無源晶振則需要外加專門的時鐘電路才能起振
總體來看,有源晶振的精度、穩定度等方面均要好于無源晶振,尤其是在精密測量領域,大部分用的都是高檔的有源晶振,以方便把各種補償技術集成在一起,減少設計復雜性。
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/18231.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/18231.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/18231.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2024.5.28晚訓題解

提前預告&#xff0c;市賽初中組會考算法題&#xff0c;應該會有兩道模板題 比如DFS BFS 二分 簡單動態規劃&#xff0c;雖然我們沒學多久&#xff0c;但是模板題你還是要會寫的 A題 編輯距離 動態規劃 注意多組輸入 #include<iostream> using namespace std; int dp[1…

9、C#【進階】特性

特性 文章目錄 1、特性概念2、自定義特性 Attribute3、特性的使用4、限制自定義特性的使用范圍5、系統自帶特性1、過時特性2、調用者信息特性3、條件編譯特性4、外部dll包函數特性 1、特性概念 特性是一種允許我們向程序的程序集添加元數據的語言結構 它是用于保存程序機構信息…

【機器學習300問】103、簡單的經典卷積神經網絡結構設計成什么樣?以LeNet-5為例說明。

一個簡單的經典CNN網絡結構由&#xff1a;輸入層、卷積層、池化層、全連接層和輸出層&#xff0c;這五種神經網絡層結構組成。它最最經典的實例是LeNet-5&#xff0c;它最早被設計用于手寫數字識別任務&#xff0c;包含兩個卷積層、兩個池化層、幾個全連接層&#xff0c;以及最…

ansible批量漏洞升級openssh版本

1、ansible宿主機準備好環境&#xff0c;并寫好hosts文件 [rootoxidized ansible]# cat hosts [all] 10.10.200.33 10.10.200.34 10.10.200.35跑playbook之前記得提前發送秘鑰 ssh-copy-id 10.10.200.33/34/352、下載好安裝包&#xff0c;然后編寫yml [rootoxidized ansible]…

【實用的 IDEA 配置和操作技巧總結】

前置知識 IDEA的設置快捷鍵為ctrlalts鍵&#xff0c;后文介紹IDEA常見的配置就不再贅述這一點了。 基礎配置 取消默認打開上次項目 日常開發都會打開不同的項目&#xff0c;初次安裝IDEA之后&#xff0c;每次打開IDEA都會開啟上一次啟動的項目&#xff0c;所以我們需要進入設…

0基礎學習Mybatis系列數據庫操作框架——Mysql的Geometry數據處理之WKB方案

大綱 序列化反序列化完整TypeHandlerSQL XML完整XML Mapper測試代碼代碼 在《0基礎學習Mybatis系列數據庫操作框架——Mysql的Geometry數據處理之WKT方案》中&#xff0c;我們介紹WTK方案的優點&#xff0c;也感受到它的繁瑣和缺陷。比如&#xff1a; 需要借助ST_GeomFromText…

element+ 引入圖標報錯 Failed to resolve import “@element-plus/icons-vue“ from “

element 引入圖標報錯 Internal server error: Failed to resolve import “element-plus/icons-vue” from “src\components\TimeLine.vue”. Does the file exist? 原因&#xff1a;element-plus需要單獨引入 icons 文檔 pnpm install element-plus/icons-vue之后就可以…

350種類型、10W+量級的API,企業應該怎么管?

忽如一夜春風來&#xff0c;萬物皆可API。 在互聯網時代&#xff0c;API無處不在&#xff1a;企業對外開放的數據、服務和業務能力&#xff0c;以API的形式提供給合作方&#xff1b;企業內部應用與應用、App與App之間的通信&#xff0c;通過API進行&#xff1b;甚至應用內部的…

php 連接sqlserver步驟

1.首先要確定使用的是sqlserver的哪個版本&#xff0c;比如sqlserver2012 2.確定服務器是64位還是32位的 3.確認一下使用php的哪個版本&#xff0c;比如php7.1 SQL Server 的 Microsoft PHP 驅動程序 Microsoft Drivers for PHP 支持矩陣 - PHP drivers for SQL Server | Mi…

Flutter 中的 CupertinoTabView 小部件:全面指南

Flutter 中的 CupertinoTabView 小部件&#xff1a;全面指南 在 Flutter 中&#xff0c;CupertinoTabView 是 Cupertino 組件庫中的一個 widget&#xff0c;它用于創建 iOS 風格的標簽頁視圖。這個 widget 通常與 CupertinoTabScaffold 結合使用&#xff0c;提供了一個底部帶有…

怎么做好客戶信息管理?

根據Forrester的調查表示&#xff0c;客戶滿意度的影響可能會使某些行業的收入每年增加高達 10 億美元。而提升客戶滿意度的關鍵環節便是做好客戶信息管理。但企業在進行客戶信息管理中往往會遇到以下問題&#xff1a; 客戶信息亂&#xff1a;客戶信息存在各個 Excel表格、個人…

PMP報考條件怎么查詢?如何判定自己是否符合條件?

PMP報考條件在PMI官網上就可以查詢&#xff0c;PMP報考條件只需要符合項目管理培訓經歷和項目管理經驗兩個方面的要求即可&#xff0c;大家可以對照下方的規定判斷自己是否符合PMP報名條件 PMP報考條件 以下是PMI&#xff08;中國&#xff09;官網對于PMP報名條件的規定&…

優秀的數據分析師需要具備哪些?

在數據驅動的時代&#xff0c;數據分析師的角色越來越被重視。本文將探討優秀數據分析師必備的三大核心能力&#xff0c;并通過實際案例說明如何將這些能力轉化為業務價值&#xff0c;幫助你在職業道路上更進一步。 在數字化迅速發展的今天&#xff0c;數據分析師扮演著極其重要…

ubuntu strace命令

strace 是 Linux 系統中的一個調試工具&#xff0c;用于跟蹤并記錄系統調用&#xff08;system calls&#xff09;和信號&#xff08;signals&#xff09;。在 Ubuntu 中&#xff0c;strace 命令可以幫助開發者和系統管理員了解一個程序在運行時如何與操作系統內核進行交互&…

TypeScript常見面試題第八節

題目三十六:什么是參數解構? 一、講解視頻 TS面試題三十六:什么是參數解構? 二、題目解析 本題目考察 ts 中的解構,解構是一種特殊語法,可以將對象解構到一個或多個局部變量中,可展開操作符相反,展開是允許將一個數組展開為另一個數組,或將一個對象展開為另一個對象,…

vue+antd實踐:在輸入框光標處插入內容

今天來看一個很簡單的需求。 需求描述&#xff1a;在輸入框光標處&#xff0c;插入指定的內容。 效果如下&#xff1a; 實現思路&#xff1a;剛開始還在想怎么獲取光標的位置&#xff0c;但是發現所做的項目是基于vue3antd組件&#xff0c;那么不簡單了嘛&#xff0c;只要調…

JAVA自制小游戲之推箱子

給家里孩子實現益智游戲開發,教會他怎么使用編程。以下是一個簡單的推箱子游戲的Java實現,包含兩個關卡: 這個程序包含兩個關卡,每個關卡都是一個字符串表示的地圖。游戲會提示玩家輸入移動方向(WASD),然后根據輸入的方向移動玩家。如果玩家成功將所有的箱子推到目標位…

配置物聯網平臺 保姆級教程

一、云平臺配置&#xff08;我們這里使用阿里云&#xff09; 1、注冊和登錄 &#xff08;1&#xff09;找到云平臺官網&#xff0c;點擊右上角的注冊登錄&#xff0c;完成之后&#xff0c;進行實名認證&#xff0c;任選一種認證方式。 ??????? 2、實例的開通和創建 …

Scala環境的搭建

要搭建Scala&#xff0c;我們必須先下載java&#xff0c;由于我的電腦已經搭建好了環境&#xff0c;因此我這里用截圖來教大家搭建環境。 可以從網上搜索安裝包對其進行安裝 IntelliJ IDEA – 領先的 Java 和 Kotlin IDE 不建議下載最新版的&#xff0c;大家下載的版本可以下…

本殺小程序開發實戰手冊:從構思到上線

一、引言 隨著移動互聯網的快速發展&#xff0c;劇本殺作為一種新興的娛樂方式&#xff0c;受到了越來越多年輕人的喜愛。為了滿足市場需求&#xff0c;開發一款劇本殺小程序成為了許多創業者和開發者的選擇。本文將從構思、設計、開發到上線等方面&#xff0c;為您詳細解析劇…