7475|6

337

帖子

0

TA的资源

纯净的硅(初级)

楼主
 

各位请教了,STM32CUBEMX+SPI+DMA 方式始终发送不对,我的芯片STM32F103RC [复制链接]

SPI及DMA初始化都是STM32CUBEMX自动生成的。外部存储器是LY68L6400.我用HAL_SPI_Transmit(&hspi2,(uint8_t * )TX_data, 1020, 0xfffffff);

函数向存储器写数,然后用函数HAL_SPI_Receive(&hspi2, (uint8_t * )RX_data, 1024, 0XFFFFF);

读出来是对的,但是用HAL_SPI_Transmit_DMA(&hspi2, (uint8_t *)AD_VALUE_Buff1,1020);

写进去,然后用HAL_SPI_Receive(&hspi2, (uint8_t * )RX_data, 1024, 0XFFFFF);

读出来的数据就不对了。究竟哪个地方有问题呢?

此帖出自stm32/stm8论坛

最新回复

你可以查看一下hspi2和spi2对应的dma结构体的state,是否有错误再分析原因,是不是dma没完成你就去Receive了   详情 回复 发表于 2020-7-22 01:15
点赞 关注
 

回复
举报

7462

帖子

2

TA的资源

五彩晶圆(高级)

沙发
 

上代码。猜不出来你的具体动作。

此帖出自stm32/stm8论坛
 
个人签名

默认摸鱼,再摸鱼。2022、9、28

 

回复

310

帖子

5

TA的资源

一粒金砂(中级)

板凳
 

cubemx的ioc文件上传,这样才可以知道你怎么配置

此帖出自stm32/stm8论坛
 
 

回复

4005

帖子

0

TA的资源

版主

4
 

你可以查看一下hspi2和spi2对应的dma结构体的state,是否有错误再分析原因,是不是dma没完成你就去Receive了

此帖出自stm32/stm8论坛
 
 
 

回复

337

帖子

0

TA的资源

纯净的硅(初级)

5
 

谢谢各位,我是用CUBE自动生成的,代码首先程序初始化

