[原创] ST NUCLEO-U083RC 评测——智能坐垫移植笔记

nengzhi   2024-5-31 22:26 楼主
 

有幸被选中参加STM32U0开发板的评测活动。原打算把一个智能坐垫的项目移植过来试一试功耗能不能降到更低。但无奈手头杂事太多,一再耽搁,今天小编通知我活动截至时间到了,也没来得及完成最终的实际功耗测试,索性功能移植的差不多了,就把移植过程中的一些记录拿来分享一下。

先来个开箱视频把,早就录好了。

https://b23.tv/12Sv54u

然后就是移植过程中的一些记录。我是第一次接触STM32 的开发,原本一直在搞Arduino下的ESP32开发,所以这次是从头开始学习STM32开发的,所以记录一下移植过程。本次移植涉及到了RTC,串口、Flash以及低功耗等部分。

先说一下我的开发环境,我用的STM32Cube IDE开发。参考B站教程 。全网最完整最干练的CubeMX、CubeIDE STM32开发教程 拥抱高效Cube开发方式【3.1】—Kevin带你读《STM32Cube高效开发教程基础篇》_哔哩哔哩_bilibili

开发板特性

先来介绍下开发板的特点。

  • 开发板自带ST-Link,这个ST-Link是自带虚拟串口的和STM32的LPUART1连在一起。
  • D1和D0跳线默认时断开的。
  • 没有外接高速晶振,只有一个低速晶振。
  • 拥有256K flash。

如下代码是把printf重定向到LUART1

/* USER CODE BEGIN Includes */
#include<stdio.h>
#include<string.h>
/* USER CODE END Includes */


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

UART_HandleTypeDef hlpuart1;

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

PUTCHAR_PROTOTYPE
{
//同样USART2改为你的串口
	HAL_UART_Transmit_IT(&hlpuart1, (uint8_t*)&ch,1);
    return ch;
}

/* USER CODE END PV */

因为板卡上带有ST-LINK,用的是USART2或LPUART1(二选一),所以把printf重定向到LPUART1串口。

在IDE生成的代码中插入如下内容:

首先,您需要在 main.c 文件中的 USER CODE Includes 中包含 “stdio.h” 以使用 printf。

/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */

以下代码将编译器将标准输出连接到 printf 的 UART。

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

UART_HandleTypeDef hlpuart1;

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

PUTCHAR_PROTOTYPE
{
//同样USART2改为你的串口
	HAL_UART_Transmit_IT(&hlpuart1, (uint8_t*)&ch,1);
    return ch;
}

/* USER CODE END PV */

浮点数问题

RTC

配置RTC

开启低速晶振

image (2).png

开启RTC

激活时钟和日历

企业微信截图_17142934983694.png

 

设置RTC

企业微信截图_17142942605230.png
 

上图为每1秒触发一次中断

设置中断

微信图片_20240603171447.png
 

配置时钟树

微信图片_20240603171545.png

编写代码

在stm32u0xx_it.c 文件中找到RTC相关的函数寻早WakeUp的IRQ处理函数

微信图片_20240603171621.png

 

导航到此处

企业微信截图_17142973522495.png

函数 __weak void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc) 是可以重新实现的,在main.c 文件中重新定义此函数。

微信图片_20240603171722.png
 
/* USER CODE BEGIN 0 */

void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc){	
	//中断处理程序
}
/* USER CODE END 0 */

以上函数在RTC唤醒后打印当前的日期和时间

while中读取RTC

  /* USER CODE BEGIN WHILE */
RTC_TimeTypeDef sTime;
RTC_DateTypeDef sDate;
while (1)
 {
	  HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
	  HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
	  printf(date_str,"%4d-%02d-%02d %02d:%02d:%02d\r\n",2000 + sDate.Year, sDate.Month, sDate.Date,sTime.Hours,sTime.Minutes,sTime.Seconds);
}

转换时间戳

