USB實踐
廢話在前面
經歷千辛萬苦終於把USB的板子焊好了,emm,來說一下缺點。
- 在設計的時候,忘了給電源加上電源燈,這導致上電的時候的,並沒有電源指示燈告訴我上電了。因此我在LED的使用上,特地用一個用戶LED燈當作電源燈,告訴我自己有電並且在運行。
- 沒有流出串口接口作爲調試接口,這個問題其實並不嚴重,主要是學習USB的協議,所以我可以利用USB CDC當作串口來使用(就是虛擬串口)。
- 板子上沒有加入定位孔定位,所以我不能用東西固定或者撐起來,直接扔桌面顯得有些不安全。
根據以上幾點的缺陷,在下一個版本的板子上將會進行修正,做一個好的、方便的USB學習板卡。
來試試?
此板卡上有兩個USB接口,USB1 和USB2,USB1使用的是PIDUSBD12的芯片控制的,USB2直接接STM32的USB接口。在接入USB2的時候,電腦將提示無法識別設備,這很正常的,因爲我根本沒有驅動起USB設備,沒有給主機發送指令,所以主機只能識別到有設備插入,卻不知道這個設備是什麼設備,沒有任何信息,所以識別爲無法識別的設備。
驅動PDIUSBD12
由圖可以看到,PDIUSBD12使用8根線作爲數據線傳輸數據用,兩根USB線接入USB接口,配有6MHz的晶振,有兩個讀寫控制引腳和一箇中斷髮生引腳。所以,在程序上,其實很好對其進行驅動。
其餘部分的初始化(LED\KEY那些,我就不說了,網上大把),我直接用STM32CUBEMX直接建立好工程的初始化,包括LED\KEY\USB FS,都初始化好,USB CDC的初始化是爲了用作串口調試用。
完成之後,對PDIUSBD12進行初始化,先把引腳都初始化爲推完輸出模式,INT引腳需要使能中斷。
void PDIUSBD12_init(void)
{
GPIO_InitTypeDef GPIO_Init;
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Init.Pin = GPIO_PIN_0|GPIO_PIN_1|
GPIO_PIN_2|GPIO_PIN_3|
GPIO_PIN_4|GPIO_PIN_5|
GPIO_PIN_6|GPIO_PIN_7;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW
HAL_GPIO_Init(GPIOC,&GPIO_Init);
GPIO_Init.Pin = GPIO_PIN_12|GPIO_PIN_13;
HAL_GPIO_Init(GPIOB,&GPIO_Init);
GPIO_Init.Mode = GPIO_MODE_INPUT;
GPIO_Init.Pin = GPIO_PIN_14;
GPIO_Init.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_Init);
}
初始化之後,需要對數據口寫好相關讀寫函數
void PDIUSBD12_write_cmd(uint8_t cmd)
{
GPIO_InitTypeDef GPIO_Init;
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Init.Pin = GPIO_PIN_0|GPIO_PIN_1|
GPIO_PIN_2|GPIO_PIN_3|
GPIO_PIN_4|GPIO_PIN_5|
GPIO_PIN_6|GPIO_PIN_7;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC,&GPIO_Init);
HAL_GPIO_WritePin(USB_PDI_A0_PORT, USB_PDI_A0_PIN, GPIO_PIN_SET); //A0拉高
HAL_GPIO_WritePin(USB_PDI_WR_PORT, USB_PDI_WR_PIN, GPIO_PIN_RESET); //WR拉低
/* 一位位發送數據 */
if(cmd & 0x80) HAL_GPIO_WritePin(USB_PDI_D7_PORT, USB_PDI_D7_PIN, GPIO_PIN_SET);
else HAL_GPIO_WritePin(USB_PDI_D7_PORT, USB_PDI_D7_PIN, GPIO_PIN_RESET);
cmd <<= 1;
if(cmd & 0x80) HAL_GPIO_WritePin(USB_PDI_D6_PORT, USB_PDI_D6_PIN, GPIO_PIN_SET);
else HAL_GPIO_WritePin(USB_PDI_D6_PORT, USB_PDI_D6_PIN, GPIO_PIN_RESET);
cmd <<= 1;
if(cmd & 0x80) HAL_GPIO_WritePin(USB_PDI_D5_PORT, USB_PDI_D5_PIN, GPIO_PIN_SET);
else HAL_GPIO_WritePin(USB_PDI_D5_PORT, USB_PDI_D5_PIN, GPIO_PIN_RESET);
cmd <<= 1;
if(cmd & 0x80) HAL_GPIO_WritePin(USB_PDI_D4_PORT, USB_PDI_D4_PIN, GPIO_PIN_SET);
else HAL_GPIO_WritePin(USB_PDI_D4_PORT, USB_PDI_D4_PIN, GPIO_PIN_RESET);
cmd <<= 1;
if(cmd & 0x80) HAL_GPIO_WritePin(USB_PDI_D3_PORT, USB_PDI_D3_PIN, GPIO_PIN_SET);
else HAL_GPIO_WritePin(USB_PDI_D3_PORT, USB_PDI_D3_PIN, GPIO_PIN_RESET);
cmd <<= 1;
if(cmd & 0x80) HAL_GPIO_WritePin(USB_PDI_D2_PORT, USB_PDI_D2_PIN, GPIO_PIN_SET);
else HAL_GPIO_WritePin(USB_PDI_D2_PORT, USB_PDI_D2_PIN, GPIO_PIN_RESET);
cmd <<= 1;
if(cmd & 0x80) HAL_GPIO_WritePin(USB_PDI_D1_PORT, USB_PDI_D1_PIN, GPIO_PIN_SET);
else HAL_GPIO_WritePin(USB_PDI_D1_PORT, USB_PDI_D1_PIN, GPIO_PIN_RESET);
cmd <<= 1;
if(cmd & 0x80) HAL_GPIO_WritePin(USB_PDI_D0_PORT, USB_PDI_D0_PIN, GPIO_PIN_SET);
else HAL_GPIO_WritePin(USB_PDI_D0_PORT, USB_PDI_D0_PIN, GPIO_PIN_RESET);
cmd <<= 1;
HAL_GPIO_WritePin(USB_PDI_WR_PORT, USB_PDI_WR_PIN, GPIO_PIN_SET); //WR拉高
}