이번에는 STM32F446에서 USB CDC(Communication Device Class) = USB Virtual Comport Serial Driver 기능을 테스트해 보겠습니다.
회사에서 제작한 보드에는 WLCSP 타입의 STM32F446 IC를 사용해서 CUBEMX 툴에서 패키지를 바꿨습니다.
[회사에서 제작한 보드]
아이고 그런데, 설계를 USB HS 포트에 연결을 해놨네.. @@
이번에 처음 테스트를 했는데, 결과적으로 USB DFU 와 CDC 모두 잘 됐습니다.
USB CDC 는 정말 간단합니다. CUBEMX 툴에서 설정만 제대로 하면 거의 다 된 것입니다.
하지만 아무리 해도 CDC가 UART 포트로 잘 안잡혔는데, 유튜브 동영상 보고 수정하니까 잘 됩니다.
이 내용은 나중에 말씀드리겠습니다.
먼저 CUBEMX 툴로 PINOUT 설정에서 필요한 기능들을 정의합니다.
1. USB_HS 포트에 internal FS Phy 를 Device Only 로 설정.
2. RCC 에서 HSE 를 Crystal 로 설정. MiddleWares 의 USB_DEVICE 에 CDC로 설정.
3. 클럭 설정에서 외부 클락을 24MHz로 수정하고 HCLK 를 180MHz로 수정하고 엔터치면 오랜 시간이 걸린 후에 168MHz로 자동으로 계산해 주는데, 자주 하다 보니 그냥 처음부터 168MHz를 써 주면 금방 설정이 완료 됩니다.
4. 마무리로 프로젝트 이름 넣어주고 Toolchain / IDE를 Keil로 설정하고 Generate code 를 클릭하면 Keil 코드가 만들어 집니다.
5. 그냥 이대로 KEIL 에서 컴파일해서 다운로드해 주면 다음과 같이 PC 장치관리자에서 USB CDC 는 보이는데,
오류가 발생합니다.
다음의 Youtube 영상의 2:36 부분부터 유심히 보시면 저와 같은 결과에 어떻게 대응하는지 잘 나와 있습니다.저도 이 영상보고 수정해서 성공했습니다.
6. 수정할 코드는 usbd_cdc.h 의 CDC_DATA_HS_MAX_PACKET_SIZE 의 값이 잘 못 되어 있습니다. (^^ 저는 원리도 모르겠고 그냥 따라했는데 잘 되요.)
아뭏든 512 를 256 으로 고치면 정상적으로 PC에서 COM PORT가 잡힙니다.
7. PC장치관리자에서 포트 확인
8. 이렇게까지 하면 포트만 생성됐지 터미날 연결하면 아무짓도 안하는게 당연하겠죠? ^^
USB UART 출력 함수는 usbd_cdc_if.c 파일 안에 uint8_t CDC_Transmit_HS(uint8_t* Buf, uint16_t Len) 함수를 사용하면 됩니다.
간단한 예로,
CDC_Transmit_HS("Try..!!\n\r",9); 하면
터미날에 ..
Try..!!
라고 출력 됩니다.
그런데 printf 함수가 참 편하므로 이것도 printf() 함수 쓰는 방법을 알아보겠습니다.
예전에 UART에서 사용하던 것과 같이 tx 함수만 CDC_Transmit_HS() 함수로 수정해 주면 됩니다.
main.c 파일에 다음과 같이 추가해 주시면 됩니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
/* USER CODE BEGIN 0 */
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
while(CDC_Transmit_HS((uint8_t *)&ch, 1) == USBD_BUSY);
return ch;
}
| cs |
그런 다음에 필요한 곳에서 printf() 함수를 사용하시면 됩니다.
끝...
이런 한가지 빼 먹었습니다. #include 에 다음과 같이 추가해 주세요.
1
2
3
4
5
6
7
8
9
10
|
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f4xx_hal.h"
#include "usb_device.h"
/* USER CODE BEGIN Includes */
#include "string.h"
#include "usbd_cdc_if.h"
/* USER CODE END Includes */
| cs |
이것은 따로 프로젝트 파일 첨부하지 않겠습니다.
너무 간단하니까요. ^^
댓글 없음:
댓글 쓰기