首頁 > 評(píng)測(cè) > RTT-Studio環(huán)境下的APM32外設(shè)驅(qū)動(dòng)使用指南
RTT-Studio環(huán)境下的APM32外設(shè)驅(qū)動(dòng)使用指南
- [導(dǎo)讀]
- 本帖最后由 luobeihai 于 2023-4-19 00:08 編輯 #申請(qǐng)?jiān)瓌?chuàng)# @21小跑堂 1. 簡介由于自己平時(shí)在項(xiàng)目中經(jīng)常使用 APM32 系列的 MCU,而且經(jīng)常是和 RT-Thread 系統(tǒng)一起使用,慢慢的就對(duì) APM32 系列 MCU 的
本帖最后由 luobeihai 于 2023-4-19 00:08 編輯
#申請(qǐng)?jiān)瓌?chuàng)# @21小跑堂
1. 簡介
2. 新建RTT-Studio工程
2.1 下載APM32F4軟件支持包
2.2 基于芯片新建一個(gè) APM32F407 的工程
3. apm32_msp.c 文件介紹
4. UART設(shè)備
4.1 確定串口引腳,修改串口GPIO初始化代碼
- void apm32_usart_init(void)
- {
- GPIO_Config_T GPIO_ConfigStruct;
- #ifdef BSP_USING_UART6
- RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOC);
- RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_USART6);
- GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_6, GPIO_AF_USART6);
- GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_7, GPIO_AF_USART6);
- GPIO_ConfigStruct.pin = GPIO_PIN_6 | GPIO_PIN_7;
- GPIO_ConfigStruct.mode = GPIO_MODE_AF;
- GPIO_ConfigStruct.otype = GPIO_OTYPE_PP;
- GPIO_ConfigStruct.pupd = GPIO_PUPD_UP;
- GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
- GPIO_Config(GPIOC, &GPIO_ConfigStruct);
- #endif
- }
4.2 在board.h中修改UART端口號(hào)
4.3 在 rtconfig.h 文件中修改控制臺(tái)所需要的串口設(shè)備
5. ADC設(shè)備
5.1 使能ADC外設(shè)驅(qū)動(dòng)
5.2 在board.h文件中定義ADC宏
5.3 ADC設(shè)備測(cè)試方法
- adc probe <adc_name> - probe adc by name
- adc read <channel> - read adc value on the channel
- adc disable <channel> - disable adc channel
- adc enable <channel> - enable adc channel
6. PWM設(shè)備
6.1 使能PWM外設(shè)驅(qū)動(dòng)
6.2 在board.h文件中定義PWM外設(shè)相關(guān)的宏
6.3 在apm32_msp.c文件中添加定時(shí)器通道初始化代碼
- void apm32_msp_timer_init(void *Instance)
- {
- #ifdef BSP_USING_PWM3
- GPIO_Config_T gpio_config;
- TMR_T *tmr_x = (TMR_T *)Instance;
- if (tmr_x == TMR3)
- {
- RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOC);
- RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR3);
- /* TMR3 channel 1 gpio init */
- GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_6, GPIO_AF_TMR3);
- gpio_config.pin = GPIO_PIN_6;
- gpio_config.mode = GPIO_MODE_AF;
- gpio_config.otype = GPIO_OTYPE_PP;
- gpio_config.speed = GPIO_SPEED_50MHz;
- GPIO_Config(GPIOC, &gpio_config);
- /* TMR3 channel 2 gpio init */
- GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_7, GPIO_AF_TMR3);
- gpio_config.pin = GPIO_PIN_7;
- GPIO_Config(GPIOC, &gpio_config);
- /* TMR3 channel 3 gpio init */
- GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_8, GPIO_AF_TMR3);
- gpio_config.pin = GPIO_PIN_8;
- GPIO_Config(GPIOC, &gpio_config);
- /* TMR3 channel 4 gpio init */
- GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_9, GPIO_AF_TMR3);
- gpio_config.pin = GPIO_PIN_9;
- GPIO_Config(GPIOC, &gpio_config);
- }
- #endif
- }
6.4 PWM設(shè)備使用示例
- /*
- * 程序清單:這是一個(gè) PWM 設(shè)備使用例程
- * 例程導(dǎo)出了 pwm_led_sample 命令到控制終端
- * 命令調(diào)用格式:pwm_led_sample
- * 程序功能:通過 PWM 設(shè)備控制 LED 燈的亮度,可以看到LED不停的由暗變到亮,然后又從亮變到暗。
- */
- #include <rtthread.h>
- #include <rtdevice.h>
- #define PWM_DEV_NAME "pwm3" /* PWM設(shè)備名稱 */
- #define PWM_DEV_CHANNEL 4 /* PWM通道 */
- struct rt_device_pwm *pwm_dev; /* PWM設(shè)備句柄 */
- static int pwm_led_sample(int argc, char *argv[])
- {
- rt_uint32_t period, pulse, dir;
- period = 500000; /* 周期為0.5ms,單位為納秒ns */
- dir = 1; /* PWM脈沖寬度值的增減方向 */
- pulse = 0; /* PWM脈沖寬度值,單位為納秒ns */
- /* 查找設(shè)備 */
- pwm_dev = (struct rt_device_pwm *)rt_device_find(PWM_DEV_NAME);
- if (pwm_dev == RT_NULL)
- {
- rt_kprintf("pwm sample run failed! can't find %s device!\n", PWM_DEV_NAME);
- return RT_ERROR;
- }
- /* 設(shè)置PWM周期和脈沖寬度默認(rèn)值 */
- rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse);
- /* 使能設(shè)備 */
- rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL);
- while (1)
- {
- rt_thread_mdelay(50);
- if (dir)
- {
- pulse += 5000; /* 從0值開始每次增加5000ns */
- }
- else
- {
- pulse -= 5000; /* 從最大值開始每次減少5000ns */
- }
- if (pulse >= period)
- {
- dir = 0;
- }
- if (0 == pulse)
- {
- dir = 1;
- }
- /* 設(shè)置PWM周期和脈沖寬度 */
- rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse);
- }
- }
- /* 導(dǎo)出到 msh 命令列表中 */
- MSH_CMD_EXPORT(pwm_led_sample, pwm sample);
7. SPI設(shè)備
7.1 使能SPI外設(shè)驅(qū)動(dòng)和串行Flash驅(qū)動(dòng)程序
7.2 在board.h文件中定義SPI相關(guān)的宏
7.3 在apm32_msp.c中編寫SPI外設(shè)引腳的初始化代碼
- void apm32_msp_spi_init(void *Instance)
- {
- #if defined (BSP_USING_SPI1) || defined (BSP_USING_SPI2) || defined (BSP_USING_SPI3)
- GPIO_Config_T gpioConfig;
- SPI_T *spi_x = (SPI_T *)Instance;
- if(spi_x == SPI1)
- {
- /* Enable related Clock */
- RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOB);
- RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SPI1);
- RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SYSCFG);
- /* Config SPI1 PinAF */
- GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_3, GPIO_AF_SPI1);
- GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_4, GPIO_AF_SPI1);
- GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_5, GPIO_AF_SPI1);
- /* Config SPI GPIO, SCK=PB3, MISO=PB4, MOSI=PB5 */
- GPIO_ConfigStructInit(&gpioConfig);
- gpioConfig.pin = GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5;
- gpioConfig.speed = GPIO_SPEED_100MHz;
- gpioConfig.mode = GPIO_MODE_AF;
- gpioConfig.otype = GPIO_OTYPE_PP;
- gpioConfig.pupd = GPIO_PUPD_NOPULL;
- GPIO_Config(GPIOB, &gpioConfig);
- }
- #endif
- }
7.4 掛載SPI設(shè)備
- #include <rtthread.h>
- #include "spi_flash.h"
- #include "spi_flash_sfud.h"
- #include "drv_spi.h"
- static int rt_hw_spi_flash_init(void)
- {
- RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOG);
- rt_hw_spi_device_attach("spi1", "spi10", GPIOG, GPIO_PIN_8);
- if (RT_NULL == rt_sfud_flash_probe("W25Q128", "spi10"))
- {
- return -RT_ERROR;
- }
- return RT_EOK;
- }
- INIT_COMPONENT_EXPORT(rt_hw_spi_flash_init);
8. CAN設(shè)備
8.1 使能CAN外設(shè)驅(qū)動(dòng)
8.2 在board.h定義與CAN外設(shè)相關(guān)的宏
- #define BSP_USING_CAN1
- #define BSP_USING_CAN2
8.3 在apm32_msp.c文件中編寫CAN引腳初始化代碼
- void apm32_msp_can_init(void *Instance)
- {
- #if defined(BSP_USING_CAN1) || defined(BSP_USING_CAN2)
- GPIO_Config_T GPIO_InitStructure;
- CAN_T *CANx = (CAN_T *)Instance;
- if (CAN1 == CANx)
- {
- RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_CAN1);
- RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOB);
- /* PB8: CAN1_RX, PB9: CAN1_TX */
- GPIO_InitStructure.pin = GPIO_PIN_8 | GPIO_PIN_9;
- GPIO_InitStructure.mode = GPIO_MODE_AF;
- GPIO_InitStructure.otype = GPIO_OTYPE_PP;
- GPIO_InitStructure.speed = GPIO_SPEED_100MHz;
- GPIO_InitStructure.pupd = GPIO_PUPD_UP;
- GPIO_Config(GPIOB, &GPIO_InitStructure);
- GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_8, GPIO_AF_CAN1);
- GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_9, GPIO_AF_CAN1);
- }
- else if (CAN2 == CANx)
- {
- /* When using the CAN2 peripheral, the CAN1 clock must be turned on */
- RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_CAN1);
- RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_CAN2);
- RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOB);
- /* PB12: CAN2_RX, PB13: CAN2_TX */
- GPIO_InitStructure.pin = GPIO_PIN_12 | GPIO_PIN_13;
- GPIO_InitStructure.mode = GPIO_MODE_AF;
- GPIO_InitStructure.otype = GPIO_OTYPE_PP;
- GPIO_InitStructure.speed = GPIO_SPEED_100MHz;
- GPIO_InitStructure.pupd = GPIO_PUPD_UP;
- GPIO_Config(GPIOB, &GPIO_InitStructure);
- GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_12, GPIO_AF_CAN2);
- GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_13, GPIO_AF_CAN2);
- }
- #endif
- }
8.4 CAN設(shè)備使用示例
-
首先把文檔中的示例代碼復(fù)制到main.c文件,然后編譯下載。
-
使用CAN分析儀連接到你板子的CANH和CANL(我所使用的是創(chuàng)芯科技的CAN分析儀)。
-
打開創(chuàng)芯科技的CAN分析儀上位機(jī)軟件,然后按照1M的波特率啟動(dòng)設(shè)備(因?yàn)镃AN驅(qū)動(dòng)程序默認(rèn)的波特率是1M,如果你修改了CAN驅(qū)動(dòng)程序中的波特率,那么CAN接收數(shù)據(jù)的上位機(jī)設(shè)置的波特率要與之對(duì)應(yīng))。
-
在串口終端運(yùn)行 can_sample 這個(gè)命令。
-
然后查看 CAN 上位機(jī)工具是否接收到了開發(fā)板發(fā)送的CAN數(shù)據(jù)。
-
也可以提供CAN上位機(jī)發(fā)送數(shù)據(jù)到開發(fā)板,然后板子會(huì)把接收到的數(shù)據(jù)打印出來。
9. SDIO設(shè)備
9.1 使能SDIO外設(shè)驅(qū)動(dòng)以及FatFs
9.2 在board.h文件中定義SDIO外設(shè)相關(guān)的宏
9.3 在apm32_msp.c文件中編寫SDIO引腳初始化代碼
- void apm32_msp_sdio_init(void *Instance)
- {
- #ifdef BSP_USING_SDIO
- GPIO_Config_T GPIO_InitStructure;
- /* Enable the GPIO Clock */
- RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOC | RCM_AHB1_PERIPH_GPIOD);
- /* Enable the SDIO Clock */
- RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SDIO);
- /* Enable the SDIO peripheral reset */
- RCM_EnableAPB2PeriphReset(RCM_APB2_PERIPH_SDIO);
- /* Configure the GPIO pin */
- GPIO_InitStructure.pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;
- GPIO_InitStructure.mode = GPIO_MODE_AF;
- GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
- GPIO_InitStructure.otype = GPIO_OTYPE_PP;
- GPIO_InitStructure.pupd = GPIO_PUPD_UP;
- GPIO_Config(GPIOC, &GPIO_InitStructure);
- GPIO_InitStructure.pin = GPIO_PIN_2;
- GPIO_Config(GPIOD, &GPIO_InitStructure);
- GPIO_ConfigPinAF(GPIOC,GPIO_PIN_SOURCE_8, GPIO_AF_SDIO);
- GPIO_ConfigPinAF(GPIOC,GPIO_PIN_SOURCE_9, GPIO_AF_SDIO);
- GPIO_ConfigPinAF(GPIOC,GPIO_PIN_SOURCE_10, GPIO_AF_SDIO);
- GPIO_ConfigPinAF(GPIOC,GPIO_PIN_SOURCE_11, GPIO_AF_SDIO);
- GPIO_ConfigPinAF(GPIOC,GPIO_PIN_SOURCE_12, GPIO_AF_SDIO);
- GPIO_ConfigPinAF(GPIOD,GPIO_PIN_SOURCE_2, GPIO_AF_SDIO);
- /* Disable the SDIO peripheral reset */
- RCM_DisableAPB2PeriphReset(RCM_APB2_PERIPH_SDIO);
- #endif
- }
9.4 SD卡掛載elm FatFs文件系統(tǒng)
- #include <dfs_elm.h>
- #include <dfs_fs.h>
- #include <dfs_file.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <sys/stat.h>
- #include <sys/statfs.h>
- void sd_mount(void *parameter)
- {
- while (1)
- {
- rt_thread_mdelay(500);
- if(rt_device_find("sd0") != RT_NULL)
- {
- if (dfs_mount("sd0", "/", "elm", 0, 0) == RT_EOK)
- {
- LOG_I("sd card mount to '/'");
- break;
- }
- else
- {
- LOG_W("sd card mount to '/' failed!");
- }
- }
- }
- }
- int apm32_sdcard_mount(void)
- {
- rt_thread_t tid;
- tid = rt_thread_create("sd_mount", sd_mount, RT_NULL,
- 2048, RT_THREAD_PRIORITY_MAX - 2, 20);
- if (tid != RT_NULL)
- {
- rt_thread_startup(tid);
- }
- else
- {
- LOG_E("create sd_mount thread err!");
- }
- return RT_EOK;
- }
- INIT_APP_EXPORT(apm32_sdcard_mount);
10. ETH設(shè)備
10.1 使能LwIP堆棧
10.2 在board.h中定義以太網(wǎng)相關(guān)的宏
10.3 在apm32_msp.c文件中添加ETH外設(shè)初始化代碼
- void apm32_msp_eth_init(void *Instance)
- {
- #ifdef BSP_USING_ETH
- GPIO_Config_T GPIO_ConfigStruct;
- /* Enable SYSCFG clock */
- RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SYSCFG);
- /* Enable GPIOs clocks */
- RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOA | RCM_AHB1_PERIPH_GPIOC | RCM_AHB1_PERIPH_GPIOG);
- /* MII/RMII Media interface selection */
- SYSCFG_ConfigMediaInterface(SYSCFG_INTERFACE_RMII);
- /*********************** Ethernet pins configuration ***************************/
- /*
- ETH_MDIO -------------------------> PA2
- ETH_MDC --------------------------> PC1
- ETH_MII_RX_CLK/ETH_RMII_REF_CLK---> PA1
- ETH_MII_RX_DV/ETH_RMII_CRS_DV ----> PA7
- ETH_MII_RXD0/ETH_RMII_RXD0 -------> PC4
- ETH_MII_RXD1/ETH_RMII_RXD1 -------> PC5
- ETH_MII_TX_EN/ETH_RMII_TX_EN -----> PG11
- ETH_MII_TXD0/ETH_RMII_TXD0 -------> PG13
- ETH_MII_TXD1/ETH_RMII_TXD1 -------> PG14
- */
- /* Configure PC1, PC4 and PC5 */
- GPIO_ConfigStruct.pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5;
- GPIO_ConfigStruct.speed = GPIO_SPEED_100MHz;
- GPIO_ConfigStruct.mode = GPIO_MODE_AF;
- GPIO_ConfigStruct.otype = GPIO_OTYPE_PP;
- GPIO_ConfigStruct.pupd = GPIO_PUPD_NOPULL;
- GPIO_Config(GPIOC, &GPIO_ConfigStruct);
- GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_1, GPIO_AF_ETH);
- GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_4, GPIO_AF_ETH);
- GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_5, GPIO_AF_ETH);
- /* Configure PG11, PG13 and PG14 */
- GPIO_ConfigStruct.pin = GPIO_PIN_11 | GPIO_PIN_13 | GPIO_PIN_14;
- GPIO_Config(GPIOG, &GPIO_ConfigStruct);
- GPIO_ConfigPinAF(GPIOG, GPIO_PIN_SOURCE_11, GPIO_AF_ETH);
- GPIO_ConfigPinAF(GPIOG, GPIO_PIN_SOURCE_13, GPIO_AF_ETH);
- GPIO_ConfigPinAF(GPIOG, GPIO_PIN_SOURCE_14, GPIO_AF_ETH);
- /* Configure PA1, PA2 and PA7 */
- GPIO_ConfigStruct.pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7;
- GPIO_Config(GPIOA, &GPIO_ConfigStruct);
- GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_1, GPIO_AF_ETH);
- GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_2, GPIO_AF_ETH);
- GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_7, GPIO_AF_ETH);
- #endif
- }
10.4 添加 phy 芯片復(fù)位函數(shù)
- void phy_reset(void)
- {
- /* phy復(fù)位相關(guān)代碼 */
- }
10.5 網(wǎng)絡(luò)功能測(cè)試
11. SDRAM設(shè)備
11.1 打開SDRAM相關(guān)的代碼
11.2 修改SDRAM時(shí)序參數(shù)以及行、列、大小等參數(shù)
- /**
- * [url=home.php?mod=space&uid=247401]@brief[/url] Timing config definition
- */
- typedef struct
- {
- uint32_t latencyCAS : 2; /*!< DMC_CAS_LATENCY_T */
- uint32_t tRAS : 4; /*!< DMC_RAS_MINIMUM_T */
- uint32_t tRCD : 3; /*!< DMC_DELAY_TIME_T */
- uint32_t tRP : 3; /*!< DMC_PRECHARGE_T */
- uint32_t tWR : 2; /*!< DMC_NEXT_PRECHARGE_T */
- uint32_t tARP : 4; /*!< DMC_AUTO_REFRESH_T */
- uint32_t tCMD : 4; /*!< DMC_ATA_CMD_T */
- uint32_t tXSR : 9; /*!< auto-refresh commands, can be 0x000 to 0x1FF */
- uint16_t tRFP : 16; /*!< Refresh period, can be 0x0000 to 0xFFFF */
- } DMC_TimingConfig_T;
- /**
- * [url=home.php?mod=space&uid=247401]@brief[/url] Config struct definition
- */
- typedef struct
- {
- DMC_BANK_WIDTH_T bankWidth; /*!< Number of bank bits */
- DMC_ROW_WIDTH_T rowWidth; /*!< Number of row address bits */
- DMC_COL_WIDTH_T colWidth; /*!< Number of col address bits */
- DMC_CLK_PHASE_T clkPhase; /*!< Clock phase */
- DMC_TimingConfig_T timing; /*!< Timing */
- } DMC_Config_T;
11.3 SDRAM測(cè)試
12. 總結(jié)
-
首先使能某個(gè)外設(shè)驅(qū)動(dòng)設(shè)備
-
在board.h文件中定義該外設(shè)驅(qū)動(dòng)相關(guān)的宏
-
在apm32_msp.c文件中添加對(duì)應(yīng)外設(shè)驅(qū)動(dòng)的引腳初始化代碼(當(dāng)然有些簡單的外設(shè),已經(jīng)把引腳的初始化代碼寫到了外設(shè)驅(qū)動(dòng)中,不需要我們?cè)倬帉懥,我們可以查看?duì)應(yīng)外設(shè)驅(qū)動(dòng)代碼是否有把引腳的初始化代碼寫進(jìn)去了)
-
根據(jù)RTT的官方的文檔介紹,添加外設(shè)驅(qū)動(dòng)的使用代碼。
- 本文系21ic原創(chuàng),未經(jīng)許可禁止轉(zhuǎn)載!
網(wǎng)友評(píng)論
- 聯(lián)系人:巧克力娃娃
- 郵箱:board@21ic.com
- 我要投稿
-
歡迎入駐,開放投稿
- NRF52810藍(lán)牙數(shù)字耳機(jī)找人定制
預(yù)算:¥30005天前
- 125KW模塊式PCS軟硬件外包開發(fā)
預(yù)算:¥1100000015小時(shí)前
- 12V汽車啟動(dòng)電源項(xiàng)目BMS設(shè)計(jì)
預(yù)算:¥50000023小時(shí)前
- 數(shù)據(jù)可視化軟件 開發(fā)
預(yù)算:¥5000023小時(shí)前
- PLC項(xiàng)目調(diào)試修改
預(yù)算:¥100001天前
- 起動(dòng)電機(jī)控制器開發(fā)
預(yù)算:¥1100001天前