硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1219|回复: 11
收起左侧

[STM32H7] 使能Icache与Dcache使原来正常的SPI出现时序错乱

[复制链接]

3

主题

11

回帖

20

积分

新手上路

积分
20
发表于 2024-11-9 21:19:57 | 显示全部楼层 |阅读模式
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "sdmmc.h"
#include "spi.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
#include "fmc.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "mpu_armv7.h"
#include "string.h"
#define CONVST_GPIO                GPIOB
#define CONVST_PIN                GPIO_PIN_14
#define CONVST_1()                CONVST_GPIO->BSRR = CONVST_PIN
#define CONVST_0()                CONVST_GPIO->BSRR = ((uint32_t)CONVST_PIN << 16U)

#define RESET_1()        HAL_GPIO_WritePin(GPIOG, GPIO_PIN_8, GPIO_PIN_SET)
#define RESET_0()        HAL_GPIO_WritePin(GPIOG, GPIO_PIN_8, GPIO_PIN_RESET)
#define NSS_SET HAL_GPIO_WritePin(SPI_NSS_GPIO_Port,SPI_NSS_Pin,GPIO_PIN_SET)
#define NSS_RESET HAL_GPIO_WritePin(SPI_NSS_GPIO_Port,SPI_NSS_Pin,GPIO_PIN_RESET)
/* AD7606 FSMC总线地址,只能读,无需写 */
#define AD7606_RESULT        *(__IO uint16_t *)0x60000000


#define DATA_SIZE              ((uint32_t)0x10000000U)/BLOCKSIZE  /* Data Size 256Mo */
#define BUFFER_SIZE            ((uint32_t)0x00004000U) /* 16Ko */
#define BLOCKSIZE   ((uint32_t)512U) /*!< Block size is 512 bytes */
#define MMC_TIMEOUT            ((uint32_t)0x00100000U)
#define ADDRESS1                ((uint32_t)0x00000400U) /* MMC Address to write/read data */
#define BUFFERSIZE                 (COUNTOF(aTxBuffer) - 1)
#define COUNTOF(__BUFFER__)        (sizeof(__BUFFER__) / sizeof(*(__BUFFER__)))
       
uint32_t ADDRESS = ADDRESS1;
uint32_t ADDRESS3 = ADDRESS1;
__IO uint8_t RxCplt, TxCplt;

/******** MMC Transmission Buffer definition *******/
#if defined ( __ICCARM__ )
#pragma location = 0x24000000
#elif defined ( __CC_ARM )
__attribute__((at(0x24000000)))
#elif defined ( __GNUC__ )
__attribute__((section (".RAM_D1")))
#endif
uint8_t aTxBuffer[BUFFER_SIZE];//数据发送
/**************************************************/

/******** MMC Transmission Buffer definition *******/
#if defined ( __ICCARM__ )
#pragma location = 0x24020000
#elif defined ( __CC_ARM )
__attribute__((at(0x24020000)))
#elif defined ( __GNUC__ )
__attribute__((section (".RAM_D1")))
#endif
uint8_t aTxBuffer1[BUFFER_SIZE];//数据接收

uint8_t USART1_aRxBuffer[12];
uint8_t Rx_UART=0;//串口中断的回调值
uint8_t OPEN=0;


/**************************************************/

/******** MMC Receive Buffer definition *******/
#if defined ( __ICCARM__ )
#pragma location = 0x24040000
#elif defined ( __CC_ARM )
__attribute__((at(0x24040000)))
#elif defined ( __GNUC__ )
__attribute__((section (".RAM_D1")))
#endif
uint8_t aRxBuffer[BUFFER_SIZE]={0};
/**************************************************/

#if defined ( __ICCARM__ )
#pragma location = 0x24030000
#elif defined ( __CC_ARM )
__attribute__((at(0x24030000)))
#elif defined ( __GNUC__ )
__attribute__((section (".RAM_D1")))
#endif
uint16_t  Rx_point[19]={0};
/**************************************************/



uint32_t start_time = 0;
uint32_t stop_time = 0;
float speed;

static uint8_t Wait_MMCCARD_Ready(void);

#ifdef __GNUC__ /* __GNUC__ */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */

/* Private functions ---------------------------------------------------------*/
void Fill_Buffer(uint32_t *pBuffer, uint16_t BufferLength, uint32_t Offset);

/**
  * @brief  Main program
  * @param  None
  * @retval None
  */



