基于正點原子阿波羅F429開發板的LWIP應用(6)——SNTP功能和lwiperf測速

說在開頭

? ? ? ? 正點原子F429開發板主芯片采用的是STM32F429IGT6,網絡PHY芯片采用的是LAN8720A(V1)和YT8512C(V2),采用的是RMII連接,PHY_ADDR為0;在代碼中將會對不同的芯片做出適配。

? ? ? ? CubeMX版本:6.6.1;

? ? ? ? F4芯片組Pack包版本:STM32Cube FW_F4 V1.27.0;

? ? ? ? 本實驗代碼以《基于正點原子阿波羅F429開發板的LWIP應用(3)——Netbiosns功能》一章的代碼作為基礎;

第一部分:SNTP功能實現

? ? ? ? SNTP的全稱是“簡單網絡時間協議”,是一種由NTP協議改編而來的網絡時間協議,主要用來同步因特網中的計算機時鐘。

? ? ? ? 在此實驗中開發板做SNTP客戶端,通過單播模式定期訪問SNTP服務器獲得準確的時間進而不斷校準單片機的RTC。

? ? ? ? 本次實驗的工作邏輯如下:首先完成RTC和LWIP的初始化,在初始化完成后開始啟動SNTP服務。在完成第一次SNTP授時后還是間隔1S從RTC讀取時間并從串口打印出來。

代碼修改(代碼注釋很詳細我就不再講解了)

1、?首先將"Middlewares/Third_Party/LwIP/src/apps/sntp/sntp.c"添加進工程“Application/User/LWIP/App”分組中;

2、在“LWIP/App”中新建“sntp_client.c?”、“sntp_client.h”2個文件并添加到工程“Application/User/LWIP/App”分組中,兩個文件分別添加以下代碼:

