8修改host_正點原子【STM32-F407探索者】第五十九章 USB 鼠標鍵盤(Host)實驗

1)資料下載:點擊資料即可下載

2)對正點原子Linux感興趣的同學可以加群討論:935446741

3)關注正點原子公眾號,獲取最新資料更新

1451daa71c1a28c4e968abe6ece7c8ed.png

上一章我們向大家介紹了如何利用 STM32F4 的 USB HOST 接口來驅動 U 盤,本章,我們

將利用 STM32F4 的 USB HOST 來驅動 USB 鼠標/鍵盤。本章分為如下幾個部分:

59.1 USB 鼠標鍵盤簡介

59.2 硬件設計

59.3 軟件設計

59.4 下載驗證

59.1 USB 鼠標鍵盤簡介

傳統的鼠標和鍵盤是采用 PS/2 接口和電腦通信的,但是現在 PS/2 接口在電腦上逐漸消失,

所以現在越來越多的鼠標鍵盤采用的是 USB 接口,而不是 PS/2 接口的了。

USB 鼠標鍵盤屬于 USB HID 設備。USB HID 即:Human Interface Device(人機交互設備)

的縮寫,鍵盤、鼠標與游戲桿等都屬于此類設備。不過 HID 設備并不一定要有人機接口,只要

符合 HID 類別規范的設備都是 HID 設備。關于 USB HID 的知識,我們這里就不詳細介紹了,

請大家自行百度學習。

本章,我們同上一章一樣,我們直接移植官方的 USB HID 例程,官方例程路徑:光盤→8,

STM32 參考資料→STM32 USB 學習資料→STM32_USB-Host-Device_Lib_V2.1.0→Project→

USB_Host_Examples→HID,該例程支持 USB 鼠標和鍵盤等 USB HID 設備,本章我們將移植這

個例程到探索者 STM32F407 開發板上。

59.2 硬件設計

本節實驗功能簡介:開機的時候先顯示一些提示信息,然后初始化 USB HOST,并不斷輪

詢。當檢測到 USB 鼠標/鍵盤的插入后,顯示設備類型,并顯示設備輸入數據,

如果是 USB 鼠標:將顯示鼠標移動的坐標(X,Y 坐標),滾輪滾動數值(Z 坐標)以及

按鍵(左中右)。

如果是 USB 鍵盤:將顯示鍵盤輸入的數字/字母等內容(不是所有按鍵都支持,部分按鍵

沒有做解碼支持,比如 F1~F12)。

最后,還是用 DS0 提示程序正在運行。

所要用到的硬件資源如下:

1) 指示燈 DS0

2) 串口

3) TFTLCD 模塊

4) USB HOST 接口

這幾個部分,在之前的實例中都已經介紹過了,我們在此就不多說了。這里再次提醒大家,

P11 的連接,要通過跳線帽連接 PA11 和 D-以及 PA12 和 D+。

59.3 軟件設計

本章,我們在第十八章實驗 (實驗 13 TFTLCD 顯示實驗 )的基礎上修改,先打開實驗

13 的工程,在 HARDWARE 文件夾所在文件夾下新建一個 USB 的文件夾,對照官方 HID 例子,

將相關文件拷貝到 USB 文件夾下。

然后,我們在工程里面添加 USB HID 相關代碼,最終得到如圖 59.3.1 所示的工程:

8f08deada110f62a75036e3e7dd33027.png
圖 59.3.1 USB 鼠標鍵盤工程截圖

可以看到,USB 部分代碼,同上一章的在結構上是一模一樣的,只是.c 文件稍微有些變化。

同樣,我們移植需要修改的代碼,就是 USB_APP 里面的這兩個.c 文件了。

其中 usb_bsp.c 的代碼,和之前的章節一模一樣,可以用上一章的代碼直接替換即可正常使

用。

usbh_usr.c 里面的代碼,則有所變化,重點代碼如下:

//下面兩個函數,為 ALIENTEK 添加,以防止 USB 死機

//USB 枚舉狀態死機檢測,防止 USB 枚舉失敗導致的死機