/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

static int16_t g_tAD7606[8];//采样值
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

#ifndef HSEM_ID_0
#define HSEM_ID_0 (0U) /* HW semaphore 0*/
#endif

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
GyroData_t GyroData;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MPU_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
//extern unsigned int Nums_Rising;//1s?????
/******************************************************************************
* @ ???  : HAL_TIM_PeriodElapsedCallback
* @ ?  ?  : ???????????
* @ ?  ?  : htim ????
* @ ???  : ?
******************************************************************************/

static void sb_delay(volatile uint32_t t)
{
        while(t--);
}

static uint16_t GZ_Du(uint16_t trans)
{
        NSS_RESET;
        sb_delay(8);
        uint16_t result;
        static HAL_StatusTypeDef state;
        state=HAL_SPI_TransmitReceive(&hspi1,(uint8_t*)&trans,(uint8_t*)&result,1,0xff);
        if(state!=HAL_OK)
        {
                while(1);
        }
        NSS_SET;
        sb_delay(130);
        return result;
}

void GZ_Write(uint8_t addr,uint8_t value)
{
        addr|=0x80;
        uint16_t tx = (addr<<8)| value ;
        GZ_Du(tx);
}

void GZ_Init(void)
{
        GZ_Write(0x68,0x80);//重启指令
        GZ_Write(0x69,0x00);
        HAL_Delay(400);
       
        GZ_Write(0x5c,0x04);//设置内置巴特沃斯滤波器等级
        GZ_Write(0x5d,0x00);
       
        GZ_Write(0x64,0x03);//设定均值滤波器值为4,此时角度差最终输出频率为2000/(0+1)=2000Hz
        GZ_Write(0x65,0x00);
}

uint16_t Tx_tmp=0,Rx_tmp=0;
float jicun_result[9];
float cubchu[100];
uint16_t  j3=0;
uint8_t  j4=0;
int32_t Rx_point1[9];//将采集的数据转换为32位的数据
void GZ_Read(void)
{
        //用于保存上一次的角度值 等下加回去
         float lastx=GyroData.anglex;
         float lasty=GyroData.angley;
         float lastz=GyroData.anglez;
         uint8_t  j=0;
         uint8_t  j1=0;
         uint8_t  j2=0;
         
       
         static uint8_t addr[]=
         {0x04,0x06,//Gyro_X
                0x08,0x0A,//Gyro_Y
                0x0C,0x0E,//Gyro_Z
                0x10,0x12,//Acc_X
                0x14,0x16,//Acc_Y
                0x18,0x1A,//Acc_Z
                0x24,0x26,//Delta_X 注意这里读到的是2ms内的角度差
                0x28,0x2A,//Delta_Y
                0x2C,0x2E,//Delta_Z
         };
         static uint16_t data[sizeof(addr)];//18个数据

         
         //数据第一帧 只发不接
         Tx_tmp=addr[0]<<8;
         Rx_tmp=GZ_Du(Tx_tmp);
         for(uint8_t i=1;i<18;i++)
         {
                Tx_tmp=addr[i]<<8;//准备发送帧的格式
                Rx_tmp=GZ_Du(Tx_tmp);
                Rx_point[i-1]=Rx_tmp;
         }
         //数据最后一帧 只接不发
         Tx_tmp=0;
         Rx_point[17]=GZ_Du(Tx_tmp);
         Rx_point[18]=GZ_Du(Tx_tmp);
//         //整理接受的数据
//         uint8_t high_part;
//         uint8_t low_part;
//         for(j=0;j<18;j++)
//         {
//                 high_part=Rx_point[j]& 0xFF;
//                 low_part=Rx_point[j+1]>>8;
//                 shou_buffer[j]=(high_part<<8)|low_part;
//         }
         for(j1=0;j1<9;j1++)
         {
                 Rx_point1[j1]=(Rx_point[2*j1+1]<<16)|Rx_point[2*j1];
         }
//                  for(j1=0;j1<9;j1++)
//         {
//                 Rx_point1[j1]=(shou_buffer[2*j1+1]<<16)|shou_buffer[2*j1];
//         }
         for(j2=0;j2<9;j2++)
         {
                 if(Rx_point1[j2]&0x80000000)
                 {
                         Rx_point1[j2]=Rx_point1[j2]-0x100000000LL;
                 }
                 else
                 {
                         Rx_point1[j2]=Rx_point1[j2];
                 }
                 if(j2<3)
                 {
                         jicun_result[j2]=Rx_point1[j2]/655360.0f;
                 }
                 if(j2<6&&j2>=3)
                 {
                         jicun_result[j2]=Rx_point1[j2]*12.25/65536000.0f;
                 }
                 if(j2<9&&j2>=6)
                 {
                         jicun_result[j2]=Rx_point1[j2]/994205.4f;
                 }
         }
//         if(j3*9<900)
//         {
//                 for(j4=0;j4<9;j4++)
//                 {
//                         cubchu[j3*9+j4]=jicun_result[j4];
//                 }
//         }
         
         if(j3*9<900)
         {
                         cubchu[j3]=jicun_result[5];
         }
         
         if(jicun_result[5]<9.7)
         {
                 j4++;
         }
         
         j3++;
         
                  if(j3>=100)
         {
                        j3=0;
//                  j4=0;
         }

}


