以MINISTM32的扩展实验26 fatfs为模板,想做一个通过usmart从串口接收文件存入SD卡的实验,用非DMA方式因为写SD卡时间较长,速度最多只能达到14400bps。为了加快速度,考虑DMA接收,开辟两块缓存,各200字节,写满一块就把dma存储地址改到另一块上继续DMA接收,同时把写满的缓存内容写入SD卡。
现在遇到的问题是,开启接收DMA后,第一次中断正常进入中断服务程序,但是之后,无论如何初始化DMA接收的寄存器设置(即使设置为与初始化相同的代码),也无法再进入中断,而且观察DMA1_Channel5->CNDTR的值,发现再收到一个字符就停止了。
更奇怪的是,在退出接收文件的代码后,调用uart_init(72,14400); 可恢复正常的usmart操作,再次开启文件传输功能时,还能再进一次中断,显然应该认为此时的DMA初始化成功。但在中断处理程序中调用uart_init(72,14400); 再操作DMA初始化则仍然无法第二次进入中断。
DMA初始化部分程序如下:
//串口1接收的DMA初始化
void MYDMA_rec_Conf(u32 cmar,u16 cndtr)
{
u32 DR_Base; //做缓冲用,不知道为什么.非要不可
RCC->AHBENR|=1<<0; //开启DMA1时钟
delay_ms(5);//加延时试试。
DR_Base=cmar;
// DMA1_MEM_LEN=cndtr; //保存DMA传输数据量
// DMA_CHx->CNDTR=cndtr; //DMA1,传输数据量
DMA1_Channel5->CNDTR=cndtr;
//DMA1_Channel5->CPAR=DR_Base; //DMA1 外设地址
DMA1_Channel5->CMAR=DR_Base; //DMA存储器地址
DMA1_Channel5->CPAR=(u32)&USART1->DR; //DMA1 外设地址
DMA1_Channel5->CCR=0X00000000; //复位
DMA1_Channel5->CCR &= ~(1<<4); //从外设读
DMA1_Channel5->CCR &= ~(1<<5); //普通模式,不执行循环操作
DMA1_Channel5->CCR &= ~(1<<6); //外设地址非增量模式
DMA1_Channel5->CCR |= 1<<7; //存储器增量模式
DMA1_Channel5->CCR &= ~(3<<8); //外设数据宽度为8位
DMA1_Channel5->CCR &= ~(3<<10); //存储器数据宽度8位
DMA1_Channel5->CCR |= 1<<12; //中等优先级
DMA1_Channel5->CCR &= ~(1<<14); //非存储器到存储器模式
//传输完成中断
DMA1_Channel5->CCR |= 1<<1; //允许传输完成中断
// DMA1_Channel5->CCR |= 1<<2; //允许半传输完成中断
MY_NVIC_Init(2,2,DMA1_Channel5_IRQChannel,2);//组2,最低优先级
}
void DMAChannel5_IRQHandler(void)
{
LED1=!LED1;
//以下为dma接收的代码
DMA1->IFCR|=1<<16; //清除通道5的全局中断标志
if (buffno==0)
{
DMA1_Channel5->CCR&=~(1<<0); //关闭DMA传输
USART1->CR3&=~(1<<6); //关闭uart1的dma接收
MYDMA_rec_Conf((u32)USDMA_RX_BUF[1],USART_REC_LEN);
USART1->CR3|=1<<6; //开启uart1的dma接收
DMA1_Channel5->CCR|=1<<0; //开启DMA传输
USART1->CR3|=1<<6; //开启uart1的dma接收
buffno=1;//切换到buff1的标志
mf_write(USDMA_RX_BUF[0],USART_REC_LEN);
}
else
{
DMA1_Channel5->CCR&=~(1<<0); //关闭DMA传输
USART1->CR3&=~(1<<6); //关闭uart1的dma接收
MYDMA_rec_Conf((u32)USDMA_RX_BUF[0],USART_REC_LEN);
USART1->CR3|=1<<6; //开启uart1的dma接收
DMA1_Channel5->CCR|=1<<0; //开启DMA传输
buffno=0;//切换到buff0
mf_write(USDMA_RX_BUF[1],USART_REC_LEN);
}
//以上为dma接收的代码
}
我已经焦头烂额了,不知道问题出在哪里,请各位高手指教! |