基于RT-Thread驅動EEPROM_AD24C02

基于RT-Thread驅動EEPROM_AD24C02

  • 前言
  • 一、硬件設計
  • 二、軟件設計
  • 三、測試
    • 1、eeprom_test()測試
    • 2、基礎操作字節實驗
    • 3、多字節讀寫

前言

  1. 存儲容量2048位,內部組織256x8(2K),即256個字節的存儲單元;分為16頁,每頁16個字節
  2. 具有寫保護,擦寫壽命1,000,000次,數據保存期限100年
  3. 寫操作可按字節寫,也可按頁寫。
  4. I2C通信,器件從機寫地址0x50, 從機讀地址0x51
    在這里插入圖片描述

一、硬件設計

  1. WP引腳上拉,這個引腳是寫保護引腳,低電平解開保護,可以讀寫。高電平寫保護,
    在這里插入圖片描述
  2. 通過IIC即可與之通信。
    在這里插入圖片描述

二、軟件設計

  1. 創建工程
    在這里插入圖片描述

  2. 打開RT-Thread Settings
    在這里插入圖片描述

  3. 打開I2C設備驅動程序
    在這里插入圖片描述

  4. 使能I2C模塊
    在這里插入圖片描述

  5. 進入board.h打開I2C1的的宏定義,SCL跟SDA引腳的綁定需要根據你實際硬件連接去修改
    在這里插入圖片描述

  6. 主函數中這么寫
    在這里插入圖片描述

  7. 在applications文件夾下新建一個system_deal文件夾,然后再在system_deal文件夾下新建一個system_deal.csystem_deal.h文件,這個文件夾里我放一個給板子閃燈的程序,判斷板子是否跑起來
    在這里插入圖片描述

  8. system_deal.c文件里這么寫