void AD7606_Reset(void)
{
        RESET_0();        /* 退出复位状态 */

        RESET_1();        /* 进入复位状态 */
        RESET_1();        /* 仅用于延迟。 RESET复位高电平脉冲宽度最小50ns。 */
        RESET_1();
        RESET_1();
        RESET_1();
        RESET_1();
        RESET_1();
        RESET_1();

        RESET_0();        /* 退出复位状态 */
}

void AD7606_StartConvst(void)
{
        /* page 7:  CONVST 高电平脉冲宽度和低电平脉冲宽度最短 25ns */
        /* CONVST平时为高 */
        CONVST_0();
        CONVST_0();
        CONVST_0();

        CONVST_1();
}


__weak void AD7606_SEGGER_RTTOUT(void)
{
       
}
uint8_t ii=0;
uint16_t iii=0;
uint16_t j=0;
uint8_t flag=0;
uint8_t flag1=0;
void AD7606_ReadNowAdc(void)
{
        g_tAD7606[0] = AD7606_RESULT;        /* 读第1路样本 */
        g_tAD7606[1] = AD7606_RESULT;        /* 读第2路样本 */
        g_tAD7606[2] = AD7606_RESULT;        /* 读第3路样本 */
        g_tAD7606[3] = AD7606_RESULT;        /* 读第4路样本 */
        g_tAD7606[4] = AD7606_RESULT;        /* 读第5路样本 */
        g_tAD7606[5] = AD7606_RESULT;        /* 读第6路样本 */
        g_tAD7606[6] = AD7606_RESULT;        /* 读第7路样本 */
        g_tAD7606[7] = AD7606_RESULT;        /* 读第8路样本 */
        if((iii*16)<BUFFERSIZE)
        {
                for(ii=0;ii<16;ii=ii+2)
                {
                        aTxBuffer1[iii*16+ii] = g_tAD7606[ii/2]>>8;
                        aTxBuffer1[iii*16+ii+1] = g_tAD7606[ii/2] & 0xFF;
                       
                        if(iii>=10)
                        {
                                aTxBuffer[iii*16+ii]=aTxBuffer1[iii*16+ii];
                                aTxBuffer[iii*16+ii+1]=aTxBuffer1[iii*16+ii+1];
                        }
                       
                }
        iii++;
        }
       
        if(iii>=10)
        {
                memcpy(aTxBuffer, aTxBuffer1, 160);       
        }
       
        if((iii*16)>=BUFFERSIZE&&flag==0)
        {
//                memcpy(aTxBuffer, aTxBuffer1, sizeof(aTxBuffer1));
//                memset(aTxBuffer1, 0, sizeof(aTxBuffer1));
                flag=1;
                iii=0;
        }
       
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
   if(htim->Instance == TIM2)                  
   {
                  AD7606_StartConvst();       
   }
}


void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
        if(GPIO_Pin == GPIO_PIN_6)
        {
                AD7606_ReadNowAdc();
        }
        if(GPIO_Pin == GPIO_PIN_10)
        {
                GZ_Read();
        }
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */
  HAL_MMC_CardCIDTypeDef pCID;
  HAL_MMC_CardCSDTypeDef pCSD;
  /* USER CODE END 1 */
