STM32串口接收使用DMA双缓冲

#define IMAGE_BUFFER_SIZE 100  //以字为单位  经试验,增大这个数值速度并未提升

u32 Image_Buffer1[IMAGE_BUFFER_SIZE]={0};
u32 Image_Buffer2[IMAGE_BUFFER_SIZE]={0};

//OV2640 JPEG模式接口配置
void OV2640_JpegDcmiInit(void)
{
DCMI_InitTypeDef DCMI_InitStructure;
DMA_InitTypeDef  DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure; //NVIC
/*** Configures the DCMI to interface with the OV2640 camera module ***/
/* Enable DCMI clock */
RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_DCMI, ENABLE);

/* DCMI configuration */ 
DCMI_InitStructure.DCMI_CaptureMode = DCMI_CaptureMode_Continuous;//单张DCMI_CaptureMode_Continuous;
DCMI_InitStructure.DCMI_SynchroMode = DCMI_SynchroMode_Hardware;
DCMI_InitStructure.DCMI_PCKPolarity = DCMI_PCKPolarity_Rising;//
DCMI_InitStructure.DCMI_VSPolarity = DCMI_VSPolarity_Low;
DCMI_InitStructure.DCMI_HSPolarity = DCMI_HSPolarity_Low;
DCMI_InitStructure.DCMI_CaptureRate = DCMI_CaptureRate_All_Frame;
DCMI_InitStructure.DCMI_ExtendedDataMode = DCMI_ExtendedDataMode_8b;
//初始化DCMI
DCMI_Init(&DCMI_InitStructure);
//使能JPG
DCMI_JPEGCmd(ENABLE);

/* Configures the DMA2 to transfer Data from DCMI */
/* Enable DMA2 clock */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);

/* DMA2 Stream1 Configuration */  
DMA_DeInit(DMA2_Stream1);

DMA_InitStructure.DMA_Channel = DMA_Channel_1;  
DMA_InitStructure.DMA_PeripheralBaseAddr = DCMI_DR_ADDRESS;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&Image_Buffer1;//传输到内部数组
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = IMAGE_BUFFER_SIZE; //以字为单位
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//使能增长模式
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;//DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
/*DMA double buffer mode*///双缓冲区模式
DMA_DoubleBufferModeConfig(DMA2_Stream1,(uint32_t)&Image_Buffer2,DMA_Memory_0);//DMA_Memory_0首先被传输
DMA_DoubleBufferModeCmd(DMA2_Stream1,ENABLE);
DMA_Init(DMA2_Stream1, &DMA_InitStructure); //初始化DMA

Dma_FreeBuf_Ok = 0;//此时没有数据准备完成
// DMA_Cmd(DMA2_Stream1,ENABLE);//启动DMA2_Stream1

//中断使能
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel = DCMI_IRQn; 
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; 
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; 
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
NVIC_Init(&NVIC_InitStructure); 
DCMI_ITConfig(DCMI_IT_FRAME,ENABLE); //中断使能

NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA_ITConfig(DMA2_Stream1,DMA_IT_TC,ENABLE);
}

//DMA传输完成中断
void DMA2_Stream1_IRQHandler(void)
{
DMA_InitTypeDef DMA_InitStructure;
if(DMA_GetITStatus(DMA2_Stream1,DMA_IT_TCIF1) != RESET)
{
DMA_ClearITPendingBit(DMA2_Stream1,DMA_IT_TCIF1);
Dma_FreeBuf_Ok = 1;//有准备好的数据了
}
}


//主循环
while(1)
{
//uip_polling();
if(Dma_FreeBuf_Ok == 1)//DMA有空闲缓冲区了
{
usart_sendJPEGdata();
Dma_FreeBuf_Ok = 0;
}


//串口传输
void usart_sendJPEGdata(void)
{
u32 i;
if(DMA_GetCurrentMemoryTarget(DMA2_Stream1) == 1)
{
for(i=0;i<IMAGE_BUFFER_SIZE;i++)
{
USART_SendData(USART2,Image_Buffer1 );
while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
USART_SendData(USART2,Image_Buffer1>>8);
while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
USART_SendData(USART2,Image_Buffer1>>16);
while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
USART_SendData(USART2,Image_Buffer1>>24);
while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
}
}
else
{
for(i=0;i<IMAGE_BUFFER_SIZE;i++)
{
USART_SendData(USART2,Image_Buffer2);
while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
USART_SendData(USART2,Image_Buffer2>>8);
while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
USART_SendData(USART2,Image_Buffer2>>16);
while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
USART_SendData(USART2,Image_Buffer2>>24);
while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
}
}
}
  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个早起的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值