打印
[STM32F0]

把FLASH1的数据拷贝到SPI2上

[复制链接]
1022|24
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
happy_10|  楼主 | 2021-1-4 19:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
两块FLASH分别接到片子的SPI1与SPI2上面,现在想把FLASH1的数据拷贝到SPI2上。

使用特权

评论回复
沙发
stly| | 2021-1-4 19:44 | 只看该作者
你有什么打算呢?或者你想知道什么?

使用特权

评论回复
板凳
happy_10|  楼主 | 2021-1-4 19:51 | 只看该作者
目前想采用DMA实现数据拷贝,即SPI1从FLASH读数据,然后SPI2把数据写到FLASH2上。

使用特权

评论回复
地板
happy_10|  楼主 | 2021-1-4 19:56 | 只看该作者
DMA寄存器到寄存器的模式, 中间不进过缓存的过渡。不知道这种是否可以实现。

使用特权

评论回复
5
dingy| | 2021-1-4 19:56 | 只看该作者
完全可以。

使用特权

评论回复
6
pengf| | 2021-1-4 20:01 | 只看该作者

//SPI1: PA5--SCK  PA7--MOSI
//SPI2: PB13--SCK  PB15--MOSI
//SPI1--Master  SPI2--Slave
//SPI1发送数据到SPI1的数据寄存器   然后SPI2数据寄存器中如果有数据的时候会发出DMA请求  接着DMA把数据搬到内部寄存器SPI2_Buffer_Rx[BufferSize]中
//SPI1用DMA1_Channel3传送数据  时钟速率达到36M/s ,SPI2用DMA1_Channel4传送 最大速率达18M/s
#include"stm32f10x.h"
#define BufferSize  50
#define SPI2_DR_Addr  0x4000380c
#define SPI1_DR_Addr  0x4001300c
uint8_t Idex=0;
typedef enum {FAILED=0,PASSED=!FAILED}TextStatus;
uint16_tSPI1_Buffer_Tx[BufferSize]={0x0102,0x0203,0x0304,0x0405,0x0506,0x0607,0x0708,0x0809,0x090a,0x0a0b,
                                                                             0x0102,0x0203,0x0304,0x0405,0x0506,0x0607,0x0708,0x0809,0x090a,0x0a0b,
                                                                             0x0102,0x0203,0x0304,0x0405,0x0506,0x0607,0x0708,0x0809,0x090a,0x0a0b,
                                                                             0x0102,0x0203,0x0304,0x0405,0x0506,0x0607,0x0708,0x0809,0x090a,0x0a0b,
                                                                             0x0102,0x0203,0x0304,0x0405,0x0506,0x0607,0x0708,0x0809,0x090a,0x0a0b
                                     };