/* USER CODE BEGIN Boot_Mode_Sequence_0 */
//  int32_t timeout;
/* USER CODE END Boot_Mode_Sequence_0 */

  /* MPU Configuration--------------------------------------------------------*/
  MPU_Config();

  /* Enable the CPU Cache */

  /* Enable I-Cache---------------------------------------------------------*/
  SCB_EnableICache();

  /* Enable D-Cache---------------------------------------------------------*/
  SCB_EnableDCache();

/* USER CODE BEGIN Boot_Mode_Sequence_1 */
  /* Wait until CPU2 boots and enters in stop mode or timeout*/
//  timeout = 0xFFFF;
//  while((__HAL_RCC_GET_FLAG(RCC_FLAG_D2CKRDY) != RESET) && (timeout-- > 0));
//  if ( timeout < 0 )
//  {
//  Error_Handler();
//  }
/* USER CODE END Boot_Mode_Sequence_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 Boot_Mode_Sequence_2 */
/* When system initialization is finished, Cortex-M7 will release Cortex-M4 by means of
HSEM notification */
/*HW semaphore Clock enable*/
__HAL_RCC_HSEM_CLK_ENABLE();
/*Take HSEM */
HAL_HSEM_FastTake(HSEM_ID_0);
/*Release HSEM in order to notify the CPU2(CM4)*/
HAL_HSEM_Release(HSEM_ID_0,0);
/* wait until CPU2 wakes up from stop mode */
//timeout = 0xFFFF;
//while((__HAL_RCC_GET_FLAG(RCC_FLAG_D2CKRDY) == RESET) && (timeout-- > 0));
//if ( timeout < 0 )
//{
//Error_Handler();
//}
/* USER CODE END Boot_Mode_Sequence_2 */

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_FMC_Init();
  MX_SDMMC1_MMC_Init();
  MX_USART2_UART_Init();
  MX_TIM2_Init();
  MX_TIM1_Init();
  MX_SPI1_Init();
  /* USER CODE BEGIN 2 */
  if(HAL_MMC_Erase(&hmmc1, ADDRESS, (ADDRESS+DATA_SIZE)) != HAL_OK)
  {
    Error_Handler();
  }
  if(Wait_MMCCARD_Ready() != HAL_OK)
  {
    Error_Handler();
  }
  AD7606_Reset();//开始时复位
//无过采样
        HAL_GPIO_WritePin(GPIOD, GPIO_PIN_11, GPIO_PIN_RESET);
        HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_RESET);
        HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_RESET);
       

        HAL_Delay(10);
        CONVST_1();//初始值为1
//        AD7606_StartConvst();//启动一次
        HAL_Delay(10);
        GZ_Init();
        HAL_Delay(5);

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

        HAL_UART_Receive_IT(&huart2, USART1_aRxBuffer, 8);//接收上位机发送的数据
        if(Rx_UART==1)//判断是否接收成功,通过回调函数,此函数只进一次
                {
                        HAL_TIM_Base_Start_IT(&htim2);
                        HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
                        HAL_NVIC_SetPriority(EXTI15_10_IRQn, 3, 0);
                        HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
                        OPEN=1;//收到上位机的信息之后,开始进行采样与发送的标志位
                        Rx_UART=0;
                }
        if(OPEN==1)
        {
                        if(flag==1)
                                {               
                                        if(j==0)
                                        {
                                                start_time = HAL_GetTick();
                                        }
                                        flag=0;
//                                        SCB_CleanDCache_by_Addr((uint32_t*)aTxBuffer, BUFFER_SIZE);
                                        TxCplt = 0;
                       
                                        if(HAL_MMC_WriteBlocks_DMA(&hmmc1, aTxBuffer, ADDRESS, (BUFFER_SIZE>>9)) != HAL_OK)
                                        {
                                                Error_Handler();
                                        }
                                        while (TxCplt == 0){}
//                                        SCB_CleanDCache_by_Addr((uint32_t*)aTxBuffer, BUFFER_SIZE);
                                        j++;
                                       
                                        if(j==1024)//8192
                                        {
                                                stop_time = HAL_GetTick();
                                                speed=(((BUFFER_SIZE*1024)>>10)*1000/1024)/(float)(stop_time - start_time);
                                                flag=0;
                                                flag1=1;
                                                HAL_TIM_Base_Stop_IT(&htim2);
                                                HAL_NVIC_DisableIRQ(EXTI15_10_IRQn);
                                        }
                                        if(j<1024)
                                        {
                                        ADDRESS += (BUFFER_SIZE>>9);
                                        }
                                }
                                if(flag1==1)
                                {
                                        SCB_CleanDCache_by_Addr((uint32_t*)aRxBuffer, BUFFER_SIZE);
                                        if(HAL_MMC_ReadBlocks_IT(&hmmc1, aRxBuffer, ADDRESS3, (BUFFER_SIZE>>9)) != HAL_OK)
                                        {
                                        Error_Handler();
                                        }
                                        while(RxCplt==0)
                                        {
                                                HAL_Delay(1);
                                        }
                                        if(RxCplt==1)
                                        {
                                                HAL_UART_Transmit(&huart2,aRxBuffer,16384,10000);  //加上位机通讯
                                                RxCplt=0;
                                        }
                                        if(ADDRESS3<ADDRESS)
                                        {
                                                ADDRESS3 += (BUFFER_SIZE>>9);
                                        }
                                        else
                                        {
                                                flag1=0;
                                                break;
                                        }
                                }
                }
       
        }

  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Supply configuration update enable
  */
  HAL_PWREx_ConfigSupply(PWR_DIRECT_SMPS_SUPPLY);

  /** Configure the main internal regulator output voltage
  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 2;
  RCC_OscInitStruct.PLL.PLLN = 64;
  RCC_OscInitStruct.PLL.PLLP = 2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  RCC_OscInitStruct.PLL.PLLR = 2;
  RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
  RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
  RCC_OscInitStruct.PLL.PLLFRACN = 0;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
                              |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
  RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */
static uint8_t Wait_MMCCARD_Ready(void)
{
  uint32_t loop = MMC_TIMEOUT;

  /* Wait for the Erasing process is completed */
  /* Verify that MMC card is ready to use after the Erase */
  while(loop > 0)
  {
    loop--;
    if(HAL_MMC_GetCardState(&hmmc1) == HAL_MMC_CARD_TRANSFER)
    {
        return HAL_OK;
    }
  }
  return HAL_ERROR;
}

void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc)
{
  RxCplt=1;
}

void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc)
{
  TxCplt=1;
}

void Fill_Buffer(uint32_t *pBuffer, uint16_t BufferLength, uint32_t Offset)
{
  uint16_t IndexTmp;

  /* Put in global buffer same values */
  for ( IndexTmp = 0; IndexTmp < BufferLength; IndexTmp++ )
  {
    pBuffer[IndexTmp] = IndexTmp + Offset;
  }
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
    if (huart->RxXferCount == 0)
                        {
        Rx_UART=1;
                        }
    // ????????????????????????????

}

/* USER CODE END 4 */

/* MPU Configuration */

void MPU_Config(void)
{
  MPU_Region_InitTypeDef MPU_InitStruct = {0};

  /* Disables the MPU */
  HAL_MPU_Disable();

  /** Initializes and configures the Region and the memory to be protected
  */
  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  MPU_InitStruct.Number = MPU_REGION_NUMBER0;
  MPU_InitStruct.BaseAddress = 0x24000000;
  MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;
  MPU_InitStruct.SubRegionDisable = 0x00;
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
  MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
  MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;

  HAL_MPU_ConfigRegion(&MPU_InitStruct);

  /** Initializes and configures the Region and the memory to be protected
  */
  MPU_InitStruct.Number = MPU_REGION_NUMBER1;
  MPU_InitStruct.BaseAddress = 0x60000000;
  MPU_InitStruct.Size = MPU_REGION_SIZE_64KB;
  MPU_InitStruct.SubRegionDisable = 0x0;
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
  MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;

  HAL_MPU_ConfigRegion(&MPU_InitStruct);
  /* Enables the MPU */
  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);

}

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */


回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2024-11-10 10:09:38 | 显示全部楼层
DCache不会破环数据,只会影响数据一致性。
回复

使用道具 举报

3

主题

11

回帖

20

积分

新手上路

积分
20
 楼主| 发表于 2024-11-10 10:50:26 | 显示全部楼层
eric2013 发表于 2024-11-10 10:09
DCache不会破环数据,只会影响数据一致性。

大佬您好,我将24000000地址后的512K大小已经定义成了NOT_Cacheable,spi读取数据的数组还放进了这部分空间。使能Dcache还是会破坏数据,这是为什么呢。
回复

使用道具 举报

3

主题

11

回帖

20

积分

新手上路

积分
20
 楼主| 发表于 2024-11-10 17:05:55 | 显示全部楼层
