这两天用STM32的DMA接收USART1的数据,USART1接的是GSM模块。
开机启动后,我要配置GSM模块,于是给模块发一些配置指令如下:
void GSM_Config(void)
{
USART1_Send_Str("AT+IPR=0\n");
delay_ms(20);
USART1_Send_Str("AT&W\n");
delay_ms(20);
USART1_Send_Str("AT+CSCS=\"GSM\"\n");
delay_ms(20);
USART1_Send_Str("AT+CMGF=1\n"); //
delay_ms(20);
USART1_Send_Str("AT+CSCS=\"UCS2\"\n"); //
delay_ms(20);
USART1_Send_Str("AT+CSMP=49,167,0,25\n");
delay_ms(20);
}
发这些指令配置模块的时候,每给模块发一条指令,模块会通过USART1返回一些数据,这时DMA都能接收到。
然后我就进入一个死循环(如下),等待GSM模块发来的数据。(此时我用另一个手机给这个GSM模块发信息,模块会马上把数据通过串口传给STM32)
while(1)
{
\\ test = USART1->DR;
test = USART1_DMA_Buf1[204]; //之前buf里已经写了204个数据,新数据从第204开始写入。
}
进入死循环后,试了好多次发信息给模块,DMA都没有把数据传到buf里,而且连USART1->DR这个寄存器里都没有新数据。
但是奇怪的是,如果我在GSM_Config()这个函数里设一个断点,然后再继续运行进入死循环后,就能接收到模块发来的数据。此时DMA也正常工作。
如果启动后不在那个函数里设断点,而是直接进入死循环,就不会收到串口数据,好像串口、DMA都没正常工作一样。好奇怪啊
是不是仿真的问题啊?好费解。我用的软件是keil4,JLINK仿真
跪求指点。。。都郁闷了。。
下面是我DMA的配置,应该是没有问题的
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); //使能DMA时钟
DMA_DeInit(DMA1_Channel5);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)SRC_USART1_DR; //源头BUF
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)USART1_DMA_Buf1; //目标BUF
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //外设作为源头
DMA_InitStructure.DMA_BufferSize = dma_len; //BUF大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不递增
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址递增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设字节为单位
DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte; //内存字节为单位
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //循环模式
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //4优先级之一的(高优先)
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //非内存到内存
DMA_Init(DMA1_Channel5,&DMA_InitStructure);
DMA_ITConfig(DMA1_Channel5,DMA_IT_TC,ENABLE); //DMA5传输完成中断
USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE); //使能串口接收DMA
DMA_Cmd(DMA1_Channel5,ENABLE); //使能DMA |