#include <time.h>

/* USER CODE BEGIN PFP */
int32_t stm32_rtc_readtimestamp(const RTC_TimeTypeDef rTime,const RTC_DateTypeDef rDate){
	struct tm tm_new;
	tm_new.tm_sec = rTime.Seconds;
	tm_new.tm_min=rTime.Minutes;
	tm_new.tm_hour=rTime.Hours - 8;
	tm_new.tm_mday=rDate.Date;
	tm_new.tm_mon=rDate.Month-1;
	tm_new.tm_year=rDate.Year+100;

	return mktime(&tm_new);
}
/* USER CODE END PFP */


int32_t timeStamp;
  while (1)
  {
      ......
      timeStamp = stm32_rtc_readtimestamp(sTime,sDate);
      printf("timestamp = %ld",timeStamp);
      
  }

验证时间戳

得到时间戳后,可以使用在线工具进行验证:时间戳(Unix timestamp)转换工具 - 在线工具
将我们自己的时间戳输入进去,即可得到北京时间,以此进行验证。也可以将我们需要转换的时间输入进去,转换得到时间戳。

串口

配置串口

开启LPUART1,并修改针脚到PA2和PA3,这两个针脚可以直接通过开发板的Typec的虚拟串口访问。

企业微信截图_17142954928712.png

 

开启LPUART2,并修改针脚到PC0和PC1,这两个针脚用于和蓝牙模块通讯。

企业微信截图_17142958921909.png

 

 

开启串口中断

微信图片_20240603171814.png

按键输入

开发板原理图

image (3).png

按键配置

企业微信截图_17142997033927.png

驱动代码

以下代码写入while中

HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin);
	  if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin)){ //是否为低电平,按下为低电平
		  HAL_Delay(10);//软件消抖
		  if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin)){
			  HAL_GPIO_TogglePin(LD4_GPIO_Port, LD4_Pin);//小灯翻转
			  while(HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == GPIO_PIN_RESET){}
		  }
	  }

低功耗

概述

微信图片_20240603173409.png

在利用RTC闹钟唤醒standby模式中,需要关注的问题有:

1.关于功耗控制,需要对不使用的IO口进行漏电流的控制,因此,最好将没有使用的IO口都配置为模拟输入状态。

2.利用RTC闹钟进行唤醒时,需要注意闹钟中断触发后,中断标识是否被清除,否则,standby模式很可能在进入后立马退出。

3.如果要在退出standby模式后,RTC时钟需要继续按照设定的时间计时,需要通过后备寄存器来判断单片机是否是第一次启动。

三种模式电流功耗大小排序

运行 > 睡眠 > 停止 > 待机。

其中运行模式与睡眠模式功耗为mA级,停止模式与待机模式为uA级,其中待机最小可以达到<5uA。

如何进入?

睡眠模式:

执行WFI或WFE指令可以使MCU进入睡眠状态。

停止模式:

在以下条件下执行WFI或WFE指令:

1、设置Cortex-M3系统控制寄存器中的SLEEPDEEP位;

2、清除电源控制寄存器(PWR_CR)中的PDDS位 进入;

3、通过设置PWR_CR中LPDS位选择电压调节器的模式;

待机模式:

在以下条件下执行WFI或WFE指令:

1、设置Cortex-M3系统控制寄存器中的SLEEPDEEP位;

2、设置电源控制寄存器(PWR_CR)中的PDDS位;

3、清除电源控制/状态寄存器(PWR_CSR)中的WUF位;

如何退出?

睡眠模式:

如果是执行WFI指令进入睡眠模式,任意一个外设中断都能将系统从睡眠模式唤醒。如果是执行WFE指令进入睡眠模式,一旦发生唤醒事件时,微处理器都将从睡眠模式退出。

停止模式:

如果是执行WFI进入停止模式,任一外部中断线为中断模式可以唤醒。如果是执行WFE进入停止模式。任一外部中断线为事件模式可以唤醒。