我学习了您发布的关于cache的视频,数据一致性发生在开启读cache,但是我的SCB配置的为000,并没有开启读cache,而且我有一个单独的spi通信代码,在使能cache后出现了错位现象
回复

使用道具 举报

3

主题

11

回帖

20

积分

新手上路

积分
20
 楼主| 发表于 2024-11-10 17:07:42 | 显示全部楼层
void MPU_Config(void)
{
  MPU_Region_InitTypeDef MPU_InitStruct = {0};

  /* Disables the MPU */
  HAL_MPU_Disable();

  /** Initializes and configures the Region and the memory to be protected
  */
  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  MPU_InitStruct.Number = MPU_REGION_NUMBER0;
  MPU_InitStruct.BaseAddress = 0x0;
  MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
  MPU_InitStruct.SubRegionDisable = 0x87;
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
  MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
  MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
  MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;

  HAL_MPU_ConfigRegion(&MPU_InitStruct);
  /* Enables the MPU */
  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);

}
  SCB_EnableICache();

  SCB_EnableDCache();


用了外部中断:
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
        if(GPIO_Pin == GPIO_PIN_10)
        {
                GZ_Read();//spi读函数
        }
}
回复

使用道具 举报

3

主题

11

回帖

20

积分

新手上路

积分
20
 楼主| 发表于 2024-11-10 17:25:02 | 显示全部楼层
eric2013 发表于 2024-11-10 10:09
DCache不会破环数据,只会影响数据一致性。

        NSS_RESET;
        sb_delay(10);
        uint16_t result;
        static HAL_StatusTypeDef state;
        state=HAL_SPI_TransmitReceive(&hspi1,(uint8_t*)&trans,(uint8_t*)&result,1,0xff);
        if(state!=HAL_OK)
        {
                while(1);
        }
        NSS_SET;
        sb_delay(150);
        return result;
读spi也没有用到dma什么的,正常读回来是16个数据,都是16位,是能之后就成了第一个数组的后八位与第二个数组的前八位是原来正确数组的16位。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2024-11-11 09:10:01 | 显示全部楼层
嘎嘎~ 发表于 2024-11-10 17:25
NSS_RESET;
        sb_delay(10);
        uint16_t result;

不知道我有没有正确理解你的意思,是不是大小端没有处理好
回复

使用道具 举报

3

主题

11

回帖

20

积分

新手上路

积分
20
 楼主| 发表于 2024-11-11 09:55:52 | 显示全部楼层
eric2013 发表于 2024-11-11 09:10
不知道我有没有正确理解你的意思,是不是大小端没有处理好

正常的是1111   2222   3333   4444    5555    6666    7777
打开cache后变为0011  1122  2233  3344  4455  5566  6677 7700这样的
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2024-11-12 09:39:34 | 显示全部楼层
嘎嘎~ 发表于 2024-11-11 09:55
正常的是1111   2222   3333   4444    5555    6666    7777
打开cache后变为0011  1122  2233  3344   ...

最后一个地方试试,将你的RAM空间,改用DTCM,这个没有Cache问题,你测测正常不
回复

使用道具 举报

3

主题

11

回帖

20

积分

新手上路

积分
20
 楼主| 发表于 2024-11-14 08:55:55 | 显示全部楼层
eric2013 发表于 2024-11-12 09:39
最后一个地方试试,将你的RAM空间,改用DTCM,这个没有Cache问题,你测测正常不

感谢大佬的指点,我连接示波器看了波形,发现是使能cache后代码运行速度太快导致了高电平持续时间太短,不满足惯组的时间要求,已经解决了。
回复

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2024-12-17 18:12:36 | 显示全部楼层
嘎嘎~ 发表于 2024-11-14 08:55
感谢大佬的指点,我连接示波器看了波形,发现是使能cache后代码运行速度太快导致了高电平持续时间太短, ...

你好,我遇到ICACH打开,DMA写SPI SRAM的数据就完全不对,如果只打开DCACH就没什么问题,请问你这个是怎么解决的呢
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2024-12-18 08:34:15 | 显示全部楼层
emma90 发表于 2024-12-17 18:12
你好,我遇到ICACH打开,DMA写SPI SRAM的数据就完全不对,如果只打开DCACH就没什么问题,请问你这个是怎 ...

ICache不影响RAM数据的一致性问题。估计程序里面有其它问题导致的
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-14 01:12 , Processed in 0.049297 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表