uint16_t SPI2_Buffer_Rx[BufferSize];
volatile TextStatus textstatus=FAILED;
void RCC_Config(void);
void GPIO_Config(void);
void DMA_Config(void);
void SPI_Config(void);
TextStatus TempComp(uint16_t*temp1,uint16_t* temp2,uint16_t length);
int main(void)
{
RCC_Config();
GPIO_Config();
DMA_Config();
SPI_Config();
while(1);
}
void RCC_Config(void)
{
//RCC_PCLK2Config(RCC_HCLK_Div2);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_SPI1,ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
}
void GPIO_Config(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB,&GPIO_InitStructure);
}
void DMA_Config(void)
{
  DMA_InitTypeDef DMA_InitStructure;
  DMA_DeInit(DMA1_Channel4);
  DMA_InitStructure.DMA_PeripheralBaseAddr=(uint32_t)SPI2_DR_Addr;
  DMA_InitStructure.DMA_MemoryBaseAddr=(uint32_t)SPI2_Buffer_Rx;
  DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_BufferSize=BufferSize;
  DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode=DMA_Mode_Normal;
  DMA_InitStructure.DMA_Priority=DMA_Priority_High;
  DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;
  DMA_Init(DMA1_Channel4,&DMA_InitStructure);
  DMA_DeInit(DMA1_Channel3);
  DMA_InitStructure.DMA_PeripheralBaseAddr=(uint32_t)SPI1_DR_Addr;
   DMA_InitStructure.DMA_MemoryBaseAddr=(uint32_t)SPI1_Buffer_Tx;
  DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralDST;
  DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_BufferSize=BufferSize;
  DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode=DMA_Mode_Normal;
  DMA_InitStructure.DMA_Priority=DMA_Priority_High;
  DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;
  DMA_Init(DMA1_Channel3,&DMA_InitStructure);
  DMA_Cmd(DMA1_Channel3,ENABLE);
  DMA_Cmd(DMA1_Channel4,ENABLE);
}
void SPI_Config(void)
{
  SPI_InitTypeDef SPI_InitStructure;
  SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_Mode=SPI_Mode_Master;
  SPI_InitStructure.SPI_DataSize=SPI_DataSize_16b;
  SPI_InitStructure.SPI_CPOL=SPI_CPOL_Low;
  SPI_InitStructure.SPI_CPHA=SPI_CPHA_1Edge;
   SPI_InitStructure.SPI_NSS=SPI_NSS_Soft;
  SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_2;
  SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial=7;
  SPI_Init(SPI1,&SPI_InitStructure);
  SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_Mode=SPI_Mode_Slave;
  SPI_Init(SPI2,&SPI_InitStructure);
  SPI_Cmd(SPI1,ENABLE);
  SPI_Cmd(SPI2,ENABLE);
  SPI_I2S_DMACmd(SPI2,SPI_I2S_DMAReq_Rx,ENABLE);
  SPI_I2S_DMACmd(SPI1,SPI_I2S_DMAReq_Tx,ENABLE);
   /*
  while(Idex < BufferSize)
   {
         while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);
         SPI_I2S_SendData(SPI1,SPI1_Buffer_Tx[Idex++]);
         //SPI1只管发送数据然后 如果SPI2数据寄存器中数据满的话 会发出DMA请求接着DMA干活
         while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE)==RESET);
         SPI2_Buffer_Rx[Idex++]=SPI_I2S_ReceiveData(SPI2);
   }
   */
  while(DMA_GetFlagStatus(DMA1_FLAG_TC3)==RESET);
  while(DMA_GetFlagStatus(DMA1_FLAG_TC4)==RESET);
  textstatus=TempComp(SPI1_Buffer_Tx,SPI2_Buffer_Rx,BufferSize);
}
TextStatus TempComp(uint16_t*temp1,uint16_t* temp2,uint16_t length)
{
while(length--)
  {
  if(*temp1 != *temp2)
   {
         return FAILED;
   }
  temp1++;
  temp2++;
  }
  return PASSED;
}
——————————————

使用特权

评论回复
7
pengf| | 2021-1-4 20:07 | 只看该作者
网上找了个,你看看能用不。既然有,肯定可以。

使用特权

评论回复
8
happy_10|  楼主 | 2021-1-4 20:18 | 只看该作者
DMA转换完成后必然要进完成中断,这时候我就必须重新使能和加载地址。毕竟寄存器到寄存器每次只能半个字转换,而我需要拷贝的数据>65535,DMA中断也就会大量消耗调CPU资源?

使用特权

评论回复
9
renyaq| | 2021-1-4 20:18 | 只看该作者

重新使能、加载,很耗时吗?
何况65536才中断一次。

使用特权

评论回复
10
xxrs| | 2021-1-4 20:21 | 只看该作者

思路没问题,
具体操作会有情况。

使用特权

评论回复
11
houcs| | 2021-1-4 20:24 | 只看该作者

SPI1和SPI2之间可能做不到,
但SPI2和SPI3之间能做到。

使用特权

评论回复
12
happy_10|  楼主 | 2021-1-4 20:30 | 只看该作者
感谢回复。
DMA控制寄存器到寄存器的通信我一直卡在一个问题上,在没有CPU参与下,就是SPI2怎么知道SPI1已经读取完成呢?
最初的思路是SPI2->DR指向SPI1->DR,中间不损耗内存

使用特权

评论回复
13
happy_10|  楼主 | 2021-1-4 20:34 | 只看该作者
目前开了一个两级的BUFF,一边读一边写。调完LZ贴代码

使用特权

评论回复
14
yinxiangh| | 2021-1-4 20:38 | 只看该作者
我也要DMA实现SPI1与SPI2通信,你开发的程序能够帖出来,让我学习一下

使用特权

评论回复
15
houcs| | 2021-1-4 20:41 | 只看该作者
自己做数组复制就行

使用特权

评论回复
16
chenjunt| | 2021-1-4 20:44 | 只看该作者
楼主哪里不会做呀?

使用特权

评论回复
17
guoyt| | 2021-1-4 20:53 | 只看该作者
用普通模式也可以

使用特权

评论回复
18
langgq| | 2021-1-4 20:56 | 只看该作者
其实就是从这个串口到那个串口的问题  不要复杂化

使用特权

评论回复
19
happy_10|  楼主 | 2021-1-4 21:00 | 只看该作者
唉,还是没有什么结果,算了,多谢大家啦

使用特权

评论回复
20
labasi| | 2021-2-1 22:45 | 只看该作者
可以实现 楼主想问怎么写代码?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

744

主题

7973

帖子

6

粉丝