/** Copyright (c) 2006-2021, RT-Thread Development Team** SPDX-License-Identifier: Apache-2.0** Change Logs:* Date           Author       Notes* 2025-04-18     Administrator       the first version*/#include "system_deal.h"/*********************************************************************************************************** Function name:       SystemLedRun** Descriptions:        System Led Run** input parameters:    NONE** output parameters:   NONE** Returned value:      NONE*********************************************************************************************************/
static void SystemLedRun(void)
{static uint8_t l_ucmode = 0;if (l_ucmode == 0){rt_pin_write(SYS_LED, PIN_HIGH);l_ucmode = 1;}else if (l_ucmode == 1){rt_pin_write(SYS_LED, PIN_LOW);l_ucmode = 0;}
}/*********************************************************************************************************** Function name:       SysDeal_thread** Descriptions:        SysDeal thread** input parameters:    parameter** output parameters:   NONE** Returned value:      NONE*********************************************************************************************************/
static void SysDeal_thread(void* parameter)
{// set pinrt_pin_mode(SYS_LED, PIN_MODE_OUTPUT);rt_pin_write(SYS_LED, PIN_HIGH);while(1){SystemLedRun();   //閃個燈rt_thread_mdelay(500);}}/*********************************************************************************************************** Function name:       SystemDealTaskInit** Descriptions:        System Task Init** input parameters:    NONE** output parameters:   NONE** Returned value:      NONE*********************************************************************************************************/
void SystemDealTaskInit(void)
{rt_thread_t SysDeal_tid;SysDeal_tid = rt_thread_create("sys_ctl", SysDeal_thread, RT_NULL, SYS_THREAD_STACK, SYS_THREAD_PRO, SYS_THREAD_TICK);if (SysDeal_tid != RT_NULL){rt_thread_startup(SysDeal_tid);}else{
#if DEBUG_LOG_ENABLErt_kprintf("/--> SysDeal create failed!\n");
#endif}
}/*********************************************************************************************************** Function name:       SystemTaskInit** Descriptions:        System Task Init** input parameters:    NONE** output parameters:   NONE** Returned value:      NONE*********************************************************************************************************/
static void SystemTaskInit(void)
{SystemDealTaskInit();  // 15}/*********************************************************************************************************** Function name:       SystemStartInit** Descriptions:        System Start Init** input parameters:    NONE** output parameters:   NONE** Returned value:      NONE*********************************************************************************************************/
void SystemStartInit(void)
{SystemTaskInit();
}
  1. system_deal.h文件里這么寫
/** Copyright (c) 2006-2021, RT-Thread Development Team** SPDX-License-Identifier: Apache-2.0** Change Logs:* Date           Author       Notes* 2025-04-18     Administrator       the first version*/
#ifndef APPLICATIONS_SYSTEM_DEAL_SYSTEM_DEAL_H_
#define APPLICATIONS_SYSTEM_DEAL_SYSTEM_DEAL_H_#include <rtdevice.h>
#include <rtthread.h>
#include "board.h"
#include "stdio.h"/* system io */
#define SYS_LED             GET_PIN(G, 13)/* thread information */
#define SYS_THREAD_STACK 1024
#define SYS_THREAD_PRO 15
#define SYS_THREAD_TICK 10extern void SystemStartInit(void);#endif /* APPLICATIONS_SYSTEM_DEAL_SYSTEM_DEAL_H_ */
  1. 在applications文件夾下新建drv_ad24c02文件夾,再在drv_ad24c02文件夾下新建drv_ad24c02.cdrv_ad24c02.h文件,這個文件夾里寫的是ad24c02的驅動
    在這里插入圖片描述
  2. drv_ad24c02.c文件里這么寫
    在這里插入圖片描述
/** Copyright (c) 2006-2021, RT-Thread Development Team** SPDX-License-Identifier: Apache-2.0** Change Logs:* Date           Author       Notes* 2025-04-18     Administrator       the first version*/
#include "drv_ad24c02.h"static struct rt_i2c_bus_device *i2c_bus = RT_NULL;
/*** eeprom write byte* @note This operation is write one bye to eeprom.** @param addr: the data address to write*        data: the data write to the address** @return >= 0: successful*           -1: error**/
rt_err_t eeprom_write_byte(uint8_t addr, uint8_t data)
{struct rt_i2c_msg msg;uint8_t buffer[2];buffer[0] = addr;buffer[1] = data;msg.addr  = EEPROM_I2C_ADDR;msg.flags = RT_I2C_WR;msg.buf = buffer;msg.len = 2;if(rt_i2c_transfer(i2c_bus, &msg, 1) != 1){rt_kprintf("eeprom i2c data write error.\n");return RT_ERROR;}rt_thread_mdelay(5);return RT_EOK;
}
/*** eeprom read byte* @note This operation is read one bye from eeprom.** @param addr: the data address to read** @return data: the data read from the address***/
uint8_t eeprom_read_byte(uint8_t addr)
{struct rt_i2c_msg msg;uint8_t buffer[2];uint8_t data;msg.addr = EEPROM_I2C_ADDR;msg.flags = RT_I2C_WR;buffer[0] = addr;msg.buf = buffer;msg.len = 1;rt_i2c_transfer(i2c_bus, &msg, 1);msg.flags = RT_I2C_RD;msg.buf = &data;rt_i2c_transfer(i2c_bus, &msg, 1);return data;
}
/*** eeprom check* @note This operation is check eeprom.** @param** @return >= 0: successful*           -1: error**/
static rt_err_t eeprom_check(uint8_t data)
{uint8_t temp;temp = eeprom_read_byte(EEPROM_SIZE - 1);if(temp != data){eeprom_write_byte(EEPROM_SIZE - 1, data);rt_thread_mdelay(5);temp = eeprom_read_byte(EEPROM_SIZE - 1);if(temp != data){
#if 1rt_kprintf("eeprom check data [0x%02X] not equal read data [0x%02X].\n", data, temp);
#endifreturn RT_ERROR;}rt_kprintf("eeprom check data [0x%02X] equal read data [0x%02X].\n", data, temp);}return RT_EOK;
}/*** eeprom init* @note This operation is eeprom init.** @param** @return >= 0: successful*           -1: error**/
rt_err_t eeprom_init(void)
{i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(EEPROM_I2C_BUS_NAME);if (i2c_bus == RT_NULL){rt_kprintf("eeprom i2c bus find error.\n");return RT_ERROR;}rt_pin_mode(EEPROM_WP_PIN, PIN_MODE_OUTPUT);rt_pin_write(EEPROM_WP_PIN, PIN_LOW);if(eeprom_check(EEPROM_CHECK_VALUE) != RT_EOK){rt_kprintf("eeprom check error.\n");return RT_ERROR;}else {rt_kprintf("eeprom check success.\n");}return RT_EOK;
}/*** eeprom test* @note This operation is test eeprom.** @param** @return >= 0: successful*           -1: error**/
static int eeprom_test(void)
{rt_uint8_t *rw_buf = RT_NULL;rw_buf = (rt_uint8_t *)rt_malloc(EEPROM_SIZE);    //分配一個256字節大小的空間eeprom_init();//erase eepromfor(rt_uint16_t addr = 0; addr < EEPROM_SIZE; addr++){if(RT_EOK == eeprom_write_byte(addr, 0)){rt_kprintf("address [0x%02X] erase OK.\n", addr);}else{rt_kprintf("address [0x%02X] erase failed.\n", addr);}}rt_kprintf("\n");rt_thread_mdelay(1000);//read eepromfor(rt_uint16_t addr = 0; addr < EEPROM_SIZE; addr++){rw_buf[addr] = eeprom_read_byte(addr);rt_kprintf("address [0x%02X] data is [%d].\n", addr, rw_buf[addr]);}rt_kprintf("\n");rt_thread_mdelay(1000);//write eepromfor(rt_uint16_t addr = 0; addr < EEPROM_SIZE; addr++){if(RT_EOK == eeprom_write_byte(addr, 0XFF)){rt_kprintf("address [0x%02X] write OK.\n", addr);}else{rt_kprintf("address [0x%02X] write failed.\n", addr);}}rt_kprintf("\n");rt_thread_mdelay(1000);//read eepromfor(rt_uint16_t addr = 0; addr < EEPROM_SIZE; addr++){rw_buf[addr] = eeprom_read_byte(addr);rt_kprintf("address [0x%02X] data is [%d].\n", addr, rw_buf[addr]);}//freert_free(rw_buf);return RT_EOK;
}
MSH_CMD_EXPORT(eeprom_test, eeprom test);static void basic_test(int argc, char** argv)
{if (argc != 3){rt_kprintf("Usage: basic_test [addr(0-255)] [data(0-255)]\n");return;}uint8_t addr = atoi(argv[1]);uint8_t wr_data = atoi(argv[2]);// 寫入并驗證eeprom_write_byte(addr, wr_data);uint8_t rd_data = eeprom_read_byte(addr);rt_kprintf("Immediate read: Addr 0x%02X => Wr:0x%02X Rd:0x%02X %s \r\n",addr, wr_data, rd_data, (wr_data == rd_data) ? "OK" : "FAIL");// 重啟后驗證rt_kprintf("Power cycle device and run again to check persistence");
}
MSH_CMD_EXPORT(basic_test, basic single-byte test);static void read_test(int argc, char** argv)
{if(argc != 2){rt_kprintf("Usage: read_test [addr(0-255)]\n");return;}uint8_t addr = atoi(argv[1]);uint8_t rd_data = eeprom_read_byte(addr);rt_kprintf("Immediate read: Addr %d => Rd:%d \r\n",addr, rd_data);}
MSH_CMD_EXPORT(read_test, read single-byte test);
  1. drv_ad24c02.h文件里這么寫
    在這里插入圖片描述
/** Copyright (c) 2006-2021, RT-Thread Development Team** SPDX-License-Identifier: Apache-2.0** Change Logs:* Date           Author       Notes* 2025-04-18     Administrator       the first version*/
#ifndef APPLICATIONS_DRV_AD24C02_DEAL_DRV_AD24C02_H_
#define APPLICATIONS_DRV_AD24C02_DEAL_DRV_AD24C02_H_#include <rtdevice.h>
#include <rtthread.h>
#include "board.h"
#include "stdio.h"
#include "stdlib.h"#define EEPROM_I2C_BUS_NAME         "i2c1"
#define EEPROM_I2C_ADDR             0x50        //0xA0 << 1
#define EEPROM_SIZE                  256         //Byte
#define EEPROM_CHECK_VALUE           0x5A/*********************************eeprom**************************************************/
#define EEPROM_WP_PIN               GET_PIN(B, 4)extern rt_err_t eeprom_init(void);   //ad24c02初始化
#endif /* APPLICATIONS_DRV_AD24C02_DEAL_DRV_AD24C02_H_ */
  1. 包含頭文件
    在這里插入圖片描述
  2. 找個位置進行ad24c02初始化
    在這里插入圖片描述
  3. 包含一下ad24c02驅動頭文件
    在這里插入圖片描述
  4. 編譯通過
    在這里插入圖片描述

三、測試

1、eeprom_test()測試

在MSH中使用命令行敲出eeprom_test進行測試。

  1. 先打help可以看到目前有什么指令,然后輸入eeprom_test進行測試,按TAB鍵可以自動補齊。
    在這里插入圖片描述

  2. 該測試函數首先會往eeprom的256個字節中寫0,一個字節一個字節的寫,每寫成功一個都會返回erase OK
    在這里插入圖片描述

  3. 寫完后,又會再讀出來,可以看到我們寫進去是0,那讀出來也是0
    在這里插入圖片描述

  4. 然后又往這256個字節里面寫,不過這回寫的是0XFF
    在這里插入圖片描述

  5. 然后再讀,0XFF對應十進制就是255。
    在這里插入圖片描述

  6. 檢查打印,看是否都寫成功,然后讀出來是否是前面一次是0,后面這次是255。如果符合預期,說明咱的eeprom驅動寫得沒問題了。

2、基礎操作字節實驗

步驟:

  1. 在指定地址寫入特定值
  2. 立即讀取驗證
  3. 斷電重啟再次讀取驗證持久性
    在MSH中敲出命令行,使用basic_test ,第一個參數寫地址,第二個參數寫數據
    在這里插入圖片描述
    可以看到有返回,當然我們寫進去的地址跟數據使用的是十進制,返回的使用的是十六進制,所以看起來不一樣,自己換算一下可以發現是一樣的。
    在這里插入圖片描述
    我們再用read_test去讀這個23地址,我們剛剛就在這個23地址中寫入了66
    在這里插入圖片描述
    可以發現讀出來的是66
    在這里插入圖片描述
    進行一次重啟(即掉電),可以發現讀出來的還是66,說明eeprom是起作用的
    在這里插入圖片描述

3、多字節讀寫

新增這兩個函數,這兩個函數可以進行多字節讀寫

int16_t eeprom_write_params(uint8_t *buf, int16_t start_index, int16_t buf_len)
{static int write_count = 0;rt_kprintf("[EEPROM] write count : %d, write len : %d\n", ++write_count, buf_len);if (start_index + buf_len >= EEPROM_SIZE){rt_kprintf("EEPROM write params assert\n");return RT_ERROR;}// Write data to EEPROMfor (int16_t i = 0; i < buf_len; i++){if (eeprom_write_byte(start_index + i, buf[i]) != RT_EOK){rt_kprintf("EEPROM write error at address %d\n", start_index + i);return RT_ERROR;}}// Verify the written datauint8_t tmp_mem[buf_len];for (int16_t i = 0; i < buf_len; i++){tmp_mem[i] = eeprom_read_byte(start_index + i);if (tmp_mem[i] != buf[i]){rt_kprintf("EEPROM write verify failed at address %d\n", start_index + i);return RT_ERROR;}else{rt_kprintf("EEPROM write verify success at address %d\n", start_index + i);}}return RT_EOK;
}//eeprom read
int16_t eeprom_read_params(uint8_t *buf, int16_t start_index, int16_t buf_len)
{if (start_index + buf_len >= EEPROM_SIZE || buf == RT_NULL){rt_kprintf("EEPROM read params assert\n");return RT_ERROR;}// Read data from EEPROMfor (int16_t i = 0; i < buf_len; i++){buf[i] = eeprom_read_byte(start_index + i);}return RT_EOK;
}

再新加這個測試函數,用于驗證

void eeprom_tes2(void)
{uint8_t write_buf[TEST_DATA_SIZE] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};uint8_t read_buf[TEST_DATA_SIZE] = {0};int16_t start_index = 0;// 初始化 EEPROMif (eeprom_init() != RT_EOK){rt_kprintf("EEPROM initialization failed\n");return;}// 向 EEPROM 寫入數據if (eeprom_write_params(write_buf, start_index, TEST_DATA_SIZE) != RT_EOK){rt_kprintf("EEPROM write params failed\n");return;}rt_thread_mdelay(100); // 適當延時,確保寫入完成// 從 EEPROM 讀取數據if (eeprom_read_params(read_buf, start_index, TEST_DATA_SIZE) != RT_EOK){rt_kprintf("EEPROM read params failed\n");return;}// 驗證寫入和讀取的數據是否一致for (int16_t i = 0; i < TEST_DATA_SIZE; i++){if (write_buf[i] != read_buf[i]){rt_kprintf("Data verification failed at index %d: write %d, read %d\n", i, write_buf[i], read_buf[i]);return;}}rt_kprintf("EEPROM read and write test passed\n");
}MSH_CMD_EXPORT(eeprom_tes2, EEPROM read and write test);

驗證結果
在這里插入圖片描述

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

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

相關文章

五、Hive表類型、分區及數據加載

在 Hive 中高效構建、管理和查詢數據倉庫&#xff0c;核心在于精準運用表類型&#xff08;內部/外部&#xff09;與分區策略&#xff08;靜態/動態/多重&#xff09;。這不僅決定數據的生命周期歸屬&#xff0c;更是優化海量數據查詢性能的關鍵手段。 一、表的身份權責&#x…

C++色彩博弈的史詩:紅黑樹

文章目錄 1.紅黑樹的概念2.紅黑樹的結構3.紅黑樹的插入4.紅黑樹的刪除5.紅黑樹與AVL樹的比較6.紅黑樹的驗證希望讀者們多多三連支持小編會繼續更新你們的鼓勵就是我前進的動力&#xff01; 紅黑樹是一種自平衡二叉查找樹&#xff0c;每個節點都帶有顏色屬性&#xff0c;顏色或為…

基于STM32、HAL庫的CH342F USB轉UART收發器 驅動程序設計

一、簡介: CH342F是一款USB轉串口芯片,由南京沁恒電子(WCH)生產,具有以下特點: 支持USB轉UART、IrDA紅外或SPI接口 內置時鐘,無需外部晶振 支持5V和3.3V電源電壓 最高支持3Mbps波特率 支持常用的MODEM聯絡信號 內置EEPROM,可配置設備VID/PID/序列號等 二、硬件接口: C…

項目功能-圖片清理(上)

一、圖片存儲介紹 在實際開發中&#xff0c;我們會有很多處理不同功能的服務器。例如&#xff1a; 應用服務器&#xff1a;負責部署我們的應用 數據庫服務器&#xff1a;運行我們的數據庫 文件服務器&#xff1a;負責存儲用戶上傳文件的服務器 分服務器處理的目的是讓服務…

創建三個網絡,分別使用RIP、OSPF、靜態,并每個網絡10個電腦。使用DHCP分配IP

DHCP 自動分配IP&#xff0c;集中管理&#xff0c;提高效率 在路由器中設置 Router>en Router#conf t Router(config)#ip dhcp pool ip30 //創建DHCP地址池 Router(dhcp-config)#network 192.168.30.0 255.255.255.0 // 配置網絡地址和子網掩碼 Router(dhcp-config)#defa…

如何使用 WMIC 命令在 Windows 11 或 10 上卸載軟件

如果您正在尋找一個命令提示符或 PowerShell 命令來卸載 Windows 應用程序,那么使用 wmic(Windows Management Instrumentation Command-line)是一種強大的技術,尤其是在處理難以卸載的程序或自動化卸載過程時。在本教程中,我們將學習如何使用 wmic 來卸載軟件。 先決條件…

FEKO許可證的安全與合規性

在電磁仿真領域&#xff0c;FEKO軟件因其出類拔萃的性能和廣泛的應用場景&#xff0c;贏得了全球用戶的廣泛贊譽。但在這背后&#xff0c;是什么讓FEKO在眾多競爭者中脫穎而出&#xff1f;答案是其許可證的安全與合規性。它們不僅為用戶提供了堅固的保障&#xff0c;更確保了用…

ESP32開發入門(九):HTTP服務器開發實踐

一、HTTP服務器基礎 1.1 什么是HTTP服務器&#xff1f; HTTP服務器是能夠處理HTTP請求并返回響應的網絡服務程序。在物聯網應用中&#xff0c;ESP32可以作為輕量級HTTP服務器&#xff0c;直接接收來自客戶端(如瀏覽器、手機APP)的請求。 1.2 ESP32作為HTTP服務器的特點 輕量…

《棒球百科》MLB棒球公益課·棒球1號位

MLB&#xff08;美國職業棒球大聯盟&#xff09;的棒球公益課通過推廣棒球運動、普及體育教育&#xff0c;對全球多個地區產生了多層次的影響&#xff1a; 1. 體育文化推廣 非傳統棒球地區的普及&#xff1a;在棒球基礎較弱的地區&#xff08;如中國、歐洲部分國家&#xff09…

Baumer工業相機堡盟工業相機的工業視覺是否可以在室外可以做視覺檢測項目

Baumer工業相機堡盟工業相機的工業視覺是否可以在室外可以做視覺檢測項目 Baumer工業相機?視覺檢測項目為什么偏愛“室內環境”&#xff1f;?工業視覺中為什么傾向于室內環境**保障人員與設備安全**&#xff1a;室內環境可以提供更好的安全保障&#xff0c;避免檢測設備和人員…

1. 使用 IntelliJ IDEA 創建 React 項目:創建 React 項目界面詳解;配置 Yarn 為包管理器

1. 使用 IntelliJ IDEA 創建 React 項目&#xff1a;創建 React 項目界面詳解&#xff1b;配置 Yarn 為包管理器 &#x1f9e9; 使用 IntelliJ IDEA 創建 React 項目&#xff08;附 Yarn 配置與 Vite 建議&#xff09;&#x1f4f7; 創建 React 項目界面詳解1?? Name&#xf…

C++GO語言微服務之用戶信息處理②

目錄 01 03-獲取用戶信息-上 02 04-獲取用戶信息-下 03 05-更新用戶名實現 01 06-中間件簡介和中間件類型 02 07-中間件測試和模型分析 03 08-中間件測試案例和小結 04 09-項目使用中間件 01 03-獲取用戶信息-上 ## Cookie操作 ### 設置Cookie go func (c *Context) …

QMK鍵盤固件開發全解析:QMK 固件開發的最新架構和規范(2025最新版)

QMK鍵盤固件開發全解析:QMK 固件開發的最新架構和規范(2025最新版) ?? 前言概述 QMK(Quantum Mechanical Keyboard)作為目前開源鍵盤固件領域的"扛把子",憑借其強大的功能和活躍的社區支持,已經成為眾多DIY鍵盤愛好者的首選開發框架。無論是入門級玩家還是資…

極狐GitLab 容器鏡像倉庫功能介紹

極狐GitLab 是 GitLab 在中國的發行版&#xff0c;關于中文參考文檔和資料有&#xff1a; 極狐GitLab 中文文檔極狐GitLab 中文論壇極狐GitLab 官網 極狐GitLab 容器鏡像庫 (BASIC ALL) 您可以使用集成的容器鏡像庫&#xff0c;來存儲每個極狐GitLab 項目的容器鏡像。 要為您…

Umi+React+Xrender+Hsf項目開發總結

一、菜單路由配置 1.umirc.ts 中的路由配置 .umirc.ts 文件是 UmiJS 框架中的一個配置文件&#xff0c;用于配置應用的全局設置&#xff0c;包括但不限于路由、插件、樣式等。 import { defineConfig } from umi; import config from ./def/config;export default defineCon…

【運維】基于Python打造分布式系統日志聚合與分析利器

《Python OpenCV從菜鳥到高手》帶你進入圖像處理與計算機視覺的大門! 解鎖Python編程的無限可能:《奇妙的Python》帶你漫游代碼世界 在分布式系統中,日志數據分散在多個節點,管理和分析變得復雜。本文詳細介紹如何基于Python開發一個日志聚合與分析工具,結合Logstash和F…

Python實戰:海量獲取京東商品信息

在數據驅動的商業時代&#xff0c;數據就是最寶貴的資源。對于電商從業者、市場分析師而言&#xff0c;從京東這類大型電商平臺獲取商品信息&#xff0c;能夠為市場調研、競品分析、銷售策略制定提供重要依據。今天&#xff0c;就來分享如何用Python實現京東商品信息的海量獲取…

聊一聊常見的超時問題:timeout

大家好&#xff0c;我是G探險者&#xff01; 在日常開發中&#xff0c;“超時&#xff08;Timeout&#xff09;”類錯誤是開發者們經常遇到的問題。無論是調用第三方服務、訪問數據庫&#xff0c;還是并發任務處理&#xff0c;都可能因超時而導致請求失敗或系統異常。 本文將系…

創建型模式:工廠方法(Factory Method)模式

一、簡介 工廠方法(Factory Method)模式是一種創建型設計模式,它定義了一個創建對象的接口,但讓子類決定實例化哪一個類。工廠方法使一個類的實例化延遲到其子類。在 C# 中,工廠方法模式提供了一種更靈活的對象創建方式,將對象的創建和使用分離,提高了代碼的可維護性和…

外網訪問內網海康威視監控視頻的方案:WebRTC + Coturn 搭建

外網訪問內網海康威視監控視頻的方案&#xff1a;WebRTC Coturn 需求背景 在倉庫中有海康威視的監控攝像頭&#xff0c;內網中是可以直接訪問到監控攝像的畫面&#xff0c;由于項目的需求&#xff0c;需要在外網中也能看到監控畫面。 實現這個功能的意義在于遠程操控設備的…