2016-08-02 5 views
0

저는 USB (가상 COM 포트) 및 CAN 주변 장치를 사용해야하는 프로젝트에서 작업하고 있지만 STM32F4DISCOVERY에서 코드를 실행하면 PC가 작동하지 않습니다. VCP를 올바르게 인식하십시오 ("USB 장치가 인식되지 않음", 오류 코드 43). 이 내 주요입니다 :HAL 라이브러리가 USB 및 CAN 주변 장치와 올바르게 작동하지 않습니다.

int main(void) 
{ 
    /* STM32F4xx HAL library initialization: 
     - Configure the Flash prefetch, instruction and Data caches 
     - Systick timer is configured by default as source of time base, but user 
     can eventually implement his proper time base source (a general purpose 
     timer for example or other time source), keeping in mind that Time base 
     duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and 
     handled in milliseconds basis. 
     - Set NVIC Group Priority to 4 
     - Low Level Initialization: global MSP (MCU Support Package) initialization 
    */ 
    HAL_Init(); 

    /* Configure the system clock to 180 MHz */ 
    SystemClock_Config(); 

    /* Configure LED1 and LED3 */ 
    BSP_LED_Init(LED4); 
    BSP_LED_Init(LED5); 


    /* Init Device Library */ 
    USBD_Init(&USBD_Device, &VCP_Desc, 0); 

    /* Add Supported Class */ 
    USBD_RegisterClass(&USBD_Device, USBD_CDC_CLASS); 

    /* Add CDC Interface Class */ 
    USBD_CDC_RegisterInterface(&USBD_Device, &USBD_CDC_fops); 

    /* Start Device Process */ 
    USBD_Start(&USBD_Device); 

    if(CAN_Polling() == HAL_OK) 
    { 
    /* OK: Turn on LED1 */ 
    BSP_LED_On(LED4); 
    } 
    else 
    { 
    /* KO: Turn on LED3 */ 
    BSP_LED_On(LED5); 
    } 

    /* Infinite loop */ 
    while (1) 
    { 
    } 
} 

그리고 이것은 SystemClock_Config입니다 : 코드가 제대로 작동하지 않는 이유

static void SystemClock_Config(void) 
{ 
    RCC_ClkInitTypeDef RCC_ClkInitStruct; 
    RCC_OscInitTypeDef RCC_OscInitStruct; 
    HAL_StatusTypeDef ret = HAL_OK; 

    /* Enable Power Control clock */ 
    __HAL_RCC_PWR_CLK_ENABLE(); 

    /* The voltage scaling allows optimizing the power consumption when the device is 
    clocked below the maximum system frequency, to update the voltage scaling value 
    regarding system frequency refer to product datasheet. */ 
    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); 

    /* Enable HSE Oscillator and activate PLL with HSE as source */ 
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; 
    RCC_OscInitStruct.HSEState = RCC_HSE_ON; 
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; 
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; 
    RCC_OscInitStruct.PLL.PLLM = 25; 
    RCC_OscInitStruct.PLL.PLLN = 336; 
    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; 
    RCC_OscInitStruct.PLL.PLLQ = 7; 

    ret = HAL_RCC_OscConfig(&RCC_OscInitStruct); 
    if(ret != HAL_OK) 
    { 
    while(1) { ; } 
    } 

    /* Activate the OverDrive to reach the 180 MHz Frequency */ 
    /*ret = HAL_PWREx_EnableOverDrive(); 
    if(ret != HAL_OK) 
    { 
    while(1) { ; } 
    }*/ 

    /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ 
    RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); 
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; 
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; 
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; 
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; 

    ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); 
    if(ret != HAL_OK) 
    { 
    while(1) { ; } 
    } 
} 

그래서 난 이해가 안 돼요. 누군가 가상 COM 포트를 수정하는 데 도움을 줄 수 있습니까?

를 초기화 CAN 수 있습니다 :

