本篇文章将基于战舰V3的F103ZET6开发板,讲述如何把flash地址中存储的数据搬运到SRAM中,并通过串口在上位机显示出来
1.确定flash和sram的地址范围
这一点查阅手册资料很容易得到,偷懒的方法可以打开keil点击魔术棒工具,如下图,1ROM1中写的便是flash的起始地址0x08000000,大小0x80000;1RAM1中写的则是SRAM的起始地址0x20000000,大小0x10000。具体如下图
2.代码核心
这里主要是用到了DMA,在这里只需要把DMA配置好,就可以实现搬运了。一般会通过const常量定义把常量写入到flash中,但是本文是直接读取0x08000000地址开始的10个地址数据,写入到0x20001000的sram中。
注意!:sram的数据选择应稍微靠后一点,避免把程序中原有的变量覆盖
DMA.c
void M2M_DMA_Init(uint32_t len)
{
DMA_InitTypeDef DMA_InitStructure;
// 开启DMA2时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
DMA_Cmd(DMA2_Channel1, DISABLE);
DMA_DeInit(DMA2_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = ((uint32_t)(0x08000000)); //flash起始地址
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)(0x20001000); //接收地址,定义后默认在sram中某块
//外设到内存
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
//长度
DMA_InitStructure.DMA_BufferSize = len;
//外设地址增加
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
//内存地址自增
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
//外设、内存数据宽度
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
//一次模式
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
// 开启内存到内存的DMA模式
DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;
DMA_Init(DMA2_Channel1, &DMA_InitStructure); // 写入配置
DMA_ClearFlag(DMA2_FLAG_GL1); // 清除DMA所有标志
DMA_Cmd(DMA2_Channel1, ENABLE); // 开启接收DMA通道,等待接收数据
}
3.到这步以后,其实在main函数里调用M2M_DMA_Init(len)就已经能够实现len个长度的数据传输,但是为了更直观的显示,我们通过串口将数据打印在上位机上,uart的初始化用原子哥的就好
main.c
uint8_t receive[10];
int main()
{
USART1_Init(115200);
M2M_DMA_Init(10);
for(int i=0;i<10;i++)
{
receive[i]=*(u32*)(0x20001000+i);
printf("%c",receive[i]);
}
while(1)
{
//只传输一次
}
}
作者这里就传10个数据演示一下好了,定义一个u8数组,指向接收的地址,然后用重定义的printf打印在我们的上位机上,结果如图:
![](https://i-blog.csdnimg.cn/blog_migrate/6b3d5d46b02a54aff6d5ce43f63bf338.png)
![](https://i-blog.csdnimg.cn/blog_migrate/cc4c00f0ff16562e0f632445ed954e01.png)
可以看到数据是对应起来的
第一次写博文,如有不对,请批评指教