再来看看DMA中断:
//u16 DataCounter;
extern DMA_InitTypeDef DMA_InitStructure;
void DMA1_Channel5_IRQHandler(void)
{
if(DMA_GetITStatus(DMA1_IT_TC5)) //通道5传输完成中断TC 还有传输 过半中断HT 错误中断TE 全局中断GL
{
//DataCounter = DMA_GetCurrDataCounter(DMA1_Channel5);//获取剩余长度,一般都为0,调试用
DMA_ClearITPendingBit(DMA1_IT_GL5); //清除全部中断标志
//转换可操作BUF
if(Free_Buf_No==BUF_NO1)
{
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)USART1_DMA_Buf1;
DMA_Init(DMA1_Channel5, &DMA_InitStructure);
Free_Buf_No=BUF_NO2;
}
else
{
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)USART1_DMA_Buf2;
DMA_Init(DMA1_Channel5, &DMA_InitStructure);
Free_Buf_No=BUF_NO1;
}
Buf_Ok=TRUE; //有准备好的数据了
}
}
写FLASH的操作
while(1)
{
if(Buf_Ok==TRUE)
{
LED1_ON; //一个标记
Buf_Ok=FALSE; //操作了准备好的数据
if((addr@96)==0) //跨越一个扇区,则需要先刷除
{
SST25SectorErase(addr);
sector_count++;
}
if(Free_Buf_No==BUF_NO1)
SST25Write(addr,USART1_DMA_Buf1,512);
else
SST25Write(addr,USART1_DMA_Buf2,512);
addr+=512;
Timer1=5000; //时间重置
LED1_OFF;
}
//检测超时 开了 定时器
if(Timer1==0) //五秒内没准备好的数据
{
//获取长度
len=512-DMA_GetCurrDataCounter(DMA1_Channel5);
//写入最后数据
if(Free_Buf_No==BUF_NO1)
SST25Write(addr,USART1_DMA_Buf2,len);
else
SST25Write(addr,USART1_DMA_Buf1,len);
addr+=len;
break;
}
}
还是很简单的。
有一点比较困扰 就是 FlagStatus标志位 与 ITStatus中断标志位 的区别。 其实就 DMA 来说 DMA_IT值 与 DMA_FLAG值 是一样的
甚至2者值的获取 都是读 DMA ISR register 的值 清除也是设置 DMA_IFCR 寄存器来清除的所以貌似没有区别.........同理这个问题在别的中断也存在但我还不可保证 IT 与FLAG 的值总是相同的这个存在也许是为了兼容但一定有其意义务必不可混用即使有时用错也正确.....