//phost:USB_HOST 結構體指針

//返回值:0,沒有死機

// 1,死機了,外部必須重新啟動 USB 連接.

u8 USBH_Check_EnumeDead(USBH_HOST *phost)

{

static u16 errcnt=0;

//這個狀態,如果持續存在,則說明 USB 死機了.

if(phost->gState==HOST_CTRL_XFER&&(phost->EnumState==ENUM_IDLE||

phost->EnumState==ENUM_GET_FULL_DEV_DESC))

{

errcnt++;

if(errcnt>2000)//死機了

{

errcnt=0;

RCC->AHB2RSTR|=1<<7; //USB OTG FS 復位

delay_ms(5);

RCC->AHB2RSTR&=~(1<<7); //復位結束

return 1;

}

}else errcnt=0;

return 0;

}

//USB HID 通信死機檢測,防止 USB 通信死機(暫時僅針對:DTERR,即 Data toggle error)

//pcore:USB_OTG_Core_dev_HANDLE 結構體指針

//phidm:HID_Machine_TypeDef 結構體指針

//返回值:0,沒有死機

// 1,死機了,外部必須重新啟動 USB 連接.

u8 USBH_Check_HIDCommDead(USB_OTG_CORE_HANDLE *pcore,

HID_Machine_TypeDef *phidm)

{

if(pcore->host.HC_Status[phidm->hc_num_in]==HC_DATATGLERR)

//檢測到 DTERR 錯誤,直接重啟 USB.

{

return 1;

}

return 0;

}

//

//USB 鍵盤鼠標數據處理

//鼠標初始化

void USR_MOUSE_Init(void)

{

USBH_Msg_Show(2);

//USB 鼠標

USB_FIRST_PLUGIN_FLAG=1;//標記第一次插入

}

//鍵盤初始化

void USR_KEYBRD_Init(void)

{

USBH_Msg_Show(1);

//USB 鍵盤

USB_FIRST_PLUGIN_FLAG=1;//標記第一次插入

}

//零時數組,用于存放鼠標坐標/鍵盤輸入內容(4.3 屏,最大可以輸入 2016 字節)

__align(4) u8 tbuf[2017];

//USB 鼠標數據處理

//data:USB 鼠標數據結構體指針

void USR_MOUSE_ProcessData(HID_MOUSE_Data_TypeDef *data)

{

static signed short x,y,z;

if(USB_FIRST_PLUGIN_FLAG)//第一次插入,將數據清零

{

USB_FIRST_PLUGIN_FLAG=0;

x=y=z=0;

}

x+=(signed char)data->x;

if(x>9999)x=9999;

if(x<-9999)x=-9999;

y+=(signed char)data->y;

if(y>9999)y=9999;

if(y<-9999)y=-9999;

z+=(signed char)data->z;

if(z>9999)z=9999;

if(z<-9999)z=-9999;

POINT_COLOR=BLUE;

sprintf((char*)tbuf,"BUTTON:");

if(data->button&0X01)strcat((char*)tbuf,"LEFT ");

if((data->button&0X03)==0X02)strcat((char*)tbuf,"RIGHT");

else if((data->button&0X03)==0X03)strcat((char*)tbuf,"+RIGHT");

if((data->button&0X07)==0X04)strcat((char*)tbuf,"MID ");

else if((data->button&0X07)>0X04)strcat((char*)tbuf,"+MID");

LCD_Fill(30+56,180,lcddev.width-1,180+16,WHITE);

LCD_ShowString(30,180,210,16,16,tbuf);

sprintf((char*)tbuf,"X POS:%05d",x);

LCD_ShowString(30,200,200,16,16,tbuf);

sprintf((char*)tbuf,"Y POS:%05d",y);

LCD_ShowString(30,220,200,16,16,tbuf);

sprintf((char*)tbuf,"Z POS:%05d",z);

LCD_ShowString(30,240,200,16,16,tbuf);

//printf("btn,X,Y,Z:0x%x,%d,%d,%drn",data->button,(signed char)data->x,

//(signed char)data->y,(signed char)data->z);

}