HAL_StatusTypeDef CAN_Polling(void) 
{ 
    CAN_FilterConfTypeDef sFilterConfig; 
    static CanTxMsgTypeDef  TxMessage; 
    static CanRxMsgTypeDef  RxMessage; 

    /*##-1- Configure the CAN peripheral #######################################*/ 
    CanHandle.Instance = CANx; 
    CanHandle.pTxMsg = &TxMessage; 
    CanHandle.pRxMsg = &RxMessage; 

    CanHandle.Init.TTCM = DISABLE; 
    CanHandle.Init.ABOM = DISABLE; 
    CanHandle.Init.AWUM = DISABLE; 
    CanHandle.Init.NART = DISABLE; 
    CanHandle.Init.RFLM = DISABLE; 
    CanHandle.Init.TXFP = DISABLE; 
    CanHandle.Init.Mode = CAN_MODE_LOOPBACK; 
    CanHandle.Init.SJW = CAN_SJW_1TQ; 
    CanHandle.Init.BS1 = CAN_BS1_6TQ; 
    CanHandle.Init.BS2 = CAN_BS2_8TQ; 
    CanHandle.Init.Prescaler = 2; 

    if(HAL_CAN_Init(&CanHandle) != HAL_OK) 
    { 
    /* Initialization Error */ 
    Error_Handler(); 
    } 

    /*##-2- Configure the CAN Filter ###########################################*/ 
    sFilterConfig.FilterNumber = 0; 
    sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; 
    sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; 
    sFilterConfig.FilterIdHigh = 0x0000; 
    sFilterConfig.FilterIdLow = 0x0000; 
    sFilterConfig.FilterMaskIdHigh = 0x0000; 
    sFilterConfig.FilterMaskIdLow = 0x0000; 
    sFilterConfig.FilterFIFOAssignment = 0; 
    sFilterConfig.FilterActivation = ENABLE; 
    sFilterConfig.BankNumber = 14; 

    if(HAL_CAN_ConfigFilter(&CanHandle, &sFilterConfig) != HAL_OK) 
    { 
    /* Filter configuration Error */ 
    Error_Handler(); 
    } 

    /*##-3- Start the Transmission process #####################################*/ 
    CanHandle.pTxMsg->StdId = 0x11; 
    CanHandle.pTxMsg->RTR = CAN_RTR_DATA; 
    CanHandle.pTxMsg->IDE = CAN_ID_STD; 
    CanHandle.pTxMsg->DLC = 2; 
    CanHandle.pTxMsg->Data[0] = 0xCA; 
    CanHandle.pTxMsg->Data[1] = 0xFE; 

    if(HAL_CAN_Transmit(&CanHandle, 10) != HAL_OK) 
    { 
    /* Transmition Error */ 
    Error_Handler(); 
    } 

    if(HAL_CAN_GetState(&CanHandle) != HAL_CAN_STATE_READY) 
    { 
    return HAL_ERROR; 
    } 

    /*##-4- Start the Reception process ########################################*/ 
    if(HAL_CAN_Receive(&CanHandle, CAN_FIFO0,10) != HAL_OK) 
    { 
    /* Reception Error */ 
    Error_Handler(); 
    } 

    if(HAL_CAN_GetState(&CanHandle) != HAL_CAN_STATE_READY) 
    { 
    return HAL_ERROR; 
    } 

    if(CanHandle.pRxMsg->StdId != 0x11) 
    { 
    return HAL_ERROR; 
    } 

    if(CanHandle.pRxMsg->IDE != CAN_ID_STD) 
    { 
    return HAL_ERROR; 
    } 

    if(CanHandle.pRxMsg->DLC != 2) 
    { 
    return HAL_ERROR; 
    } 

    if((CanHandle.pRxMsg->Data[0]<<8|RxMessage.Data[1]) != 0xCAFE) 
    { 
    return HAL_ERROR; 
    } 

    return HAL_OK; /* Test Passed */ 
} 

답변

0

내가 출발점으로 STMCubeMX를 사용하도록 조언을 것입니다, 당신을 위해 모든 초기화를 수행합니다.

단계별 디버깅을하고 USBD_Device에서 유효한 항목이 있는지 확인하십시오. 필자의 경우 VCP를 작동시키기 위해 startup.s 파일의 힙 크기를 수동으로 늘려야했습니다.

USB의 또 다른 일반적인 문제는 시계 초기화입니다. USB가 작동하려면 48MHz 클럭이라고 정확히 48MHz가 필요합니다. 지금까지와 같이 8MHz 크리스털, PLLM = 25, PLLN = 336 및 PLLQ = 7을 사용하면 48MHz가 필요하지 않습니다. STMCubMX를 사용하면 시계 초기화가 간단 해집니다.

MCU에 전원 공급을 위해 외부 전원 공급 장치를 사용하는 경우 3.0V 이상인지 확인하십시오.

+0

VCP를 통한 통신에 HAL 예제를 사용하려고 시도했지만 작동합니다. 하지만 내가 CAN을 구현하려고 할 때 코드가 작동하지 않습니다. 디버깅을 시도했지만 문제를 해결할 수 없습니다. 프로그램이 HAL_init() 함수가 시작될 때 작동하지 않습니다 .CAN과 USB가 호환됩니까? VCP 및 CAN 용 48MHz 클럭이 필요합니까? 동일한 클럭? 결국, PLLM, PLLN 및 PLLQ의 어떤 값을 48MHz 클럭을 얻기 위해 초기화해야합니까? 답을 위해 고맙습니다. –

+0

M = 5, N = 210, P = 2 및 Q = 7 48MHz 클럭을 48MHz로 설정하고 시스템 클럭을 168MHz로 설정하십시오 USB와 CAN은 잠재적으로 동일한 핀을 공유 할 수 있습니다 .USB는 고정 핀을 가지고 있으므로 CAN과 USB를 동일하게 사용하지 않아야합니다 .48MHz 클럭 만 필요합니다 USB에 대한 게시물을 편집하고 CAN 초기화 코드를 공유하면 도움이 될 것입니다. –

+0

CAN 초기화 코드를 추가했습니다. 어떻게 CAN에 맞는 핀을 설정할 수 있습니까? 답장을 보내 주셔서 감사 드리며 바보 같은 질문에 사과드립니다. –

관련 문제