[Źródło: http://www.st.com/en/evaluation-tools/stm32f4discovery.html]
Cube Mx:
Poniżej przejdę przez całe przygotowanie projektu w środowisku CubeMx.
W pierwszej kolejności należy włączyć sygnały RCC oraz diody led do sygnalizacji stanu pracy od PD12 do PD15.
Najważniejsze jest otrzymanie zegara dla USB o wartości 48MHz.
Dalej należy włączyć USB_OTG_FS w trybie Device Only:
Kolejnym elementem jest włączenie CDC w trybie VCP.
Ustawienia USB w części konfiguracyjnej:
USB Device:
Program:
Po wygenerowaniu przygotowanego projektu należy jeszcze zainstalować sterowniki dla VCP. Po tym po wgraniu wygenerowanego kodu układ powinien być wykryty jako VCP w komputrze.
Pliki projektu znajdują się pod tym linkiem.
W pierwszej kolejności należy do pliku main.c dołączyć plik usbd_cdc_if.h.
Drugim elementem jaki należałoby zrobić jest zwiększenie buforów danych w pliku usbd_cdc.h
- /* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */
- #define CDC_DATA_HS_MAX_PACKET_SIZE 256 /* Endpoint IN & OUT Packet size */
- #define CDC_DATA_FS_MAX_PACKET_SIZE 64 /* Endpoint IN & OUT Packet size */
- #define CDC_CMD_PACKET_SIZE 8 /* Control Endpoint Packet size */
Następnie zwiększyć należy bufor danych odebranych oraz wysłanych przez CDC. Najlepiej tego typu elementy wprowadzać wartość potęgi 2. Wartości wielkości bufora wprowadza się w pliku usbd_cdc_if.c.
- /* USER CODE BEGIN PRIVATE_DEFINES */
- /* Define size for the receive and transmit buffer over CDC */
- /* It's up to user to redefine and/or remove those define */
- #define APP_RX_DATA_SIZE 128
- #define APP_TX_DATA_SIZE 128
- /* USER CODE END PRIVATE_DEFINES */
No i teraz właściwie można przejść do kodu aplikacji głównej. W której nastąpi transmisja danych. Będzie ona dwustronna, cyklicznie będą przesyłane kolejne dane na komputer, natomiast niezależnie dane będą odbierane, i ponownie przesyłane na ekran.
Teraz należy ponownie wrócić do pliku usbd_cdc_if.c. W nim wprowadza się następujący kod, który pozwoli na odbieranie wysłanych danych.
- volatile extern char string_rx[40];
- //...
- //...
- //...
- static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len)
- {
- /* USER CODE BEGIN 6 */
- strncpy(string_rx, (char*)Buf,*Len);
- string_rx[*Len] = 0;
- USBD_CDC_ReceivePacket(&hUsbDeviceFS);
- return (USBD_OK);
- /* USER CODE END 6 */
- }
Teraz plik main.c. W kleje poniżej część pliku do końca funkcji main. Pozostałe pliki zostają takie jakie wygenerował CubeMx.
- /* Includes ------------------------------------------------------------------*/
- #include "main.h"
- #include "string.h"
- #include "stm32f4xx_hal.h"
- #include "usb_device.h"
- /* USER CODE BEGIN Includes */
- #include "usbd_cdc_if.h"
- /* USER CODE END Includes */
- /* Private variables ---------------------------------------------------------*/
- I2C_HandleTypeDef hi2c1;
- /* USER CODE BEGIN PV */
- /* Private variables ---------------------------------------------------------*/
- char string_tx[64];
- char string_rx[64];
- /* USER CODE END PV */
- /* Private function prototypes -----------------------------------------------*/
- void SystemClock_Config(void);
- void Error_Handler(void);
- static void MX_GPIO_Init(void);
- static void MX_I2C1_Init(void);
- /* USER CODE BEGIN PFP */
- /* Private function prototypes -----------------------------------------------*/
- /* USER CODE END PFP */
- /* USER CODE BEGIN 0 */
- /* USER CODE END 0 */
- int main(void)
- {
- /* USER CODE BEGIN 1 */
- uint8_t i=0;
- uint8_t number=0;
- /* USER CODE END 1 */
- /* MCU Configuration----------------------------------------------------------*/
- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
- HAL_Init();
- /* Configure the system clock */
- SystemClock_Config();
- /* Initialize all configured peripherals */
- MX_GPIO_Init();
- MX_I2C1_Init();
- MX_USB_DEVICE_Init();
- /* USER CODE BEGIN 2 */
- /* USER CODE END 2 */
- /* Infinite loop */
- /* USER CODE BEGIN WHILE */
- while (1)
- {
- /* USER CODE END WHILE */
- sprintf(string_tx, "USB Transmit %d\r\n", number);
- CDC_Transmit_FS((uint8_t*)string_tx, strlen(string_tx));
- number++;
- HAL_Delay(500);
- for(i=1;i<((uint8_t)(64-strlen(string_rx)));i++)
- {
- CDC_Transmit_FS((uint8_t*)string_rx, strlen(string_rx));
- }
- for(i=0;i<64;i++)
- {
- string_tx[i] = 0;
- string_rx[i] = 0;
- }
- /* USER CODE BEGIN 3 */
- }
- /* USER CODE END 3 */
- }