//USB 鍵盤數據處理

//data:USB 鼠標數據結構體指針

void USR_KEYBRD_ProcessData (uint8_t data)

{

static u16 pos;

static u16 endx,endy;

static u16 maxinputchar;

u8 buf[4];

if(USB_FIRST_PLUGIN_FLAG)//第一次插入,將數據清零

{

USB_FIRST_PLUGIN_FLAG=0;

endx=((lcddev.width-30)/8)*8+30;

//得到 endx 值

endy=((lcddev.height-220)/16)*16+220;

//得到 endy 值

maxinputchar=((lcddev.width-30)/8);

maxinputchar*=(lcddev.height-220)/16;//當前 LCD 最大可以顯示的字符數.

pos=0;

}

POINT_COLOR=BLUE;

sprintf((char*)buf,"%02X",data);

LCD_ShowString(30+56,180,200,16,16,buf);//顯示鍵值

if(data>=' '&&data<='~')

{

tbuf[pos++]=data;

tbuf[pos]=0;

//添加結束符.

if(pos>maxinputchar)pos=maxinputchar;//最大輸入這么多

}else if(data==0X0D) //退格鍵

{

if(pos)pos--;

tbuf[pos]=0;

//添加結束符.

}

if(pos<=maxinputchar) //沒有超過顯示區

{

LCD_Fill(30,220,endx,endy,WHITE);

LCD_ShowString(30,220,endx-30,endy-220,16,tbuf);

}

//printf("KEY Board Value:%02Xrn",data);

//printf("KEY Board Char:%crn",data);

}

ST 官方的 USB HID 例程,僅僅是能用,很多地方還要改善,比如識別率低,容易死機(枚

舉/通信都可能死機)等問題,這里:USBH_Check_EnumeDead 和 USBH_Check_HIDCommDead

這兩個函數,就是我們針對官方 HID 例程現有 bug 做出的改進處理,通過這兩個函數,可以檢

測枚舉/通信是否正常,當出現異常時,直接重啟 USB 內核,重新連接設備,這樣可以防止死

機造成的程序無響應情況。

另外,為了提高對鼠標鍵盤的識別率和兼容性,對 usbh_hid_core.c 里面的兩處代碼進行了

修改:

1,USBH_HID_ClassRequest 函數,修改代碼(351 行)為:

classReqStatus = USBH_Set_Idle (pdev, pphost, 100, 0);//這里 duration 官方設置的是 0,修改為

//100,提高兼容性

2,USBH_Set_Idle 函數,修改代碼(542 行)為:

phost->Control.setup.b.wLength.w = 100; //官方的這里設置的是 0,導致部分鼠標無法識別,

//這里修改為 100 以后,識別率明顯提高.

以上兩處地方,官方默認值都是設置的 0,我們修改為 100 后,可以明顯提高 USB 鼠標/

鍵盤的識別率,兼容性好很多。

還有,在 usbh_hid_keybd.h 里面,要修改鍵盤類型的定義,改為:

#define QWERTY_KEYBOARD

//通用鍵盤

//#define AZERTY_KEYBOARD

//法國版鍵盤

ST 官方例程,是使用的法國版鍵盤,一般我們國內用的是通用鍵盤,所以,需要換一個宏

定義(換成:QWERTY_KEYBOARD)。

最后,在 usbh_hid_mouse.c 里面,MOUSE_Decode 函數用于鼠標數據解析,但是 ST 官方

例程僅對 4 字節鼠標數據做了解析,而忽略了 5 字節/6 字節鼠標數據的處理,所以,需要修改

該函數為:

extern HID_Machine_TypeDef HID_Machine;

static void MOUSE_Decode(uint8_t *data)

