网站标题 空格,网站规划与建设进度,专业团队的优势,微网站如何做微信支付宝支付宝支付本文章仅仅简单记录32单片机的SPIDMA驱动显示屏的性能测试#xff0c;这里不花费时间介绍SPI和DMA。 硬件材料#xff1a;SPI显示屏一个#xff0c;32单片机 软件材料#xff1a; 1.LCD的SPI驱动显示程序#xff08;SPI / SPIDMA#xff09;#xff1a; #xff08;1DMA驱动显示屏的性能测试这里不花费时间介绍SPI和DMA。 硬件材料SPI显示屏一个32单片机 软件材料 1.LCD的SPI驱动显示程序SPI / SPIDMA 1SPI的配置程序
SPI_HandleTypeDef SPI3_Handler; //create a SPI handle
/*** brief SPI3 master mode* param void* return void*/
void SPI3_Init(void)
{SPI3_Handler.InstanceSPI3; SPI3_Handler.Init.ModeSPI_MODE_MASTER; SPI3_Handler.Init.DirectionSPI_DIRECTION_2LINES; SPI3_Handler.Init.DataSizeSPI_DATASIZE_8BIT; SPI3_Handler.Init.CLKPolaritySPI_POLARITY_HIGH; //Idle state clock is highSPI3_Handler.Init.CLKPhaseSPI_PHASE_2EDGE; SPI3_Handler.Init.NSSSPI_NSS_SOFT; SPI3_Handler.Init.BaudRatePrescalerSPI_BAUDRATEPRESCALER_2;//baudrate is highestSPI3_Handler.Init.FirstBitSPI_FIRSTBIT_MSB; SPI3_Handler.Init.TIModeSPI_TIMODE_DISABLE; SPI3_Handler.Init.CRCCalculationSPI_CRCCALCULATION_DISABLE;SPI3_Handler.Init.CRCPolynomial7; //omitHAL_SPI_Init(SPI3_Handler);__HAL_SPI_ENABLE(SPI3_Handler);
}/*** brief SPI3 lower driver configperip clock io* param hspi: the SPI handle pointer should be use* return void*/
void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
{GPIO_InitTypeDef GPIO_Initure;__HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_SPI3_CLK_ENABLE(); GPIO_Initure.PinGPIO_PIN_3|GPIO_PIN_5;GPIO_Initure.ModeGPIO_MODE_AF_PP; GPIO_Initure.PullGPIO_PULLUP; GPIO_Initure.SpeedGPIO_SPEED_FREQ_VERY_HIGH; GPIO_Initure.AlternateGPIO_AF6_SPI3; HAL_GPIO_Init(GPIOB,GPIO_Initure);
}2SPI的读写接口非DMA情况下需要使用到
/*** brief SPI3 R/W one octet* param TxData the u8 data which should be writed* return the u8 data received*/
u8 SPI3_ReadWriteByte(u8 TxData)
{u8 Rxdata;HAL_SPI_TransmitReceive(SPI3_Handler,TxData,Rxdata,1, 1000); return Rxdata;
}/*** brief SPI3 Write one octet* param TxData the tx payload* param size payload length* return u8 0:success,others:fail*/
u8 SPI3_WriteByte(u8 *TxData,u16 size)
{return HAL_SPI_Transmit(SPI3_Handler,TxData,size,1000);
}3SPI的DMA配置初始化 我使用的是Stm32L4做SPI3DMA的测试首先看芯片手册DMA相关的内容 上面的表格罗列了DMA2每个通道的DMA请求SPI3_Tx对应通道2请求30011那么我们可以这样配置SPI3的DMA通道
void vidSPI3DMA_Config(void)
{__HAL_RCC_DMA2_CLK_ENABLE();//DMA2 Clock Enable__HAL_LINKDMA(SPI3_Handler, hdmatx, SPI3TxDMA_Handler); //Link DMA to SPI3, here we use the dma tx function//Tx Dma configSPI3TxDMA_Handler.Instance DMA2_Channel2; //select the channelSPI3TxDMA_Handler.Init.Request DMA_REQUEST_3; //request(CxS:0011)SPI3TxDMA_Handler.Init.Direction DMA_MEMORY_TO_PERIPH; //memory to peripheralSPI3TxDMA_Handler.Init.PeriphInc DMA_PINC_DISABLE; //peripheral not incrementSPI3TxDMA_Handler.Init.MemInc DMA_MINC_ENABLE; //memory inc SPI3TxDMA_Handler.Init.PeriphDataAlignment DMA_PDATAALIGN_BYTE; //perip data length:8 bitSPI3TxDMA_Handler.Init.MemDataAlignment DMA_MDATAALIGN_BYTE; //mem data length:8 bitSPI3TxDMA_Handler.Init.Mode DMA_NORMAL; SPI3TxDMA_Handler.Init.Priority DMA_PRIORITY_HIGH; SPI3TxDMA_Handler.State HAL_DMA_STATE_READY;HAL_DMA_DeInit(SPI3TxDMA_Handler);HAL_DMA_Init(SPI3TxDMA_Handler);HAL_NVIC_SetPriority(DMA2_Channel2_IRQn, 0, 3);HAL_NVIC_EnableIRQ(DMA2_Channel2_IRQn);
}
4使用DMA中断需要调用DMA中断函数去清除相关中断标志位。
/** brief: DMA2 Channel2 IRQ handler function* mainly clear the interrupt flag
*/
void DMA2_Channel2_IRQHandler(void)
{HAL_DMA_IRQHandler(SPI3TxDMA_Handler);
}/** brief: After Tx is completed, the SPI DMA should be stopped for next transfer
*/
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{HAL_SPI_DMAStop(hspi);
}2.LCD显示驱动程序 1LCD基于SPI的数据发送接口
/*** brief LCD SPI send data API* return void*/
#define NO_USING_DMA 1
static void LCD_SPI_Send(u8 *data, u32 size)
{
#if NO_USING_DMAu32 i;u32 delta size/0xFFFF;for(i 0; idelta; i){if( idelta ) /* Send the last data */SPI3_WriteByte(data[i*0xFFFF], size%0xFFFF);//cause this API 2nd param is u16 typeelse /* send 0xFFFF octets */SPI3_WriteByte(data[i*0xFFFF], 0xFFFF);}
#elsewhile(SPI3_Handler.State ! HAL_SPI_STATE_READY);HAL_SPI_Transmit_DMA(SPI3_Handler, data, size);
#endifreturn;
}往LCD写任何数据都是用的这个接口LCD_SPI_Send。关于图片的绘制的函数这里不多余贴出来相信网上一大把程序可以参考这里直接使用定时器去了解不开DMA和开DMA显示同一张图片耗时差异时间从串口打印出来 u32 t0;printf(Show a 240X82 picture,Start: %d | , t);vidEnableTIM3(1);//enable TIM3,and clear the counterDisplay_240x82_pic(0, 0);t u32GetTim3Counter();printf(End: %d\r\n, t);这里我定时器计数频率分频到1Mhz最大计数50000次也是就计数频率1us周期50ms。 第一次我是以SPIDMA驱动LCD显示240X82的图片可以看出显示该图片在有DMA加DMA中断的加持下耗时156us。第二次是我单独用SPI驱动LCD显示240X82的图片耗时8685us所以区别还是蛮大的。