USB practice
Bullshit ahead
After many hardships, I finally soldered the USB board, emm, let’s talk about the shortcomings.
- When designing, I forgot to add a power light to the power supply, which resulted in no power indicator to tell me when I was powered on. Therefore, in the use of LEDs, I specially use a user LED light as a power light to tell me that I have electricity and are running.
- There is no outgoing serial port as a debugging interface. This problem is actually not serious. The main reason is to learn the USB protocol, so I can use the USB CDC as a serial port (that is, a virtual serial port).
- There are no positioning holes on the board, so I can't use things to fix or support it. It seems a little unsafe to throw it directly on the table.
Based on the defects of the above points, the next version of the board will be corrected to make a good and convenient USB learning board.
Come try?
There are two USB interfaces on this board, USB1 and USB2. USB1 is controlled by the PIDUSBD12 chip, and USB2 is directly connected to the USB interface of STM32. When connecting to USB2, the computer will prompt that the device cannot be recognized. This is normal, because I did not drive the USB device at all and did not send instructions to the host, so the host can only recognize that the device is plugged in, but I don’t know which device is. There is no information about the device, so it is recognized as an unrecognized device.
Drive PDIUSBD12
As can be seen from the figure, PDIUSBD12 uses 8 wires as data wires for data transmission. Two USB wires are connected to the USB interface. It is equipped with a 6MHz crystal oscillator. It has two read-write control pins and one interrupt generation pin. Therefore, in terms of program, it is actually very easy to drive it.
For the rest of the initialization (LED\KEY, I won’t talk about it, there are a lot of them on the Internet), I directly use STM32CUBEMX to directly build the initialization of the project, including LED\KEY\USB FS, all of which are initialized. The USB CDC is initialized for Used for serial port debugging.
After completion, initialize PDIUSBD12, first initialize all the pins to push output mode, and the INT pin needs to enable interrupts.
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);
}
After initialization, you need to write related read and write functions to the data port
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拉高
}