{

if(HID_Machine.length==5||HID_Machine.length==6)//5/6 字節長度 USB 鼠標數據處理

{

HID_MOUSE_Data.button = data[0];

HID_MOUSE_Data.x = data[1];

HID_MOUSE_Data.y = data[3]<<4|data[2]>>4;

HID_MOUSE_Data.z = data[4];

}else if(HID_Machine.length==4) //4 字節長度的 USB 鼠標數據處理

{

HID_MOUSE_Data.button = data[0];

HID_MOUSE_Data.x = data[1];

HID_MOUSE_Data.y = data[2];

HID_MOUSE_Data.z = data[3];

}

USR_MOUSE_ProcessData(&HID_MOUSE_Data);

}

再回到 usbh_usr.c,USR_MOUSE_Init 和 USR_MOUSE_ProcessData 用于處理鼠標數據,這

兩個函數在 usbh_hid_mouse.c 里面被調用,USR_MOUSE_Init 在鼠標初始化的時候被調用,而

USR_MOUSE_ProcessData 函數,則在鼠標初始化成功,輪詢數據的時候調用,處理鼠標數據,

該函數將得到的鼠標數據顯示在 LCD 上面。

同樣,USR_KEYBRD_Init 和 USR_KEYBRD_ProcessData 用于處理鍵盤數據,這兩個函數

在 usbh_hid_keybd.c 里面被調用,USR_KEYBRD_Init 在鍵盤初始化的時候被調用,而

USR_KEYBRD_ProcessData 函數,則在鍵盤初始化成功,輪詢數據的時候調用,處理鍵盤數據,

該函數將鍵盤輸入的字符顯示在 LCD 上面。

其他代碼,我們就不再介紹了,請大家參考開發板光盤本例程源碼。

最后,來看看 main.c 里面的代碼,如下:

USBH_HOST USB_Host;

USB_OTG_CORE_HANDLE USB_OTG_Core_dev;

extern HID_Machine_TypeDef HID_Machine;

//USB 信息顯示

//msgx:0,USB 無連接

// 1,USB 鍵盤

// 2,USB 鼠標

// 3,不支持的 USB 設備

void USBH_Msg_Show(u8 msgx)

{

POINT_COLOR=RED;

switch(msgx)

{

case 0: //USB 無連接

LCD_ShowString(30,130,200,16,16,"USB Connecting...");

LCD_Fill(0,150,lcddev.width,lcddev.height,WHITE);

break;

case 1: //USB 鍵盤

LCD_ShowString(30,130,200,16,16,"USB Connected ");

LCD_ShowString(30,150,200,16,16,"USB KeyBoard");

LCD_ShowString(30,180,210,16,16,"KEYVAL:");

LCD_ShowString(30,200,210,16,16,"INPUT STRING:");

break;

case 2: //USB 鼠標

LCD_ShowString(30,130,200,16,16,"USB Connected ");

LCD_ShowString(30,150,200,16,16,"USB Mouse");

LCD_ShowString(30,180,210,16,16,"BUTTON:");

LCD_ShowString(30,200,210,16,16,"X POS:");

LCD_ShowString(30,220,210,16,16,"Y POS:");

LCD_ShowString(30,240,210,16,16,"Z POS:");

break;

case 3: //不支持的 USB 設備

LCD_ShowString(30,130,200,16,16,"USB Connected ");

LCD_ShowString(30,150,200,16,16,"Unknow Device");

break;

}

}

//HID 重新連接

void USBH_HID_Reconnect(void)

{

//關閉之前的連接

USBH_DeInit(&USB_OTG_Core_dev,&USB_Host); //復位 USB HOST

USB_OTG_StopHost(&USB_OTG_Core_dev);

//停止 USBhost

if(USB_Host.usr_cb->DeviceDisconnected)

//存在,才禁止

{

USB_Host.usr_cb->DeviceDisconnected(); //關閉 USB 連接

USBH_DeInit(&USB_OTG_Core_dev, &USB_Host);

USB_Host.usr_cb->DeInit();

USB_Host.class_cb->DeInit(&USB_OTG_Core_dev,&USB_Host.device_prop);

}

USB_OTG_DisableGlobalInt(&USB_OTG_Core_dev);//關閉所有中斷

//重新復位 USB

__HAL_RCC_USB_OTG_FS_FORCE_RESET();//USB OTG FS 復位

delay_ms(5);

__HAL_RCC_USB_OTG_FS_RELEASE_RESET();//復位結束

memset(&USB_OTG_Core_dev,0,sizeof(USB_OTG_CORE_HANDLE));

memset(&USB_Host,0,sizeof(USB_Host));

//重新連接 USB HID 設備

USBH_Init(&USB_OTG_Core_dev,USB_OTG_FS_CORE_ID,&USB_Host,&HID_cb,

&USR_Callbacks);

}