待机模式:

待机模式唤醒只有4种:外部复位、IWDG复位、WKUP引脚上的上升沿或RTC闹钟事件的上升沿。并且从待机唤醒后,除了电源控制/状态寄存器,所有寄存器被复位。唤醒后的代码执行等同于复位后的执行。

RTC唤醒设置

在利用RTC闹钟唤醒standby模式中,需要关注的问题有:

1.关于功耗控制,需要对不使用的IO口进行漏电流的控制,因此,最好将没有使用的IO口都配置为模拟输入状态。参见针脚设置

2.利用RTC闹钟进行唤醒时,需要注意闹钟中断触发后,中断标识是否被清除,否则,standby模式很可能在进入后立马退出。

3.如果要在退出standby模式后,RTC时钟需要继续按照设定的时间计时,需要通过后备寄存器来判断单片机是否是第一次启动。

进入待机模式

/* USER CODE BEGIN 0 */
void sys_enter_standby_mode(void)
{
   GPIO_AnalogState_Config(); //禁用GPIO
    __HAL_RCC_PWR_CLK_ENABLE();   // 使能PWR时钟
    HAL_PWR_EnableBkUpAccess();
	HAL_PWR_EnterSTANDBYMode();  //进入待机模式
}

/* USER CODE END 0 */

避免RTC被重置

static void MX_RTC_Init(void)
{
    ......

/* USER CODE BEGIN RTC_Init 1 */
  
  HAL_PWR_EnableBkUpAccess();
  /* USER CODE END RTC_Init 1 */
    ......
    ......
        
    /* USER CODE BEGIN Check_RTC_BKUP */
  if(HAL_RTCEx_BKUPRead(&hrtc,RTC_BKP_DR1) != 0xA5A5) //判断后备寄存器是否被赋值
  {


  /* USER CODE END Check_RTC_BKUP */

  /** Initialize RTC and set the Time and Date
  */
      ......
      ......
      ......
          
    /* USER CODE BEGIN RTC_Init 2 */
  HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR1, 0xA5A5);  //这里就是将这个寄存器的标志设为刚才的那个值,下次掉电后就不会进入到这里来
	}
	else
	{
		if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0, RTC_WAKEUPCLOCK_CK_SPRE_16BITS, 0) != HAL_OK)
		  {
		    Error_Handler();
		  }                          /* RTC的中断配置初始化以及启动 */
	}
  /* USER CODE END RTC_Init 2 */
          
}

设置IO口为模拟输入状态

这个函数主要是为了在低功耗状态下,尽量控制IO上不必要的漏电流产生。在进入待机模式前调用。

/* USER CODE BEGIN 2 */

void GPIO_AnalogState_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    
    /*Set all GPIO in analog state to reduce power consumption*/
    
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();
    
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Pin = GPIO_PIN_All;
    
    HAL_GPIO_Init(GPIOA,&GPIO_InitStruct);
    HAL_GPIO_Init(GPIOB,&GPIO_InitStruct);
    HAL_GPIO_Init(GPIOC,&GPIO_InitStruct);
    
    __HAL_RCC_GPIOA_CLK_DISABLE();
    __HAL_RCC_GPIOB_CLK_DISABLE();
    __HAL_RCC_GPIOC_CLK_DISABLE();
}

/* USER CODE END 2 */

Flash

编程

上ST-LINKUtility 查看flash占用情况

本器件地址为0x08000000 到 0x0803EED0

可以从0x08020000 开始进行写入。本MCU仅支持双位操作。

int d1 =0;
int d2 =0;
uint32_t flashwriteaddr = 0x08020000;        //定义写入数据的地址
uint32_t pageError = 0;
uint64_t flashwritedata = u32_to_u64(946657215,946658888);//0x386CD7BE00000002;//要写入的数据,必须得是双字64bit