/******************sntp_client.c文件代碼**********************/
#include "sntp_client.h"#include "lwip/apps/sntp.h"
#include "time.h"
#include "rtc.h"/*1、中國國家授時中心NTP服務器“域名:ntp.ntsc.ac.cnIP:202.120.2.101 ---> 0X650278CA2、阿里云NTP服務器地址:域名:ntp.aliyun.comIP:110.75.8.1
*//*!
* @brief 設置 SNTP 的服務器地址,
* 		 加入多個 IP 以免某個 IP 獲取不了時間
*        執行條件:無
*
* @retval: 無
*/
void set_sntp_server_list(void)
{uint32_t server_list[SNTP_MAX_SERVERS] =	{  0X650278CA,  //國家授時中心0x0B6C1978,0x0B0C5CB6,0x58066BCB,0xC51F70CA,0x521D70CA,0x820176CA,0x510176CA,};ip_addr_t sntp_server;for(int i = 0; i < SNTP_MAX_SERVERS; i++){sntp_server.addr = server_list[i];sntp_setserver(i, &sntp_server);  // 國家授時中心}
}/*!
* @brief Lwip 的 SNTP 初始化封裝接口
*        執行條件:無
*
* @retval: 無
*/
void bsp_sntp_init(void)
{/*設置 SNTP 的獲取方式SNTP_OPMODE_POLL             //單播模式,客戶端主動發送獲取時間請求SNTP_OPMODE_LISTENONLY       //組播模式,等待授時服務器主動發送更新時間請求(請求發送時間不確定)*/sntp_setoperatingmode(SNTP_OPMODE_POLL);//SNTP 初始化sntp_init();//加入授時中心的IP信息set_sntp_server_list();/*通過修改sntp_opts.h中的SNTP_UPDATE_DELAY宏定義的值來修改同步時間的間隔默認1小時——3600000,目前修改成1分鐘:60000*/
}/*!
* @brief SNTP 獲取時間戳的處理函數
*        執行條件:無
*
* @param [in] : sntp 獲取的時間戳
*
* @retval: 無
*/
void sntp_set_time(uint32_t sntp_time)
{if(sntp_time == 0){printf("sntp_set_time: wrong!@@\n");return;}struct tm *time;sntp_time += (8 * 60 * 60); ///北京時間是東8區需偏移8小時time = localtime(&sntp_time);//RTC校準RTC_calibration((time->tm_year - 100), (time->tm_mon + 1), time->tm_mday, time->tm_hour, time->tm_min, time->tm_sec, time->tm_wday);if(RTC_calibrate_flag == 0) RTC_calibrate_flag =1;//	printf("sntp_set_time: 20%d-%02d-%02d %d:%d:%d, 星期%d", \
//		time->tm_year - 100,
//		time->tm_mon + 1,
//		time->tm_mday,
//		time->tm_hour,
//		time->tm_min,
//		time->tm_sec,
//		(time->tm_wday==0 ? 7 : time->tm_wday));//星期需要注意:0表示周天,1-6表示周一到周六}/******************sntp_client.h文件代碼**********************/
#ifndef __SNTP_CLIENT_H
#define __SNTP_CLIENT_H#include "main.h"void bsp_sntp_init(void);
void sntp_set_time(uint32_t sntp_time);
#endif

3、在“lwipopts.h”文件中添加以下內容:

#define LWIP_SNTP 											1
#define SNTP_MAX_SERVERS 								8
#include "sntp_client.h"
#define SNTP_SET_SYSTEM_TIME						sntp_set_time 	//定義 Lwip SNTP 的 處理函數
#define SNTP_UPDATE_DELAY								60000           //授時請求發送間隔:1分鐘

4、rtc.c文件添加以下內容:

/******************rtc.c文件添加代碼**********************/
void RTC_calibration(uint8_t year,uint8_t month,uint8_t day,uint8_t hour,uint8_t minute,uint8_t sec, uint8_t week)//RTC校準
{RTC_DateTypeDef sdatestructure;RTC_TimeTypeDef stimestructure;sdatestructure.Year    = year;//年 自2000開始,0x24表示24年sdatestructure.Month   = month;//月sdatestructure.Date    = day;//日sdatestructure.WeekDay = week;//星期if(HAL_RTC_SetDate(&hrtc,&sdatestructure,RTC_FORMAT_BIN) != HAL_OK){Error_Handler(); }stimestructure.Hours        = hour;stimestructure.Minutes      = minute;stimestructure.Seconds      = sec;stimestructure.TimeFormat = 0;stimestructure.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;stimestructure.StoreOperation = RTC_STOREOPERATION_RESET;if(HAL_RTC_SetTime(&hrtc,&stimestructure,RTC_FORMAT_BIN) != HAL_OK){Error_Handler();}
}void Get_time_info(uint8_t *info)
{RTC_DateTypeDef sdatestructureget;RTC_TimeTypeDef stimestructureget;uint8_t aShowTime[50] = {0};uint8_t aShowDate[50] = {0};/* Get the RTC current Time */HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN);/* Get the RTC current Date */HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN);/* Display time Format : hh:mm:ss */info[0]   =  sdatestructureget.Year;//2000開始info[1] 	=	 sdatestructureget.Month;//1至12info[2]   =  sdatestructureget.Date;//1至31info[3]  	=  stimestructureget.Hours; info[4] 	=	 stimestructureget.Minutes;info[5] 	=  stimestructureget.Seconds;info[6]   =	 sdatestructureget.WeekDay;	//0至6表示周日到周六sprintf((char*)aShowTime,"%02d:%02d:%02d",stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds);/* Display date Format : mm-dd-yy */sprintf((char*)aShowDate,"%02d-%02d-%02d,week=%d",sdatestructureget.Month, sdatestructureget.Date, 2000 + sdatestructureget.Year, sdatestructureget.WeekDay); printf("%s %s\n",aShowTime,aShowDate);
}/******************rtc.h文件添加代碼**********************/
void RTC_calibration(uint8_t year,uint8_t month,uint8_t day,uint8_t hour,uint8_t minute,uint8_t sec, uint8_t week);
void Get_time_info(uint8_t *info);

5、main.c文件增加以下內容:

/******************main.c開頭增加以下內容**********************/
uint8_t RTC_calibrate_flag = 0;//RTC校準標志位
uint8_t Internet_timeinfo[7] = { NULL };//網絡時間中的:年 月 日 時 分 秒 星期	/******************main函數while(1)前增加以下內容**********************/
bsp_sntp_init();//SNTP初始化/******************main.h增加以下內容**********************/
extern uint8_t RTC_calibrate_flag;//RTC校準標志位
extern uint8_t Internet_timeinfo[7];