int main(void)
{
  /* USER CODE BEGIN 1 */
#if (OS_TASK_NAME_EN > 0u)
CPU_INT08U os_err;
#endif
    OS_CPU_SR  cpu_sr;
  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_TIM2_Init();
  MX_SPI2_Init();
  /* USER CODE BEGIN 2 */
    HAL_SPI_TransmitReceive_DMA(&hspi2, (uint8_t *)AD_VALUE_Buff1, (uint8_t* )RX_data,1024);//象串口收发一样初始SPI
 LY68_Data_init_Test();//初始我的接收测试数组

然后在进入任务处开始接收测试

void Task_One(void *p_arg)//优先级最高的任务
{
    OS_CPU_SR cpu_sr=0;
    p_arg=p_arg;
  u32 Writ_Add; 
    Writ_Add=YL68Mem.Star_add;  //外设起始地址,我是从02开始,但是从00开始一样不对 
     HAL_GPIO_WritePin(NSS_GPIO_Port, NSS_Pin, GPIO_PIN_RESET);//拉低外设片选
     LY68_Write_Page_writ(Writ_Add);//开始写

    delay_us(5);
     HAL_GPIO_WritePin(NSS_GPIO_Port, NSS_Pin, GPIO_PIN_SET);
     delay_us(5);
     HAL_GPIO_WritePin(NSS_GPIO_Port, NSS_Pin, GPIO_PIN_RESET);
     delay_us(10);
     LY68_Read_Page_writ(); //开始读
     delay_us(10);
     HAL_GPIO_WritePin(NSS_GPIO_Port, NSS_Pin, GPIO_PIN_SET) 
  while(1)//进入任务循环
    {       

 

//下面是我的具体读写程序

写。。

void LY68_Write_Page_writ(u32 Write_Start_Addr )
{
  u16 Len;
    Write_Start_Addr=0;   //写地址
    Send_Write_Command(LY_SPI_Write_COMMAND);   //发02写命令
    SPI2_ReadWriteByte((u8)((Write_Start_Addr)>>16));//地址 23:16  ·
    SPI2_ReadWriteByte((u8)((Write_Start_Addr)>>8)); //地址 15:8   
    SPI2_ReadWriteByte((u8)(Write_Start_Addr));      //地址 15:8     
   HAL_SPI_TransmitReceive_DMA(&hspi2, (uint8_t *)AD_VALUE_Buff1, (uint8_t* )RX_data,1024);
   //HAL_SPI_Transmit(&hspi2, (uint8_t *)AD_VALUE_Buff1,1024,0XFFFF);//用这个就对
    return;
}   

//读     

void LY68_Read_Page_writ()
{
    u16 Read_ADDR;
    Read_ADDR=0;
    Send_Write_Command(LY_SPI_Fast_Read_COMMAND); //·发读命令
    SPI2_ReadWriteByte((u8)((Read_ADDR)>>16));//µØÖ·  23:16   //·¢ËͶÁÊý¾ÝÆðʼµØÖ·
    SPI2_ReadWriteByte((u8)((Read_ADDR)>>8)); //µØÖ·  15:8    
    SPI2_ReadWriteByte((u8)(Read_ADDR));      //µØÖ·  15:8
    HAL_SPI_TransmitReceive(&hspi2, (uint8_t *)AD_VALUE_Buff1, (uint8_t* )RX_data,1020,0XFFFFF);
    //HAL_SPI_Receive_IT(&hspi2,(uint8_t* )RX_data, 1020);
}        

 

SPI及DMA初始化。。。。。

void MX_SPI2_Init(void)
{

  hspi2.Instance = SPI2;
  hspi2.Init.Mode = SPI_MODE_MASTER;
  hspi2.Init.Direction = SPI_DIRECTION_2LINES;
  hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi2.Init.NSS = SPI_NSS_SOFT;
  hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
  hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi2.Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(&hspi2) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}///////////*********************************************

 

void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct;
  if(spiHandle->Instance==SPI2)
  {
  /* USER CODE BEGIN SPI2_MspInit 0 */

  /* USER CODE END SPI2_MspInit 0 */
    /* SPI2 clock enable */
    __HAL_RCC_SPI2_CLK_ENABLE();
  
    /**SPI2 GPIO Configuration    
    PB13     ------> SPI2_SCK
    PB14     ------> SPI2_MISO
    PB15     ------> SPI2_MOSI 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_15;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_14;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* SPI2 DMA Init */
    /* SPI2_RX Init */
    hdma_spi2_rx.Instance = DMA1_Channel4;
    hdma_spi2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_spi2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_spi2_rx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_spi2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_spi2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_spi2_rx.Init.Mode = DMA_NORMAL;
    hdma_spi2_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
    if (HAL_DMA_Init(&hdma_spi2_rx) != HAL_OK)
    {
      _Error_Handler(__FILE__, __LINE__);
    }

    __HAL_LINKDMA(spiHandle,hdmarx,hdma_spi2_rx);

    /* SPI2_TX Init */
    hdma_spi2_tx.Instance = DMA1_Channel5;
    hdma_spi2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdma_spi2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_spi2_tx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_spi2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_spi2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_spi2_tx.Init.Mode = DMA_NORMAL;
    hdma_spi2_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
    if (HAL_DMA_Init(&hdma_spi2_tx) != HAL_OK)
    {
      _Error_Handler(__FILE__, __LINE__);
    }

    __HAL_LINKDMA(spiHandle,hdmatx,hdma_spi2_tx);

  /* USER CODE BEGIN SPI2_MspInit 1 */

  /* USER CODE END SPI2_MspInit 1 */
  }
}

此帖出自stm32/stm8论坛
 
 
 

回复

337

帖子

0

TA的资源

纯净的硅(初级)

6
 

我现在DMA用寄存器方式控制,不过看了手册以及参考了网上资料感觉还没有没有启动得了DMA方式,这个SPI的DMA方式到底怎么启动呢?下面是我的代码

void TX_MYDMA_Config(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)//发送设置
{
    RCC->AHBENR|=1<<0;               //¿ªÆôDMA1ʱÖÓ
    delay_ms(5);                      //µÈ´ýDMAʱÖÓÎȶ¨
    DMA_CHx->CPAR=cpar;            //DMA1 ÍâÉèµØÖ· 
    DMA_CHx->CMAR=(u32)cmar;     //DMA1,´æ´¢Æ÷µØÖ·
    DMA1_MEM_LEN=cndtr;          //±£´æDMA´«ÊäÊý¾ÝÁ¿
    DMA_CHx->CNDTR=cndtr;        //DMA1,´«ÊäÊý¾ÝÁ¿
    DMA_CHx->CCR=0X00000000;    //¸´Î»
    DMA_CHx->CCR|=1<<4;          //´Ó´æ´¢Æ÷¶Á
    DMA_CHx->CCR|=0<<5;          //ÆÕͨģʽ
    DMA_CHx->CCR|=0<<6;         //ÍâÉèµØÖ··ÇÔöÁ¿Ä£Ê½
    DMA_CHx->CCR|=1<<7;          //´æ´¢Æ÷ÔöÁ¿Ä£Ê½
    DMA_CHx->CCR|=0<<8;          //ÍâÉèÊý¾Ý¿í¶ÈΪ8λ
    DMA_CHx->CCR|=0<<10;         //´æ´¢Æ÷Êý¾Ý¿í¶È8λ
    DMA_CHx->CCR|=1<<12;         //ÖеÈÓÅÏȼ¶
    DMA_CHx->CCR|=0<<14;         //·Ç´æ´¢Æ÷µ½´æ´¢Æ÷ģʽ        
  DMA_CHx->CCR|=1<<1;    //¿ªÆô´«ÊäÍê³ÉÖжϠ   

//开启一次DMA传输
void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx)
{
    DMA_CHx->CCR&=~(1<<0);       //¹Ø±ÕDMA´«Êä 
    DMA_CHx->CNDTR&= 0x0000;
    DMA_CHx->CNDTR=DMA1_MEM_LEN; //DMA1,´«ÊäÊý¾ÝÁ¿ 
    DMA_CHx->CCR|=1<<0;  //开启DMA传输
}    

 

void RX_MYDMA_Config(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)  //发送
{
    RCC->AHBENR|=1<<0;               //¿ªÆôDMA1ʱÖÓ
    delay_ms(5);                      //µÈ´ýDMAʱÖÓÎȶ¨
    DMA_CHx->CPAR=cpar;            //DMA1 ÍâÉèµØÖ· 
    DMA_CHx->CMAR=(u32)RX_data;     //DMA1,´æ´¢Æ÷µØÖ·
    DMA1_MEM_LEN=1024;          //±£´æDMA´«ÊäÊý¾ÝÁ¿
    DMA_CHx->CNDTR=1024;        //DMA1,´«ÊäÊý¾ÝÁ¿
    DMA_CHx->CCR=0X00000000;    //¸´Î»
    DMA_CHx->CCR|=0<<4;            //´Ó´æ´¢Æ÷д
    DMA_CHx->CCR|=0<<5;          //ÆÕͨģʽ
    DMA_CHx->CCR|=0<<6;         //ÍâÉèµØÖ··ÇÔöÁ¿Ä£Ê½
    DMA_CHx->CCR|=1<<7;          //´æ´¢Æ÷ÔöÁ¿Ä£Ê½
    DMA_CHx->CCR|=0<<8;          //ÍâÉèÊý¾Ý¿í¶ÈΪ8λ
    DMA_CHx->CCR|=0<<10;         //´æ´¢Æ÷Êý¾Ý¿í¶È8λ
    DMA_CHx->CCR|=1<<12;         //ÖеÈÓÅÏȼ¶
    DMA_CHx->CCR|=0<<14;         //·Ç´æ´¢Æ÷µ½´æ´¢Æ÷ģʽ        
  DMA_CHx->CCR|=1<<1;    //¿ªÆô´«ÊäÍê³ÉÖжϠ   

 

//写函数

void LY68_Write_Page_writ(u32 Write_Start_Addr,u8* pTxData,u16 TSize )
{
  u16 Len;
    //Write_Start_Addr=0;   //´Ó0ҳдÆð
    MYDMA_Enable(DMA1_Channel5);
    delay_us(10);
  Send_Write_Command(LY_SPI_Write_COMMAND);                    //·¢ËÍдÃüÁî
    SPI2_ReadWriteByte((u8)((Write_Start_Addr)>>16));//µØÖ·  23:16  ·¢ËÍдÈë 
    SPI2_ReadWriteByte((u8)((Write_Start_Addr)>>8)); //µØÖ·  15:8   ·¢ËÍдÈë 
    SPI2_ReadWriteByte((u8)(Write_Start_Addr));      //µØÖ·  15:8      ·¢ËÍдÈë 
    //HAL_SPI_Transmit(&hspi2,(uint8_t * )TX_data, 1024, 0xfffffff);
    //Spi2DMATx_comp=0;

//TXDMAEN:发送缓冲区DMA使能,
    SPI2->CR2|=1<<1; 
    SPI2->CR2=(SPI2->CR2)&0XFE;//     

//读函数

void LY68_Read_Page_writ()
{
    u16 Read_ADDR;
    Read_ADDR=0;
    
    u16 retry=0;    
    MYDMA_Enable(DMA1_Channel4);
    delay_us(10);
    Send_Write_Command(LY_SPI_Fast_Read_COMMAND); //·¢ËͶÁÊý¾ÝÃüÁî
    SPI2_ReadWriteByte((u8)((Read_ADDR)>>16));//µØÖ·  23:16   //·¢ËͶÁÊý¾ÝÆðʼµØÖ·
    SPI2_ReadWriteByte((u8)((Read_ADDR)>>8)); //µØÖ·  15:8    
    SPI2_ReadWriteByte((u8)(Read_ADDR));      //µØÖ·  15:8

   //RXDMAEN:接收缓冲区DMA使能 (Rx buffer DMA enable)
    SPI2->CR2=(SPI2->CR2)&0XFD;//  
    SPI2->CR2=(SPI2->CR2)|0X01;//  

此帖出自stm32/stm8论坛
 
 
 

回复

337

帖子

0

TA的资源

纯净的硅(初级)

7
 

感觉SPI的DMA方式很麻烦

此帖出自stm32/stm8论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表