FLASH_EraseInitTypeDef flash_erase;          //定义一个结构体变量,里面有擦除操作需要定义的变量
HAL_FLASH_Unlock();                                    //第二步:解锁
flash_erase.TypeErase = FLASH_TYPEERASE_PAGES;         //擦除类型是“Page Erase”
flash_erase.Page = 64;                                 //擦除第16页
flash_erase.NbPages = 1;                               //一次性擦除2页,可以是任意页
HAL_FLASHEx_Erase(&flash_erase,&pageError);            //第三步:参数写好后调用擦除函数
HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, flashwriteaddr, flashwritedata);//第四步:写入数据
HAL_FLASH_Lock();                                      //第五步:上锁
d1 = *(__IO uint32_t *)flashwriteaddr;	   //读出flash中的数据
d2 = *(__IO uint32_t *)(flashwriteaddr+4); //地址偏移+4
printf("read data:%d   %d\r\n",d2,d1);
HAL_Delay(200);
/**
 * 通过位操作实现2个uint32_t合并为uint64_t
 */
uint64_t u32_to_u64(uint32_t d1,uint32_t d2){
	//先将uint32_t的a转为uint64_t,此时a前面32位都是0,然后左移32位,此时右32位为0,最后加上uint32_t类型的b,填充右32位的0
	return (uint64_t)(((uint64_t)d1) << 32) + d2;
}

分页

以下是开发板载的mcu的分页表。