int main(void)

{

u32 t;

HAL_Init();

//初始化 HAL 庫

Stm32_Clock_Init(336,8,2,7);

//設置時鐘,168Mhz

delay_init(168);

//初始化延時函數

uart_init(115200);

//初始化 USART

usmart_dev.init(84);

//初始化 USMART

LED_Init();

//初始化 LED

KEY_Init();

//初始化 KEY

LCD_Init(); //初始化 LCD

SRAM_Init();

//初始化外部 SRAM

W25QXX_Init();

//初始化 W25Q128

POINT_COLOR=RED;

LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");

LCD_ShowString(30,70,200,16,16,"USB MOUSE/KEYBOARD TEST");

LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");

LCD_ShowString(30,110,200,16,16,"2017/5/16");

LCD_ShowString(30,130,200,16,16,"USB Connecting...");

//初始化 USB 主機

USBH_Init(&USB_OTG_Core_dev,USB_OTG_FS_CORE_ID,&USB_Host,&HID_cb,

&USR_Callbacks);

while(1)

{

USBH_Process(&USB_OTG_Core_dev, &USB_Host);

if(bDeviceState==1)//連接建立了

{

if(USBH_Check_HIDCommDead(&USB_OTG_Core_dev,&HID_Machine))

//檢測 USB HID 通信,是否還正常?

{

USBH_HID_Reconnect();//重連

}

}else

//連接未建立的時候,檢測

{

if(USBH_Check_EnumeDead(&USB_Host))

//檢測 USB HOST 枚舉是否死機了?死機了,則重新初始化

{

USBH_HID_Reconnect();//重連

}

}

t++;

if(t==200000)

{

LED0=!LED0;

t=0;

}

}

}

這里總共三個函數:USBH_Msg_Show 用于顯示一些提示信息,在 usbh_usr.c 里面被相關

函數調用。USBH_HID_Reconnect 則用于 USB HID 重新連接,當發現枚舉/通信死機的時候,

調用該函數實現 USB 復位重啟,以重新連接;最后,main 函數就比較簡單了,處理方式和上

一章幾乎一樣,只是多了一些通信死機處理。

軟件設計部分就為大家介紹到這里。

59.4 下載驗證

在代碼編譯成功之后,我們下載到探索者 STM32F4 開發板上,然后在 USB_HOST 端子插

入 USB 鼠標/鍵盤,注意:此時 USB SLAVE 口不要插 USB 線到電腦,否則會干擾!!

等 USB 鼠標/鍵盤成功識別后,便可以看到 LCD 顯示 USB Connected,并顯示設備類型:

USB Mouse 或者 USB KeyBoard,同時也會顯示輸入的數據,如圖 58.4.1 和圖 58.4.2 所示:

4b748a481ae1b5af10496f1fbaa42674.png
圖 59.4.1 USB 鼠標測試

f4d9b6c9cbdde5598afbf235f03a440b.png
圖 59.4.2 USB 鍵盤測試

其中,圖 59.4.1 是 USB 鼠標測試界面,圖 59.4.2 是 USB 鍵盤測試界面。

最后,特別提醒大家,由于例程的 HID 內核,只處理了第一個接口描述符,所以對于 USB

符合設備,只能識別第一個描述符所代表的設備。體現到實際使用中,就是:USB 無線鼠標,

一般是無法使用(被識別為鍵盤),而 USB 無線鍵盤,可以使用,因為鍵盤在第一個描述符,

鼠標在第二個描述符。

