本人为STM32初学者,请教各位大侠一个问题。
实现功能:用STM32实现DMA接收串口2数据,然后用LCD显示接收的数据。
遇到问题:我设置的是DMA传输完成中断,缓冲大小是512 bytes。但是串口每发送1个字节,就进入了一次DMA中断,甚是费解。不甚感激!!
我的代码如下:
//DMA目标缓冲,这里使用双缓冲
u8 USART2_DMA_Buf1[512] = NULL;
u8 USART2_DMA_Buf2[512] = NULL;
bool Buf_OK; //BUF是否已经可用
BUF_NO Free_BUf_NO; //空闲的BUF
DMA_InitTypeDef DMA_InitStructure;
//DMA初始化
void USART_DMAToBuf1(void)
{
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_DMA1, ENABLE); // open DMA clock
DMA_DeInit(DMA1_Channel6); //make the channel 6 default
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32) SRC_USART2_DR; //BUF is from &(USART2->DR)
DMA_InitStructure.DMA_MemoryBaseAddr = (u32) USART2_DMA_Buf1; // BUF is to USART2_DMA_Buf1
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // set peripheral is the source
DMA_InitStructure.DMA_BufferSize = 512; // the Buffer of DMA, and uint is set next
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //???è???·?????÷??????
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //???????·????
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; // the unit of peripheral is byte
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // the unit of memory is byte
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // worked in the circular model
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // it is not memory to memory
DMA_Init(DMA1_Channel6, &DMA_InitStructure); // initialize the dma
DMA_ITConfig( DMA1_Channel6, DMA_IT_TC, ENABLE);
/** DMA_ IT **/
USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE); //enable the usart2 reception Interruption
/** Init the BUF **/
Free_BUf_NO = BUF_NO2; //DMA_InitStructure.DMA_MemoryBaseAddr = (u32) USART2_DMA_Buf1;
Buf_OK = FALSE; //No data transmitting is completed
DMA_Cmd(DMA1_Channel6, ENABLE); //enable the dma
}
/*******************************************************************************
* Function Name : USART2 to DMA IT Handler
* Description : When DMA FULL,
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void DMA1_Channel6_IRQHandler(void)
{
DMA1_Channel6_IRQHandler_Next();
}
void DMA1_Channel6_IRQHandler_Next(void)
{
if(DMA_GetITStatus(DMA1_IT_TC6))
{
DataCounter = DMA_GetCurrDataCounter(DMA1_Channel6); /// for debug
DMA_ClearITPendingBit(DMA1_IT_GL6); //clear the whole flag
/**transfer the operatorial BUF**/
if(Free_BUf_NO == BUF_NO1)
{
DMA_InitStructure.DMA_MemoryBaseAddr = (u32) USART2_DMA_Buf1;
DMA_Init(DMA1_Channel6, &DMA_InitStructure);
Free_BUf_NO = BUF_NO2;
}
else
{
DMA_InitStructure.DMA_MemoryBaseAddr = (u32) USART2_DMA_Buf2;
DMA_Init(DMA1_Channel6, &DMA_InitStructure);
Free_BUf_NO = BUF_NO1;
}
Buf_OK = TRUE; // have the already data
}
}
//USART2中断处理函数
void USART2_IRQHandler(void)
{
USART2_ReceiveData(); //Send strings to STM32
}
//串口接收程序
void USART2_ReceiveData()
{
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
{
USART_ClearITPendingBit(USART2, USART_IT_RXNE);
USART2_DMA_Buf1[BufCounter] = (unsigned char)USART_ReceiveData(USART2);
BufCounter++;
}
}
int main()
{
System_Init();
USART_TO_FLASH_DMA_Init();
while(1)
{
if(Buf_OK == TRUE)
{
Buf_OK = FALSE; // operate the already data
while(1)
{
LCD_ClearScreen();
char lcd_str[32];
for(int i=0; i<32; i++)
{
lcd_str=USART2_DMA_Buf1;
}
LCD_DisplayString((char *)lcd_str);
Delay_xms(1000);
}
}
}
} |