소형 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데이터의 출력이 지연없이 동작 하는것을 확인 할 수 있다.
반응형