DMA 中断状态寄存器(DMA_ISR)
我们如果开启了 DMA_ISR 中这些中断,在达到条件后就会跳到中断服务函数里面去,即使 没开启,我们也可以通过查询这些位来获得当前 DMA 传输的状态。
这里我们常用的是 TCIFx, 即通道 DMA 传输完成与否的标志。注意此寄存器为只读寄存器,所以在这些位被置位之后,只 能通过其他的操作来清除
【图上说的写1清除???】
DMA 中断标志清除寄存器(DMA_IFCR)
DMA_IFCR 的各位就是用来清除 DMA_ISR 的对应位的,通过写 0 清除。在 DMA_ISR 被置位后, 我们必须通过向该位寄存器对应的位写入 0 来清除。
DMA 通道 x 配置寄存器(DMA_CCRx)是 DMA 传输的核心控制寄存器
DMA 通道 x 传输数据量寄存器(DMA_CNDTRx)
其设置范围为 0~65535。并且该寄存器的值会随着传输的进行而减少, 当该寄存器的值为 0 的时候就代表此次数据传输已经全部发送完成了。可以通过这个寄存 器的值来知道当前 DMA 传输的进度
DMA 通道 x 的外设地址寄存器(DMA_CPARx)
比如我们使用串口 1,那么该寄存器必须写入 0x40013804(其实就是&USART1_DR)。如果使 用其他外设,就修改成相应外设的地址就行
DMA 通道 x 的存储器地址寄存器(DMA_CMARx
用来放存储器的地址的。比如我们使用 SendBuf[5200]数组来做存储器,那么我们在 DMA_CMARx 中写入&SendBuff 就可以了
j=sizeof(TEXT_TO_SEND);
for(i=0;i<SEND_BUF_SIZE;i++)//填充数据到SendBuff
{
if(t>=j)//加入换行符
{
if(mask)
{
SendBuff[i]=0x0a;
t=0;
}else
{
SendBuff[i]=0x0d;
mask++;
}
}else//复制TEXT_TO_SEND语句
{
mask=0;
SendBuff[i]=TEXT_TO_SEND[t];
t++;
}
}
POINT_COLOR=BLUE;//设置字体为蓝色
i=0;
while(1)
{
t=KEY_Scan(0);
if(t==KEY0_PRES)//KEY0按下
{
LCD_ShowString(30,150,200,16,16,"Start Transimit....");
LCD_ShowString(30,170,200,16,16," %");//显示百分号
printf("\r\nDMA DATA:\r\n");
USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE); //使能串口1的DMA发送
MYDMA_Enable(DMA1_Channel4);//开始一次DMA传输!
//等待DMA传输完成,此时我们来做另外一些事,点灯
//实际应用中,传输数据期间,可以执行另外的任务
while(1)
{
if(DMA_GetFlagStatus(DMA1_FLAG_TC4)!=RESET) //判断通道4传输完成
{
DMA_ClearFlag(DMA1_FLAG_TC4);//清除通道4传输完成标志
break;
}
pro=DMA_GetCurrDataCounter(DMA1_Channel4);//得到当前还剩余多少个数据
pro=1-pro/SEND_BUF_SIZE;//得到百分比
pro*=100; //扩大100倍
LCD_ShowNum(30,170,pro,3,16);
}
LCD_ShowNum(30,170,100,3,16);//显示100% (2)
LCD_ShowString(30,150,200,16,16,"Transimit Finished!");//提示传送完成
}
i++;
delay_ms(10);
if(i==20)
{
LED0=!LED0;//提示系统正在运行
i=0;
}
}
}
(1)
如果mask=1,说明已经赋回车符0x0d,此时只需赋换行符0x0a
else mask=0,先赋回车符,再mask+1,即等于1,执行赋0x0a
回车换行符包含两个字符"\r\n",即先“回车”光标回到行首,再通过“换行”新起一行,
0x0d;是Windows系统中定义的控制字符,表示光标回到行首,也有当前行确认完成的意思,但它不起换行作用
0x0a才是表示换行的控制符。
在Windows系统中,我们按键盘上的回车键时,系统接收到的其实有0x0d0x0a两个控制字符,所以显示出来就有换行功能,但不要认为回车符就包含了换行作用。
(2)
第三个字符串长度如何确定?第四个和第五个为字体大小,为什么唯独这里是3,16???
待实践。