網(wǎng)上有很多關(guān)于按鍵pos機(jī)鍵盤,阿波羅 STM32F767 開發(fā)板資料連載第六十五章 USB 鼠標(biāo)鍵盤實(shí)驗(yàn)的知識(shí),也有很多人為大家解答關(guān)于按鍵pos機(jī)鍵盤的問題,今天pos機(jī)之家(www.rcqwhg.com)為大家整理了關(guān)于這方面的知識(shí),讓我們一起來看下吧!
本文目錄一覽:
按鍵pos機(jī)鍵盤
1)實(shí)驗(yàn)平臺(tái):alientek 阿波羅 STM32F767 開發(fā)板2)摘自《STM32F7 開發(fā)指南(HAL 庫版)》關(guān)注官方微信號(hào)公眾號(hào),獲取更多資料:正點(diǎn)原子
第六十五章 USB 鼠標(biāo)鍵盤(Host)實(shí)驗(yàn)
上一章我們向大家介紹了如何利用 STM32F767 的 USB HOST 接口來驅(qū)動(dòng) U 盤,本章,我
們將利用 STM32F767 的 USB HOST 來驅(qū)動(dòng) USB 鼠標(biāo)/鍵盤。本章分為如下幾個(gè)部分:
65.1 USB 鼠標(biāo)鍵盤簡(jiǎn)介
65.2 硬件設(shè)計(jì)
65.3 軟件設(shè)計(jì)
65.4 下載驗(yàn)證
65.1 USB 鼠標(biāo)鍵盤簡(jiǎn)介
傳統(tǒng)的鼠標(biāo)和鍵盤是采用 PS/2 接口和電腦通信的,但是現(xiàn)在 PS/2 接口在電腦上逐漸消失,
所以現(xiàn)在越來越多的鼠標(biāo)鍵盤采用的是 USB 接口,而不是 PS/2 接口的了。
USB 鼠標(biāo)鍵盤屬于 USB HID 設(shè)備。USB HID 即:Human Interface Device(人機(jī)交互設(shè)備)
的縮寫,鍵盤、鼠標(biāo)與游戲桿等都屬于此類設(shè)備。不過 HID 設(shè)備并不一定要有人機(jī)接口,只要
符合 HID 類別規(guī)范的設(shè)備都是 HID 設(shè)備。關(guān)于 USB HID 的知識(shí),我們這里就不詳細(xì)介紹了,
請(qǐng)大家自行百度學(xué)習(xí)。
本章,我們同上一章一樣,我們直接移植官方的 USB HID 例程,官方例程路徑:光盤\uf0e08,
STM32 參考資料\uf0e0STM32 USB 學(xué)習(xí)資料\uf0e0STM32_USB-Host-Device_Lib_V2.2.0\uf0e0Project\uf0e0
USB_Host_Examples\uf0e0HID,該例程支持 USB 鼠標(biāo)和鍵盤等 USB HID 設(shè)備,本章我們將移植這
個(gè)例程到阿波羅 STM32 開發(fā)板上。
65.2 硬件設(shè)計(jì)
本節(jié)實(shí)驗(yàn)功能簡(jiǎn)介:開機(jī)的時(shí)候先顯示一些提示信息,然后初始化 USB HOST,并不斷輪
詢。當(dāng)檢測(cè)到 USB 鼠標(biāo)/鍵盤的插入后,顯示設(shè)備類型,并顯示設(shè)備輸入數(shù)據(jù),
如果是 USB 鼠標(biāo):將顯示鼠標(biāo)移動(dòng)的坐標(biāo)(X,Y 坐標(biāo)),滾輪滾動(dòng)數(shù)值(Z 坐標(biāo))以及
按鍵(左中右)。
如果是 USB 鍵盤:將顯示鍵盤輸入的數(shù)字/字母等內(nèi)容(不是所有按鍵都支持,部分按鍵
沒有做解碼支持,比如 F1~F12)。
最后,還是用 DS0 提示程序正在運(yùn)行。
所要用到的硬件資源如下:
1) 指示燈 DS0
2) 串口
3) LCD 模塊
4) USB HOST 接口
這幾個(gè)部分,在之前的實(shí)例中都已經(jīng)介紹過了,我們?cè)诖司筒欢嗾f了。這里再次提醒大家,
P10 的連接,要通過跳線帽連接 PA11 和 D-以及 PA12 和 D+。
65.3 軟件設(shè)計(jì)
本章,我們?cè)诘诙聦?shí)驗(yàn) (實(shí)驗(yàn) 15 LTDC LCD(RGB 屏)實(shí)驗(yàn))的基礎(chǔ)上修改,先打
開實(shí)驗(yàn) 15 的工程,在 HARDWARE 文件夾所在文件夾下新建一個(gè) USB 的文件夾,對(duì)照官方
HID 例子,將相關(guān)文件拷貝到 USB 文件夾下。
然后,我們?cè)诠こ汤锩嫣砑?USB HID 相關(guān)代碼,最終得到如圖 65.3.1 所示的工程:
圖 62.3.1 USB 鼠標(biāo)鍵盤工程截圖
注意:為了支持 STM32F7,USB OTG 庫部分代碼要做修改,詳見 61.3 節(jié)的介紹(USB
HOST 實(shí)驗(yàn)只需要修改 usb_core.c 這一個(gè)文件就可以支持 STM32F7 了)。
可以看到,USB 部分代碼,同上一章的在結(jié)構(gòu)上是一模一樣的,只是.c 文件稍微有些變化。
同樣,我們移植需要修改的代碼,就是 USB_APP 里面的這兩個(gè).c 文件了。
其中 usb_bsp.c 的代碼,和之前的章節(jié)一模一樣,可以用上一章的代碼直接替換即可正常使
用。
usbh_usr.c 里面的代碼,則有所變化,重點(diǎn)代碼如下:
//下面兩個(gè)函數(shù),為 ALIENTEK 添加,以防止 USB 死機(jī)//USB 枚舉狀態(tài)死機(jī)檢測(cè),防止 USB 枚舉失敗導(dǎo)致的死機(jī)//phost:USB_HOST 結(jié)構(gòu)體指針//返回值:0,沒有死機(jī)// 1,死機(jī)了,外部必須重新啟動(dòng) USB 連接.u8 USBH_Check_EnumeDead(USBH_HOST *phost){static u16 errcnt=0;//這個(gè)狀態(tài),如果持續(xù)存在,則說明 USB 死機(jī)了.if(phost->gState==HOST_CTRL_XFER&&(phost->EnumState==ENUM_IDLE||phost->EnumState==ENUM_GET_FULL_DEV_DESC)){errcnt++;if(errcnt>2000)//死機(jī)了{(lán) errcnt=0;RCC->AHB2RSTR|=1<<7; //USB OTG FS 復(fù)位delay_ms(5);RCC->AHB2RSTR&=~(1<<7); //復(fù)位結(jié)束 return 1;} }else errcnt=0;return 0;} //USB HID 通信死機(jī)檢測(cè),防止 USB 通信死機(jī)(暫時(shí)僅針對(duì):DTERR,即 Data toggle error)//pcore:USB_OTG_Core_dev_HANDLE 結(jié)構(gòu)體指針//phidm:HID_Machine_TypeDef 結(jié)構(gòu)體指針//返回值:0,沒有死機(jī)// 1,死機(jī)了,外部必須重新啟動(dòng) 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 錯(cuò)誤{ return 1;}return 0;}//USB 鍵盤鼠標(biāo)數(shù)據(jù)處理//鼠標(biāo)初始化void USR_MOUSE_Init(void){USBH_Msg_Show(2); //USB 鼠標(biāo)USB_FIRST_PLUGIN_FLAG=1;//標(biāo)記第一次插入}//鍵盤初始化void USR_KEYBRD_Init(void){ USBH_Msg_Show(1); //USB 鍵盤USB_FIRST_PLUGIN_FLAG=1;//標(biāo)記第一次插入}//臨時(shí)數(shù)組,用于存放鼠標(biāo)坐標(biāo)/鍵盤輸入內(nèi)容(4.3 屏,最大可以輸入 2016 字節(jié))__align(4) u8 tbuf[2017]; //USB 鼠標(biāo)數(shù)據(jù)處理//data:USB 鼠標(biāo)數(shù)據(jù)結(jié)構(gòu)體指針void USR_MOUSE_ProcessData(HID_MOUSE_Data_TypeDef *data){ static signed short x,y,z; if(USB_FIRST_PLUGIN_FLAG)//第一次插入,將數(shù)據(jù)清零{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="360px",height="auto" />
ST 官方的 USB HID 例程,僅僅是能用,很多地方還要改善,比如識(shí)別率低,容易死機(jī)(枚
舉/通信都可能死機(jī))等問題,這里:USBH_Check_EnumeDead 和 USBH_Check_HIDCommDead
這兩個(gè)函數(shù),就是我們針對(duì)官方 HID 例程現(xiàn)有 bug 做出的改進(jìn)處理,通過這兩個(gè)函數(shù),可以檢
測(cè)枚舉/通信是否正常,當(dāng)出現(xiàn)異常時(shí),直接重啟 USB 內(nèi)核,重新連接設(shè)備,這樣可以防止死
機(jī)造成的程序無響應(yīng)情況。
另外,為了提高對(duì)鼠標(biāo)鍵盤的識(shí)別率和兼容性,對(duì) usbh_hid_core.c 里面的兩處代碼進(jìn)行了
修改:
1,USBH_HID_ClassRequest 函數(shù),修改代碼(394 行)為:
classReqStatus = USBH_Set_Idle (pdev, pphost, 100, 0);//這里 duration 官方設(shè)置的是 0,修改為
//100,提高兼容性
2,USBH_Set_Idle 函數(shù),修改代碼(542 行)為:
phost->Control.setup.b.wLength.w = 100; //官方的這里設(shè)置的是 0,導(dǎo)致部分鼠標(biāo)無法識(shí)別,
//這里修改為 100 以后,識(shí)別率明顯提高.
以上兩處地方,官方默認(rèn)值都是設(shè)置的 0,我們修改為 100 后,可以明顯提高 USB 鼠標(biāo)/
鍵盤的識(shí)別率,兼容性好很多。
還有,在 usbh_hid_keybd.h 里面,要修改鍵盤類型的定義,改為:
#define QWERTY_KEYBOARD
//通用鍵盤
//#define AZERTY_KEYBOARD
//法國(guó)版鍵盤
ST 官方例程,是使用的法國(guó)版鍵盤,一般我們國(guó)內(nèi)用的是通用鍵盤,所以,需要換一個(gè)宏
定義(換成:QWERTY_KEYBOARD)。
最后,在 usbh_hid_mouse.c 里面,MOUSE_Decode 函數(shù)用于鼠標(biāo)數(shù)據(jù)解析,但是 ST 官方
例程僅對(duì) 4 字節(jié)鼠標(biāo)數(shù)據(jù)做了解析,而忽略了 5 字節(jié)/6 字節(jié)鼠標(biāo)數(shù)據(jù)的處理,所以,需要修改
該函數(shù)為:
extern HID_Machine_TypeDef HID_Machine;
static void MOUSE_Decode(uint8_t *data)
{
if(HID_Machine.length==5||HID_Machine.length==6||HID_Machine.length==8)
//5/6/8 字節(jié)長(zhǎng)度的 USB 鼠標(biāo)數(shù)據(jù)處理
{
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 字節(jié)長(zhǎng)度的 USB 鼠標(biāo)數(shù)據(jù)處理
{
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 用于處理鼠標(biāo)數(shù)據(jù),這
兩個(gè)函數(shù)在 usbh_hid_mouse.c 里面被調(diào)用,USR_MOUSE_Init 在鼠標(biāo)初始化的時(shí)候被調(diào)用,而
USR_MOUSE_ProcessData 函數(shù),則在鼠標(biāo)初始化成功,輪詢數(shù)據(jù)的時(shí)候調(diào)用,處理鼠標(biāo)數(shù)據(jù),
該函數(shù)將得到的鼠標(biāo)數(shù)據(jù)顯示在 LCD 上面。
同樣,USR_KEYBRD_Init 和 USR_KEYBRD_ProcessData 用于處理鍵盤數(shù)據(jù),這兩個(gè)函數(shù)
在 usbh_hid_keybd.c 里面被調(diào)用,USR_KEYBRD_Init 在鍵盤初始化的時(shí)候被調(diào)用,而
USR_KEYBRD_ProcessData 函數(shù),則在鍵盤初始化成功,輪詢數(shù)據(jù)的時(shí)候調(diào)用,處理鍵盤數(shù)據(jù),
該函數(shù)將鍵盤輸入的字符顯示在 LCD 上面。
其他代碼,我們就不再介紹了,請(qǐng)大家參考開發(fā)板光盤本例程源碼。
最后,來看看 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 鼠標(biāo)// 3,不支持的 USB 設(shè)備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="360px",height="auto" />
int main(void)
{
u8 t;
Cache_Enable(); //打開 L1-Cache
HAL_Init();
//初始化 HAL 庫
Stm32_Clock_Init(432,25,2,9); //設(shè)置時(shí)鐘,216Mhz
delay_init(216); //延時(shí)初始化
uart_init(115200);
//串口初始化
LED_Init(); //初始化 LED
KEY_Init(); //初始化按鍵
SDRAM_Init();
//初始化 SDRAM
LCD_Init(); //初始化 LCD
W25QXX_Init();
//初始化 W25Q256
PCF8574_Init();
//初始化 PCF8574
POINT_COLOR=RED;
LCD_ShowString(30,50,200,16,16,"Apollo STM32F4/F7");
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,"2016/8/11");
LCD_ShowString(30,130,200,16,16,"USB Connecting...");
//初始化 USB 主機(jī)
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))
//檢測(cè) USB HID 通信,是否還正常?
{
USBH_HID_Reconnect();//重連
}
}else
//連接未建立的時(shí)候,檢測(cè)
{
if(USBH_Check_EnumeDead(&USB_Host))
//檢測(cè) USB HOST 枚舉是否死機(jī)了?死機(jī)了,則重新初始化
{
USBH_HID_Reconnect();//重連
}
}
t++;
if(t==200000)
{
LED0_Toggle;
t=0;
}
}
}
這里總共三個(gè)函數(shù):USBH_Msg_Show 用于顯示一些提示信息,在 usbh_usr.c 里面被相關(guān)函數(shù)
調(diào)用。USBH_HID_Reconnect 則用于 USB HID 重新連接,當(dāng)發(fā)現(xiàn)枚舉/通信死機(jī)的時(shí)候,調(diào)用
該函數(shù)實(shí)現(xiàn) USB 復(fù)位重啟,以重新連接;最后,main 函數(shù)就比較簡(jiǎn)單了,處理方式和上一章
幾乎一樣,只是多了一些通信死機(jī)處理。
軟件設(shè)計(jì)部分就為大家介紹到這里。
65.4 下載驗(yàn)證
在代碼編譯成功之后,我們下載到阿波羅 STM32 開發(fā)板上,然后在 USB_HOST 端子插入
USB 鼠標(biāo)/鍵盤,注意:此時(shí) USB SLAVE 口不要插 USB 線到電腦,否則會(huì)干擾?。?/strong>
等 USB 鼠標(biāo)/鍵盤成功識(shí)別后,便可以看到 LCD 顯示 USB Connected,并顯示設(shè)備類型:
USB Mouse 或者 USB KeyBoard,同時(shí)也會(huì)顯示輸入的數(shù)據(jù),如圖 65.4.1 和圖 65.4.2 所示:
圖 65.4.1 USB 鼠標(biāo)測(cè)試
圖 65.4.2 USB 鍵盤測(cè)試
其中,圖 65.4.1 是 USB 鼠標(biāo)測(cè)試界面,圖 65.4.2 是 USB 鍵盤測(cè)試界面。
最后,特別提醒大家,由于例程的 HID 內(nèi)核,只處理了第一個(gè)接口描述符,所以對(duì)于 USB
符合設(shè)備,只能識(shí)別第一個(gè)描述符所代表的設(shè)備。體現(xiàn)到實(shí)際使用中,就是:USB 無線鼠標(biāo),
一般是無法使用(被識(shí)別為鍵盤),而 USB 無線鍵盤,可以使用,因?yàn)殒I盤在第一個(gè)描述符,
鼠標(biāo)在第二個(gè)描述符。
如果想支持 USB 無線鼠標(biāo),可以通過修改 usbh_hid_core.c 里面的 USBH_HID_InterfaceInit
函數(shù)來支持
以上就是關(guān)于按鍵pos機(jī)鍵盤,阿波羅 STM32F767 開發(fā)板資料連載第六十五章 USB 鼠標(biāo)鍵盤實(shí)驗(yàn)的知識(shí),后面我們會(huì)繼續(xù)為大家整理關(guān)于按鍵pos機(jī)鍵盤的知識(shí),希望能夠幫助到大家!