如果想支持 USB 無線鼠標,可以通過修改 usbh_hid_core.c 里面的 USBH_HID_InterfaceInit

函數來支持。

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

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

相關文章

CF815C Karen and Supermarket [樹形DP]

題目傳送門 Karen and Supermarket On the way home, Karen decided to stop by the supermarket to buy some groceries. She needs to buy a lot of goods, but since she is a student her budget is still quite limited. In fact, she can only spend up to b dollars. Th…

linux命令積累之egrep命令

學搭建Nginx環境&#xff0c;必須要配置的Nginx.conf文件中&#xff0c;如下&#xff1a;#user nobody;worker_processes 1;#error_log logs/error.log;#error_log logs/error.log notice;#error_log logs/error.log info;#pid logs/nginx.pid;events { worke…

Sublime Text 3 安裝及插件推薦

本篇介紹跨平臺編輯器Sublime Text 3的安裝和其插件推薦。 目錄&#xff1a; 1.介紹 2.下載安裝 3.插件 4.參考資料 1.介紹 Sublime Text具有漂亮的用戶界面和強大的功能&#xff0c;例如代碼縮略圖&#xff0c;Python的插件&#xff0c;代碼段等。還可自定義鍵綁定&#xff0c…

6工程文件夾作用_data_dragon數據工程小工具收集

最近在GitHub上創建了一個新工程&#xff0c;收集個人在數據工程工作的小工具集合&#xff0c;命名為data_dragon (數據一條龍)。取這個名字的是希望這些腳本或代碼能夠復用&#xff0c;端到端地減少臨時數據處理的時間。最近因為工作上的一些變化&#xff0c;寫作節奏有點被打…

暑假第十七測

題解&#xff1a; 第一題 #include<bits/stdc.h> using namespace std; #define ll long long const int M 1e5 10; ll a[M], b[M], ans; priority_queue <ll, vector<ll> , greater<ll> > Q; int main(){freopen("buy.in","r",…

Uva 11354 LCA 倍增祖先

題目鏈接&#xff1a;https://vjudge.net/contest/144221#problem/B 題意&#xff1a;找一條從 s 到 t 的路&#xff0c;使得瓶頸路最小。 點的數目是10^4&#xff0c;如果向之前的方案求 maxcost數組&#xff0c;O(n*n)時間是過不了的&#xff0c;這個時候&#xff0c;用到了…

Nginx搭建flv視頻點播服務器

Nginx搭建flv視頻點播服務器前一段時間使用Nginx搭建的多媒體服務器只能在緩沖過的時間區域內拖放, 而不能拖放到未緩沖的地方. 這就帶來了一個問題: 如果視頻限速的速率很小, 那么客戶端觀看視頻時肯定不流暢, 而且用戶不能向前拖放, 用戶體驗很不好. 如果視頻限速的速率很大或…

編碼拾遺

1 #!/usr/bin/env python32 #-*- coding:utf-8 -*-3 4 Administrator 5 2018/8/16 6 7 8 # fopen("demo","r",encoding"utf8")9 # dataf.read() 10 # print(data) 11 # f.close() 12 13 14 # print("沈哲子") 15 16 s"中國&qu…

Xcode:Foundation框架找不到,或者是自動提示出現問題

問題描述&#xff1a;Foundation框架找不到&#xff0c;或者是自動提示出現問題 之前的操作&#xff1a;手賤&#xff0c;不少心把編譯器里面的源碼改了處理辦法&#xff1a;清理緩存緩存位置&#xff1a;點擊桌面后&#xff0c;選擇系統菜單欄&#xff1a;前往—電腦—硬盤—用…

mybatis 不生效 參數_Mybatis-日志配置

日志Mybatis 的內置日志工廠提供日志功能&#xff0c;內置日志工廠將日志交給以下其中一種工具作代理&#xff1a;SLF4JApache Commons LoggingLog4j 2Log4jJDK loggingMyBatis 內置日志工廠基于運行時自省機制選擇合適的日志工具。它會使用第一個查找得到的工具(按上文列舉的順…

PS通過濾色實現簡單的圖片拼合

