본문 바로가기

WCH/CH32V003

CH32V003 SSM - SPI DMA 동작 테스트

소형 MCU에서 가장 많이 사용하는 페리는 SPI가 아닐까? CH32V003에서 SPI 동작 테스트를 해 보자.

CH32V003 SSM EVM 보드에서 SPI는 PC5, PC6, PC7에 할당 되어 있다.

 

CH32V003의 SPI 최대 클럭 속도는 24Mhz로 STM32F030 SPI 클럭속도 보다 더 빠르다.

 

CH32V003의 SPI 기본 동작 테스트 코드

int main(void)
{
    u8 i;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
    Delay_Init();
    USART_Printf_Init(115200);
    printf("SystemClk:%d\r\n",SystemCoreClock);
#if (SPI_MODE == SLAVE_MODE)
    printf("SLAVE Mode\r\n");
    Delay_Ms(1000);
#endif
    SPI_1Lines_HalfDuplex_Init();
#if (SPI_MODE == HOST_MODE)
    printf("HOST Mode\r\n");
    Delay_Ms(2000);
    SPI_I2S_ITConfig( SPI1, SPI_I2S_IT_TXE , ENABLE );
#endif
    printf("start");
    while(1)
    {
#if (SPI_MODE == HOST_MODE)
        while( Txval<18 );
        while( SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_TXE ) != RESET )
        {
            if(SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_BSY ) == RESET)
            {
                SPI_Cmd( SPI1, DISABLE );
                while(1);
            }
        }
        while( Txval<18 );
        while( SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_TXE ) != RESET )
        {
            if(SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_BSY ) == RESET)
            {
                SPI_Cmd( SPI1, DISABLE );
                while(1);
            }
        }
/*
        SPI_I2S_SendData( SPI1, TxData[0] );
        //SPI_I2S_ITConfig( SPI1, SPI_I2S_IT_TXE , DISABLE );
        SPI_I2S_SendData( SPI1, TxData[1] );
        //SPI_I2S_ITConfig( SPI1, SPI_I2S_IT_TXE , DISABLE );
         */
        Delay_Ms(1000);
        printf( ".");
#elif (SPI_MODE == SLAVE_MODE)
        while( Rxval<18 );
        for( i=0; i<18; i++ ){
            printf( "Rxdata:%04x\r\n", RxData[i] );
        }
        while(1);
#endif
    }
}
void SPI1_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
/*********************************************************************
 * @fn      SPI1_IRQHandler
 *
 * @brief   This function handles SPI1 exception.
 *
 * @return  none
 */
void SPI1_IRQHandler(void)
{
#if (SPI_MODE == HOST_MODE)
    if( SPI_I2S_GetITStatus( SPI1, SPI_I2S_IT_TXE ) != RESET )
    {
        SPI_I2S_SendData( SPI1, TxData[Txval++] );
        //SPI_I2S_SendData( SPI1, 0xf000 );
        if( Txval == 18 )
        {
            SPI_I2S_ITConfig( SPI1, SPI_I2S_IT_TXE , DISABLE );
        }
    }
#elif (SPI_MODE == SLAVE_MODE)
    RxData[Rxval++] = SPI_I2S_ReceiveData( SPI1 );
#endif
}

 

SPI 클럭 속도는 최대 속도인 24Mhz가 출력되고 역시 SPI 출력간의 딜레이는 1.4us로 느려진다.

 


CH32V003의 SPI 속도를 높이기 위해 DMA를 사용하면 되는데 아래 코드로 SPI DMA를 구현 할 수 있다.

int main(void)
{
    u8 i;
    Delay_Init();
    //USART_Printf_Init(460800);
    USART_Printf_Init(115200);
    printf("SystemClk:%d\r\n", SystemCoreClock);
    SPI_FullDuplex_Init();
#if(SPI_MODE == SLAVE_MODE)
    printf("Slave Mode\r\n");
    Delay_Ms(1000);
#endif
#if(SPI_MODE == HOST_MODE)
    printf("Host Mode\r\n");
    Delay_Ms(2000);
#endif
    /*
    DMA_Tx_Init(DMA1_Channel3, (u32)&SPI1->DATAR, (u32)TxData, Size);
    DMA_Rx_Init(DMA1_Channel2, (u32)&SPI1->DATAR, (u32)RxData, Size);
    DMA_Cmd(DMA1_Channel3, ENABLE);
    DMA_Cmd(DMA1_Channel2, ENABLE);
*/
    while(1)
    {
        DMA_Tx_Init(DMA1_Channel3, (u32)&SPI1->DATAR, (u32)TxData, 4);
        DMA_Cmd(DMA1_Channel3, ENABLE);
        Delay_Ms(10);
        /*
        while((!DMA_GetFlagStatus(DMA1_FLAG_TC2)) && (!DMA_GetFlagStatus(DMA1_FLAG_TC3)));
        for(i = 0; i < Size; i++)
        {
            printf(" RxData:%04x\r\n", RxData[i]);
        }
        while(1);*/
    }
}

 

테스트 결과 SPI데이터의 출력이 지연없이 동작 하는것을 확인 할 수 있다.

반응형