//STM32u0的FLASH大小为256KB,只有128个页
#define ADDR_FLASH_PAGE_0     ((uint32_t)0x08000000) /* Base @ of Page 0, 2 Kbytes */
#define ADDR_FLASH_PAGE_1     ((uint32_t)0x08000800) /* Base @ of Page 1, 2 Kbytes */
#define ADDR_FLASH_PAGE_2     ((uint32_t)0x08001000) /* Base @ of Page 2, 2 Kbytes */
#define ADDR_FLASH_PAGE_3     ((uint32_t)0x08001800) /* Base @ of Page 3, 2 Kbytes */
#define ADDR_FLASH_PAGE_4     ((uint32_t)0x08002000) /* Base @ of Page 4, 2 Kbytes */
#define ADDR_FLASH_PAGE_5     ((uint32_t)0x08002800) /* Base @ of Page 5, 2 Kbytes */
#define ADDR_FLASH_PAGE_6     ((uint32_t)0x08003000) /* Base @ of Page 6, 2 Kbytes */
#define ADDR_FLASH_PAGE_7     ((uint32_t)0x08003800) /* Base @ of Page 7, 2 Kbytes */
#define ADDR_FLASH_PAGE_8     ((uint32_t)0x08004000) /* Base @ of Page 8, 2 Kbytes */
#define ADDR_FLASH_PAGE_9     ((uint32_t)0x08004800) /* Base @ of Page 9, 2 Kbytes */
#define ADDR_FLASH_PAGE_10    ((uint32_t)0x08005000) /* Base @ of Page 10, 2 Kbytes */
#define ADDR_FLASH_PAGE_11    ((uint32_t)0x08005800) /* Base @ of Page 11, 2 Kbytes */
#define ADDR_FLASH_PAGE_12    ((uint32_t)0x08006000) /* Base @ of Page 12, 2 Kbytes */
#define ADDR_FLASH_PAGE_13    ((uint32_t)0x08006800) /* Base @ of Page 13, 2 Kbytes */
#define ADDR_FLASH_PAGE_14    ((uint32_t)0x08007000) /* Base @ of Page 14, 2 Kbytes */
#define ADDR_FLASH_PAGE_15    ((uint32_t)0x08007800) /* Base @ of Page 15, 2 Kbytes */
#define ADDR_FLASH_PAGE_16    ((uint32_t)0x08008000) /* Base @ of Page 16, 2 Kbytes */
#define ADDR_FLASH_PAGE_17    ((uint32_t)0x08008800) /* Base @ of Page 17, 2 Kbytes */
#define ADDR_FLASH_PAGE_18    ((uint32_t)0x08009000) /* Base @ of Page 18, 2 Kbytes */
#define ADDR_FLASH_PAGE_19    ((uint32_t)0x08009800) /* Base @ of Page 19, 2 Kbytes */
#define ADDR_FLASH_PAGE_20    ((uint32_t)0x0800A000) /* Base @ of Page 20, 2 Kbytes */
#define ADDR_FLASH_PAGE_21    ((uint32_t)0x0800A800) /* Base @ of Page 21, 2 Kbytes */
#define ADDR_FLASH_PAGE_22    ((uint32_t)0x0800B000) /* Base @ of Page 22, 2 Kbytes */
#define ADDR_FLASH_PAGE_23    ((uint32_t)0x0800B800) /* Base @ of Page 23, 2 Kbytes */
#define ADDR_FLASH_PAGE_24    ((uint32_t)0x0800C000) /* Base @ of Page 24, 2 Kbytes */
#define ADDR_FLASH_PAGE_25    ((uint32_t)0x0800C800) /* Base @ of Page 25, 2 Kbytes */
#define ADDR_FLASH_PAGE_26    ((uint32_t)0x0800D000) /* Base @ of Page 26, 2 Kbytes */
#define ADDR_FLASH_PAGE_27    ((uint32_t)0x0800D800) /* Base @ of Page 27, 2 Kbytes */
#define ADDR_FLASH_PAGE_28    ((uint32_t)0x0800E000) /* Base @ of Page 28, 2 Kbytes */
#define ADDR_FLASH_PAGE_29    ((uint32_t)0x0800E800) /* Base @ of Page 29, 2 Kbytes */
#define ADDR_FLASH_PAGE_30    ((uint32_t)0x0800F000) /* Base @ of Page 30, 2 Kbytes */
#define ADDR_FLASH_PAGE_31    ((uint32_t)0x0800F800) /* Base @ of Page 31, 2 Kbytes */
#define ADDR_FLASH_PAGE_32    ((uint32_t)0x08010000) /* Base @ of Page 32, 2 Kbytes */
#define ADDR_FLASH_PAGE_33    ((uint32_t)0x08010800) /* Base @ of Page 33, 2 Kbytes */
#define ADDR_FLASH_PAGE_34    ((uint32_t)0x08011000) /* Base @ of Page 34, 2 Kbytes */
#define ADDR_FLASH_PAGE_35    ((uint32_t)0x08011800) /* Base @ of Page 35, 2 Kbytes */
#define ADDR_FLASH_PAGE_36    ((uint32_t)0x08012000) /* Base @ of Page 36, 2 Kbytes */
#define ADDR_FLASH_PAGE_37    ((uint32_t)0x08012800) /* Base @ of Page 37, 2 Kbytes */
#define ADDR_FLASH_PAGE_38    ((uint32_t)0x08013000) /* Base @ of Page 38, 2 Kbytes */
#define ADDR_FLASH_PAGE_39    ((uint32_t)0x08013800) /* Base @ of Page 39, 2 Kbytes */
#define ADDR_FLASH_PAGE_40    ((uint32_t)0x08014000) /* Base @ of Page 40, 2 Kbytes */
#define ADDR_FLASH_PAGE_41    ((uint32_t)0x08014800) /* Base @ of Page 41, 2 Kbytes */
#define ADDR_FLASH_PAGE_42    ((uint32_t)0x08015000) /* Base @ of Page 42, 2 Kbytes */
#define ADDR_FLASH_PAGE_43    ((uint32_t)0x08015800) /* Base @ of Page 43, 2 Kbytes */
#define ADDR_FLASH_PAGE_44    ((uint32_t)0x08016000) /* Base @ of Page 44, 2 Kbytes */
#define ADDR_FLASH_PAGE_45    ((uint32_t)0x08016800) /* Base @ of Page 45, 2 Kbytes */
#define ADDR_FLASH_PAGE_46    ((uint32_t)0x08017000) /* Base @ of Page 46, 2 Kbytes */
#define ADDR_FLASH_PAGE_47    ((uint32_t)0x08017800) /* Base @ of Page 47, 2 Kbytes */
#define ADDR_FLASH_PAGE_48    ((uint32_t)0x08018000) /* Base @ of Page 48, 2 Kbytes */
#define ADDR_FLASH_PAGE_49    ((uint32_t)0x08018800) /* Base @ of Page 49, 2 Kbytes */
#define ADDR_FLASH_PAGE_50    ((uint32_t)0x08019000) /* Base @ of Page 50, 2 Kbytes */
#define ADDR_FLASH_PAGE_51    ((uint32_t)0x08019800) /* Base @ of Page 51, 2 Kbytes */
#define ADDR_FLASH_PAGE_52    ((uint32_t)0x0801A000) /* Base @ of Page 52, 2 Kbytes */
#define ADDR_FLASH_PAGE_53    ((uint32_t)0x0801A800) /* Base @ of Page 53, 2 Kbytes */
#define ADDR_FLASH_PAGE_54    ((uint32_t)0x0801B000) /* Base @ of Page 54, 2 Kbytes */
#define ADDR_FLASH_PAGE_55    ((uint32_t)0x0801B800) /* Base @ of Page 55, 2 Kbytes */
#define ADDR_FLASH_PAGE_56    ((uint32_t)0x0801C000) /* Base @ of Page 56, 2 Kbytes */
#define ADDR_FLASH_PAGE_57    ((uint32_t)0x0801C800) /* Base @ of Page 57, 2 Kbytes */
#define ADDR_FLASH_PAGE_58    ((uint32_t)0x0801D000) /* Base @ of Page 58, 2 Kbytes */
#define ADDR_FLASH_PAGE_59    ((uint32_t)0x0801D800) /* Base @ of Page 59, 2 Kbytes */
#define ADDR_FLASH_PAGE_60    ((uint32_t)0x0801E000) /* Base @ of Page 60, 2 Kbytes */
#define ADDR_FLASH_PAGE_61    ((uint32_t)0x0801E800) /* Base @ of Page 61, 2 Kbytes */
#define ADDR_FLASH_PAGE_62    ((uint32_t)0x0801F000) /* Base @ of Page 62, 2 Kbytes */
#define ADDR_FLASH_PAGE_63    ((uint32_t)0x0801F800) /* Base @ of Page 63, 2 Kbytes */
#define ADDR_FLASH_PAGE_64	((uint32_t)0x08020000) /* Base @ of Page 64, 2 Kbytes */
#define ADDR_FLASH_PAGE_65	((uint32_t)0x08020800) /* Base @ of Page 65, 2 Kbytes */
#define ADDR_FLASH_PAGE_66	((uint32_t)0x08021000) /* Base @ of Page 66, 2 Kbytes */
#define ADDR_FLASH_PAGE_67	((uint32_t)0x08021800) /* Base @ of Page 67, 2 Kbytes */
#define ADDR_FLASH_PAGE_68	((uint32_t)0x08022000) /* Base @ of Page 68, 2 Kbytes */
#define ADDR_FLASH_PAGE_69	((uint32_t)0x08022800) /* Base @ of Page 69, 2 Kbytes */
#define ADDR_FLASH_PAGE_70	((uint32_t)0x08023000) /* Base @ of Page 70, 2 Kbytes */
#define ADDR_FLASH_PAGE_71	((uint32_t)0x08023800) /* Base @ of Page 71, 2 Kbytes */
#define ADDR_FLASH_PAGE_72	((uint32_t)0x08024000) /* Base @ of Page 72, 2 Kbytes */
#define ADDR_FLASH_PAGE_73	((uint32_t)0x08024800) /* Base @ of Page 73, 2 Kbytes */
#define ADDR_FLASH_PAGE_74	((uint32_t)0x08025000) /* Base @ of Page 74, 2 Kbytes */
#define ADDR_FLASH_PAGE_75	((uint32_t)0x08025800) /* Base @ of Page 75, 2 Kbytes */
#define ADDR_FLASH_PAGE_76	((uint32_t)0x08026000) /* Base @ of Page 76, 2 Kbytes */
#define ADDR_FLASH_PAGE_77	((uint32_t)0x08026800) /* Base @ of Page 77, 2 Kbytes */
#define ADDR_FLASH_PAGE_78	((uint32_t)0x08027000) /* Base @ of Page 78, 2 Kbytes */
#define ADDR_FLASH_PAGE_79	((uint32_t)0x08027800) /* Base @ of Page 79, 2 Kbytes */
#define ADDR_FLASH_PAGE_80	((uint32_t)0x08028000) /* Base @ of Page 80, 2 Kbytes */
#define ADDR_FLASH_PAGE_81	((uint32_t)0x08028800) /* Base @ of Page 81, 2 Kbytes */
#define ADDR_FLASH_PAGE_82	((uint32_t)0x08029000) /* Base @ of Page 82, 2 Kbytes */
#define ADDR_FLASH_PAGE_83	((uint32_t)0x08029800) /* Base @ of Page 83, 2 Kbytes */
#define ADDR_FLASH_PAGE_84	((uint32_t)0x0802A000) /* Base @ of Page 84, 2 Kbytes */
#define ADDR_FLASH_PAGE_85	((uint32_t)0x0802A800) /* Base @ of Page 85, 2 Kbytes */
#define ADDR_FLASH_PAGE_86	((uint32_t)0x0802B000) /* Base @ of Page 86, 2 Kbytes */
#define ADDR_FLASH_PAGE_87	((uint32_t)0x0802B800) /* Base @ of Page 87, 2 Kbytes */
#define ADDR_FLASH_PAGE_88	((uint32_t)0x0802C000) /* Base @ of Page 88, 2 Kbytes */
#define ADDR_FLASH_PAGE_89	((uint32_t)0x0802C800) /* Base @ of Page 89, 2 Kbytes */
#define ADDR_FLASH_PAGE_90	((uint32_t)0x0802D000) /* Base @ of Page 90, 2 Kbytes */
#define ADDR_FLASH_PAGE_91	((uint32_t)0x0802D800) /* Base @ of Page 91, 2 Kbytes */
#define ADDR_FLASH_PAGE_92	((uint32_t)0x0802E000) /* Base @ of Page 92, 2 Kbytes */
#define ADDR_FLASH_PAGE_93	((uint32_t)0x0802E800) /* Base @ of Page 93, 2 Kbytes */
#define ADDR_FLASH_PAGE_94	((uint32_t)0x0802F000) /* Base @ of Page 94, 2 Kbytes */
#define ADDR_FLASH_PAGE_95	((uint32_t)0x0802F800) /* Base @ of Page 95, 2 Kbytes */
#define ADDR_FLASH_PAGE_96	((uint32_t)0x08030000) /* Base @ of Page 96, 2 Kbytes */
#define ADDR_FLASH_PAGE_97	((uint32_t)0x08030800) /* Base @ of Page 97, 2 Kbytes */
#define ADDR_FLASH_PAGE_98	((uint32_t)0x08031000) /* Base @ of Page 98, 2 Kbytes */
#define ADDR_FLASH_PAGE_99	((uint32_t)0x08031800) /* Base @ of Page 99, 2 Kbytes */
#define ADDR_FLASH_PAGE_100	((uint32_t)0x08032000) /* Base @ of Page 100, 2 Kbytes */
#define ADDR_FLASH_PAGE_101	((uint32_t)0x08032800) /* Base @ of Page 101, 2 Kbytes */
#define ADDR_FLASH_PAGE_102	((uint32_t)0x08033000) /* Base @ of Page 102, 2 Kbytes */
#define ADDR_FLASH_PAGE_103	((uint32_t)0x08033800) /* Base @ of Page 103, 2 Kbytes */
#define ADDR_FLASH_PAGE_104	((uint32_t)0x08034000) /* Base @ of Page 104, 2 Kbytes */
#define ADDR_FLASH_PAGE_105	((uint32_t)0x08034800) /* Base @ of Page 105, 2 Kbytes */
#define ADDR_FLASH_PAGE_106	((uint32_t)0x08035000) /* Base @ of Page 106, 2 Kbytes */
#define ADDR_FLASH_PAGE_107	((uint32_t)0x08035800) /* Base @ of Page 107, 2 Kbytes */
#define ADDR_FLASH_PAGE_108	((uint32_t)0x08036000) /* Base @ of Page 108, 2 Kbytes */
#define ADDR_FLASH_PAGE_109	((uint32_t)0x08036800) /* Base @ of Page 109, 2 Kbytes */
#define ADDR_FLASH_PAGE_110	((uint32_t)0x08037000) /* Base @ of Page 110, 2 Kbytes */
#define ADDR_FLASH_PAGE_111	((uint32_t)0x08037800) /* Base @ of Page 111, 2 Kbytes */
#define ADDR_FLASH_PAGE_112	((uint32_t)0x08038000) /* Base @ of Page 112, 2 Kbytes */
#define ADDR_FLASH_PAGE_113	((uint32_t)0x08038800) /* Base @ of Page 113, 2 Kbytes */
#define ADDR_FLASH_PAGE_114	((uint32_t)0x08039000) /* Base @ of Page 114, 2 Kbytes */
#define ADDR_FLASH_PAGE_115	((uint32_t)0x08039800) /* Base @ of Page 115, 2 Kbytes */
#define ADDR_FLASH_PAGE_116	((uint32_t)0x0803A000) /* Base @ of Page 116, 2 Kbytes */
#define ADDR_FLASH_PAGE_117	((uint32_t)0x0803A800) /* Base @ of Page 117, 2 Kbytes */
#define ADDR_FLASH_PAGE_118	((uint32_t)0x0803B000) /* Base @ of Page 118, 2 Kbytes */
#define ADDR_FLASH_PAGE_119	((uint32_t)0x0803B800) /* Base @ of Page 119, 2 Kbytes */
#define ADDR_FLASH_PAGE_120	((uint32_t)0x0803C000) /* Base @ of Page 120, 2 Kbytes */
#define ADDR_FLASH_PAGE_121	((uint32_t)0x0803C800) /* Base @ of Page 121, 2 Kbytes */
#define ADDR_FLASH_PAGE_122	((uint32_t)0x0803D000) /* Base @ of Page 122, 2 Kbytes */
#define ADDR_FLASH_PAGE_123	((uint32_t)0x0803D800) /* Base @ of Page 123, 2 Kbytes */
#define ADDR_FLASH_PAGE_124	((uint32_t)0x0803E000) /* Base @ of Page 124, 2 Kbytes */
#define ADDR_FLASH_PAGE_125	((uint32_t)0x0803E800) /* Base @ of Page 125, 2 Kbytes */
#define ADDR_FLASH_PAGE_126	((uint32_t)0x0803F000) /* Base @ of Page 126, 2 Kbytes */
#define ADDR_FLASH_PAGE_127	((uint32_t)0x0803F800) /* Base @ of Page 127, 2 Kbytes */

 

本帖最后由 nengzhi 于 2024-6-3 17:38 编辑

回复评论 (1)

感谢楼主的评测分享,这一章内容非常多呀,期待您的最终作品程现!

点赞  2024-6-3 20:58
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复