素材如下&#xff1a; 素材一&#xff1a; 雪山 素材二&#xff1a; 月亮 效果&#xff1a; 實現步驟 1、在PS中打開雪山素材一 2、將月亮素材直接拖入雪山所在的圖層中 3、鎖定置入素材的高寬比&#xff08;點擊一下鏈狀按鈕&#xff09; 4、調整月亮到合適大小合適位置 5、…

預處理:主成分分析與白化

主成分分析 引言 主成分分析&#xff08;PCA&#xff09;是一種能夠極大提升無監督特征學習速度的數據降維算法。更重要的是&#xff0c;理解PCA算法&#xff0c;對實現白化算法有很大的幫助&#xff0c;很多算法都先用白化算法作預處理步驟。 假設你使用圖像來訓練算法&#x…

jQuery Ajax

jQuery load()方法&#xff1a;是簡單但強大的Ajax 方法load() 方法從服務器(URL,data,callback);必須的URL 參數規定您希望架加載的URL可選的data參數 規定與請求一同發送的差字符串鍵/值對集合。可選的callback參數時load()方法完成后所執行的函數名稱$(documnet).ready(…

swagger 修改dto注解_Web服務開發:Spring集成Swagger,3步自動生成API文檔

目錄&#xff1a;1&#xff0c;Spring Boot集成Swagger2&#xff0c;Swagger接口文檔頁面3&#xff0c;常見問題和解決方法在Sping開發REST接口服務時&#xff0c;API文檔是不可缺少的一個重要部分。Swagger框架定義了完整的REST接口文檔規范&#xff0c;提供了強大的頁面測試功…

WPF自定義控件之列表滑動特效 PowerListBox

列表控件是應用程序中常見的控件之一&#xff0c;對其做一些絢麗的視覺特效&#xff0c;可以讓軟件增色不少。 本人網上看過一個視頻&#xff0c;是windows phone 7系統上的一個App的列表滾動效果&#xff0c;效果非常炫 現在在WPF上用ListBox重現此效果 首先我們來分析一下&am…

去除inline-block元素間間距

根本原因&#xff1a;inline-block元素之間之所以有空白間距是因為空格有字體大小原因。 第一種&#xff1a; 把代碼之間的換行空白都去掉。 例如&#xff1a; <div>第一個inline-block元素</div><div>第二個inline-block元素</div> 第二種&#xff1a…

python - 定時清理ES 索引

只保留三天 #!/usr/bin/env python3 # -*- coding:utf-8 -*- import os import datetime# 時間轉化為字符串now_time datetime.datetime.now().strptime(datetime.datetime.now().strftime("%Y.%m.%d"),"%Y.%m.%d") os.system("curl -XGET http://12…

CnosDB如何確保多步操作的最終一致性?

背景 在時序數據庫中&#xff0c;資源的操作是一個復雜且關鍵的任務。這些操作通常涉及到多個步驟&#xff0c;每個步驟都可能會失敗&#xff0c;導致資源處于不一致的狀態。例如&#xff0c;一個用戶可能想要在CnosDB集群中刪除一個租戶&#xff0c;這個操作可能需要刪除租戶…

頸椎前路caspar撐開器_“骨質增生”導致的頸椎病怎么破?

來源&#xff1a;《脊柱外科微創手術精要》作者&#xff1a;中日友好醫院 鄒海波此文是區別于頸椎間盤軟性突出診治一文&#xff0c;主要針對“骨質增生”導致的頸椎病(Spondylosis)進行介紹。傳統的頸椎前路手術主要為頸椎病而設計。一度認為對頸椎病采用前路手術的主要好處在…

Struts2整合Freemarker生成靜態頁面

2019獨角獸企業重金招聘Python工程師標準>>> 這是生成靜態頁面的預覽&#xff1a; 其對應的模板文件&#xff1a; <table style"text-align:center;FONT-SIZE: 11pt; WIDTH: 600px; FONT-FAMILY: 宋體; BORDER-COLLAPSE: collapse" borderColor#3399ff…