6、stm32f4xx_it.c文件增加以下內容:

/******************stm32f4xx_it.c開頭增加以下內容**********************/
extern void Get_time_info(uint8_t *info);
uint16_t time_read_count = 0;/******************SysTick_Handler函數最后增加以下內容**********************/time_read_count++;if(time_read_count >= 1000){time_read_count = 0;if(RTC_calibrate_flag) Get_time_info(Internet_timeinfo);//從RTC獲取時間}

至此就修改完成了,編譯0警告0錯誤。燒錄進開發板可以看到DS0一直閃爍,同時串口間隔1S打印RTC的時間,打印時間和串口接收的時間戳相差不超過1S鐘,串口打印如下圖:

第二部分:lwiperf測速實現

1、?首先將"Middlewares/Third_Party/LwIP/src/apps/lwiperf/lwiperf.c"添加進工程“Application/User/LWIP/App”分組中;

2、在“LWIP/App”中新建“speed_test.c?”、“speed_test.h”2個文件并添加到工程“Application/User/LWIP/App”分組中,兩個文件分別添加以下代碼:

/******************speed_test.c內容如下**********************/
#include "speed_test.h"#include "lwip.h"#include "lwip/apps/lwiperf.h"uint8_t info_buf[30];/* 報告狀態 */
const char *report_type_str[] = 
{"TCP_DONE_SERVER",             /* LWIPERF_TCP_DONE_SERVER,*/"TCP_DONE_CLIENT",             /* LWIPERF_TCP_DONE_CLIENT,*/"TCP_ABORTED_LOCAL",           /* LWIPERF_TCP_ABORTED_LOCAL, */"TCP_ABORTED_LOCAL_DATAERROR", /* LWIPERF_TCP_ABORTED_LOCAL_DATAERROR, */"TCP_ABORTED_LOCAL_TXERROR",   /* LWIPERF_TCP_ABORTED_LOCAL_TXERROR, */"TCP_ABORTED_REMOTE",          /* LWIPERF_TCP_ABORTED_REMOTE, */"UDP_STARTED",                 /* LWIPERF_UDP_STARTED, */"UDP_DONE",                    /* LWIPERF_UDP_DONE, */"UDP_ABORTED_LOCAL",           /* LWIPERF_UDP_ABORTED_LOCAL, */"UDP_ABORTED_REMOTE"           /* LWIPERF_UDP_ABORTED_REMOTE */
};/* 當測試結束以后會調用此函數,此函數用來報告測試結果 */
/*** @brief       當測試結束以后會調用此函數,此函數用來報告測試結果* @param       無* @retval      無*/
static void lwiperf_report(void *arg,enum lwiperf_report_type report_type,const ip_addr_t *local_addr,u16_t local_port,const ip_addr_t *remote_addr,u16_t remote_port,u32_t bytes_transferred,u32_t ms_duration,u32_t bandwidth_kbitpsec)
{printf("-------------------------------------------------\r\n");if (((int)report_type < (sizeof(report_type_str)/sizeof(report_type_str[0]))) && local_addr && remote_addr){printf(" %s \r\n", report_type_str[report_type]);printf(" Local address : %u.%u.%u.%u ", ((u8_t *)local_addr)[0], ((u8_t *)local_addr)[1],((u8_t *)local_addr)[2], ((u8_t *)local_addr)[3]);printf(" Port %d \r\n", local_port);printf(" Remote address : %u.%u.%u.%u ", ((u8_t *)remote_addr)[0], ((u8_t *)remote_addr)[1],((u8_t *)remote_addr)[2], ((u8_t *)remote_addr)[3]);printf(" Port %d \r\n", remote_port);printf(" Bytes Transferred %d \r\n", (int)bytes_transferred);printf(" Duration (ms) %d \r\n", (int)ms_duration);printf(" Bandwidth (kbitpsec) %d \r\n", (int)bandwidth_kbitpsec);memset(info_buf,0,sizeof(info_buf));sprintf((char*)info_buf,"%u.%u.%u.%u",((u8_t *)local_addr)[0], ((u8_t *)local_addr)[1],((u8_t *)local_addr)[2], ((u8_t *)local_addr)[3]);           /* 顯示動態IP地址 */printf("%s\n",info_buf);memset(info_buf,0,sizeof(info_buf));sprintf((char*)info_buf,"%d",local_port);                           /* 顯示本地端口 */printf("%s\n",info_buf);memset(info_buf,0,sizeof(info_buf));sprintf((char*)info_buf,"%u.%u.%u.%u",((u8_t *)remote_addr)[0], ((u8_t *)remote_addr)[1],((u8_t *)remote_addr)[2], ((u8_t *)remote_addr)[3]);         /* 顯示遠程IP地址 */printf("%s\n",info_buf);memset(info_buf,0,sizeof(info_buf));sprintf((char*)info_buf,"%d",remote_port);              /* 顯示遠程IP端口 */printf("%s\n",info_buf);memset(info_buf,0,sizeof(info_buf));sprintf((char*)info_buf,"%d",(int)bytes_transferred/1024);   /* 轉換速度 */printf("%s\n",info_buf);memset(info_buf,0,sizeof(info_buf));sprintf((char*)info_buf,"%d",(int)ms_duration);         /* 持續時間 */printf("%s\n",info_buf);memset(info_buf,0,sizeof(info_buf));sprintf((char*)info_buf,"%d",(int)bandwidth_kbitpsec);  /* 帶寬 */printf("%s\n",info_buf);}else{printf(" IPERF Report error\r\n");}
}/*** @brief       lwip_demo實驗入口* @param       無* @retval      無*/
void speed_test(void)
{lwiperf_start_tcp_server_default(lwiperf_report,NULL);
}/******************speed_test.h內容如下**********************/
#ifndef __SPEED_TEST_H
#define __SPEED_TEST_H#include "main.h"void speed_test(void);#endif

3、main.c文件增加以下內容:

/******************main.c開頭增加以下內容**********************/
#include "speed_test.h"/******************main函數while(1)前增加以下內容**********************/
speed_test();

至此就修改完成了,編譯0警告0錯誤。燒錄進開發板串口打印模塊IP。

之后運行JPerf 網絡測速工具(會和實驗源碼一起分享),按下圖操作即可進行測速:

測速完成后串口也會打印相關信息:

看到這個結果大家肯定會納悶了,官方不是宣稱開發板帶的是百兆網絡嗎,為什么這里測出來才23M呢?那接下來就告訴大家該如何進行優化:在“lwipopts.h”文件中修改以下參數的值可以提升網速(沒有就新增):

/* 堆內存的大小,如果需要更大的堆內存,那么設置高一點 */
#define MEM_SIZE (30*1024)
/* MEMP_NUM_PBUF: 設置內存池的數量 */
#define MEMP_NUM_PBUF 25
/* MEMP_NUM_UDP_PCB: UDP 協議控制塊的數量. */
#define MEMP_NUM_UDP_PCB 4
/* MEMP_NUM_TCP_PCB: TCP 的數量. */
#define MEMP_NUM_TCP_PCB 8
/* MEMP_NUM_TCP_PCB_LISTEN: 監聽 TCP 的數量. */
#define MEMP_NUM_TCP_PCB_LISTEN 2
/* MEMP_NUM_TCP_SEG: 同時排隊的 TCP 的數量段. */
#define MEMP_NUM_TCP_SEG 150
/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
#define PBUF_POOL_SIZE          20
/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
#define PBUF_POOL_BUFSIZE       LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)//1536
/* TCP 接收窗口 */
#define TCP_WND 								(20*TCP_MSS)

編譯完成后再次測試,雖然沒有達到100M,但也可以穩定在86M,歡迎大家繼續優化并把優化好的參數分享在評論區:

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

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

相關文章

C:\Users\中文名修改為英文名

C:\Users\中文名修改為英文名 背景操作步驟 背景 買了臺新電腦&#xff0c;初始化好不知道啥操作把自己的登錄用戶名改成了中文&#xff0c;有些安裝的軟件看見有中文直接就水土不服了。 操作步驟 以下稱中文用戶名為張三。 正常登錄張三用戶 進入用戶管理頁面修改用戶名&a…

YOLOv12環境配置,手把手教你使用YOLOv12訓練自己的數據集和推理(附YOLOv12網絡結構圖),全文最詳細教程

文章目錄 前言一、YOLOv12代碼下載地址1.YOLOv12模型結構圖 二、YOLO環境配置教程1.創建虛擬環境2.激活虛擬環境3.查詢自己電腦可支持最高cuda版本是多少&#xff08;無顯卡的同學可以跳過這個步驟&#xff09;4.pytorch安裝5.驗證 PyTorch GPU 是否可用&#xff08;沒有顯卡的…

ES6(ES2015)特性全解析

ES6&#xff08;ECMAScript 2015&#xff09;是 JavaScript 語言發展史上的一個重要里程碑&#xff0c;它引入了許多新的語法特性和功能&#xff0c;提升了代碼的可讀性、可維護性和開發效率。 1. 塊級作用域變量&#xff1a;let 和 const ES6 引入了 let 和 const 關鍵字&am…

jvm 垃圾收集算法 詳解

垃圾收集算法 分代收集理論 垃圾收集器的理論基礎&#xff0c;它建立在兩個分代假說之上&#xff1a; 弱分代假說&#xff1a;絕大多數對象都是朝生夕滅的。強分代假說&#xff1a;熬過越多次垃圾收集過程的對象就越難以消亡。 這兩個分代假說共同奠定了多款常用的垃圾收集…

數字孿生+AR/VR的融合創新

目錄 引言&#xff1a;工業元宇宙的興起與技術基石數字孿生&#xff1a;工業元宇宙的數字底座 2.1 數字孿生的概念與關鍵要素 2.2 數字孿生在工業領域的應用 2.3 數字孿生的技術架構 (Mermaid Graph) AR/VR&#xff1a;工業元宇宙的沉浸式體驗層 3.1 AR/VR 的概念與技術原理…

圖解C#教程 第五版 第4章 類型、存儲和變量 筆記

第4章 類型、存儲和變量 筆記 4.1 C# 程序是一組類型聲明 C程序是一組函數和數據類型&#xff0c;C程序是一組函數和類&#xff0c; 而C#程序是一組類型聲明&#xff0c;具有如下特征&#xff1a; C# 程序或 DLL 的源代碼是一組類型聲明類型聲明中必須有一個包含 Main 方法…

SpringBoot整合SSM

1. SSM整合步驟 今天帶大家學習一下基于SpringBoot的SSM整合案例&#xff0c;話不多說&#xff0c;咱們開始&#xff0c;要實現SSM整合&#xff0c;有以下這么幾步 導入依賴創建yml配置文件dao層靜態頁面測試類進行測試 1.1 導入依賴 <?xml version"1.0" enco…

多面體模型-學習筆記2

1&#xff09; 多面體模型被應用于解決程序變換問題&#xff0c;并有效地推動了程 序自動并行化等技術的發展。與傳統的解決程序變換的方法相比&#xff0c;多面體模型 具有許多優勢[5]。多面體模型提供了一種強大的抽象&#xff0c;將每個語句的動態語句執 行實例視作一個多面…

基于django+vue的健身房管理系統-vue

開發語言&#xff1a;Python框架&#xff1a;djangoPython版本&#xff1a;python3.8數據庫&#xff1a;mysql 5.7數據庫工具&#xff1a;Navicat12開發軟件&#xff1a;PyCharm 系統展示 會員信息管理 員工信息管理 會員卡類型管理 健身項目管理 會員卡管理 摘要 健身房管理…

【Linux系統】Linux環境變量:系統配置的隱形指揮官

。# Linux系列 文章目錄 前言一、環境變量的概念二、常見的環境變量三、環境變量特點及其相關指令3.1 環境變量的全局性3.2、環境變量的生命周期 四、環境變量的組織方式五、C語言對環境變量的操作5.1 設置環境變量&#xff1a;setenv5.2 刪除環境變量:unsetenv5.3 遍歷所有環境…

Spring AI中使用ChatMemory實現會話記憶功能

文章目錄 1、需求2、ChatMemory中消息的存儲位置3、實現步驟1、引入依賴2、配置Spring AI3、配置chatmemory4、java層傳遞conversaionId 4、驗證5、完整代碼6、參考文檔 1、需求 我們知道大型語言模型 &#xff08;LLM&#xff09; 是無狀態的&#xff0c;這就意味著他們不會保…

Java 高級泛型實戰:8 個場景化編程技巧

文章目錄 一、通配符高級應用&#xff1a;靈活處理類型關系二、泛型方法與類型推斷三、泛型類的嵌套使用四、受限泛型與邊界條件五、泛型與反射結合六、泛型在函數式接口中的應用七、類型擦除與橋接方法八、自定義泛型注解總結 在Java編程中&#xff0c;泛型不僅是類型安全的保…

[藍橋杯 2024 國 B] 立定跳遠

問題描述 在運動會上&#xff0c;小明從數軸的原點開始向正方向立定跳遠。項目設置了 n 個檢查點 a1,a2,...,an且 ai≥ai?1>0。小明必須先后跳躍到每個檢查點上且只能跳躍到檢查點上。同時&#xff0c;小明可以自行再增加 m 個檢查點讓自己跳得更輕松。在運動會前&#xf…

2025年全國I卷數學壓軸題解答

第19題第3問: b b b 使得存在 t t t, 對于任意的 x x x, 5 cos ? x ? cos ? ( 5 x t ) < b 5\cos x-\cos(5xt)<b 5cosx?cos(5xt)<b, 求 b b b 的最小值. 解: b b b 的最小值 b m i n min ? t max ? x g ( x , t ) b_{min}\min_{t} \max_{x} g(x,t) bmi…

wpf在image控件上快速顯示內存圖像

wpf在image控件上快速顯示內存圖像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在尋找能夠快速在image控件刷新大圖像&#xff08;比如分辨率3000*3000的圖像&#xff09;的辦法&#xff0c;尤其是想把內存中的裸數據&#xff08;只有圖像的數據&#xff0c;不包…

解決網頁導出PDF部分內容被遮擋問題

問題描述 以學習通為例&#xff0c;在使用CtrlP打印頁面或截圖時&#xff0c;固定側邊欄會遮擋部分內容&#xff0c;影響完整內容的獲取。如下圖所示&#xff1a; 解決辦法 通過瀏覽器開發者工具臨時移除固定側邊欄&#xff0c;具體步驟如下&#xff1a; 在目標頁面右鍵點…

機器學習監督學習實戰六:五種算法對新聞組英文文檔進行文本分類(20類),詞頻統計和TF-IDF 轉換特征提取方法理論和對比解析

本文主要介紹了20 Newsgroups數據集及其在文本分類任務中的應用。20 Newsgroups數據集包含約20,000篇新聞組文檔&#xff0c;分為20個不同主題的新聞組&#xff0c;數據集被分為訓練集和測試集。在數據預處理階段&#xff0c;使用了CountVectorizer和TfidfVectorizer兩種方法將…

易學探索助手-個人記錄(十四)

項目背景 在大語言模型&#xff08;LLM&#xff09;完成指令微調&#xff08;SFT&#xff09;之后&#xff0c;雖然可以處理開放式問答任務&#xff0c;但在專業領域&#xff08;如《周易》&#xff09;仍面臨知識更新滯后、事實性薄弱等問題。為此&#xff0c;本文介紹如何通…

從“人找政策”到“政策找人”:智能退稅ERP數字化重構外貿生態

離境退稅新政核心內容與外貿企業影響 &#xff08;一&#xff09;政策核心變化解析 退稅商店網絡擴容 新政明確鼓勵在大型商圈、旅游景區、交通樞紐等境外旅客聚集地增設退稅商店&#xff0c;并放寬備案條件至納稅信用M級企業。以上海為例&#xff0c;靜安區計劃新增1000家退…

Pandas 可視化集成:數據科學家的高效繪圖指南

為什么選擇 Pandas 進行數據可視化&#xff1f; 在數據科學和分析領域&#xff0c;可視化是理解數據、發現模式和傳達見解的關鍵步驟。Python 生態系統提供了多種可視化工具&#xff0c;如 Matplotlib、Seaborn、Plotly 等&#xff0c;但 Pandas 內置的可視化功能因其與數據結…