TDC7201 全部寄存器完整功能手册前置说明1. TDC7201 内部包含两路独立 TDC 内核TDC1 / TDC2两套寄存器完全独立通过 CSB1 / CSB2 片选区分下文统一前缀 TDCx_ 代表任意一路内核寄存器2. 寄存器地址范围 00h ~ 1Ch分为配置寄存器、中断寄存器、溢出阈值寄存器、STOP 屏蔽寄存器、测量结果寄存器、校准寄存器六大类3. 8 位寄存器单字节读写24 位寄存器TIME/CLOCK_COUNT/CALIBRATION3 字节 SPI 读取Bit23 为奇偶校验位Bit22~0 为有效计数值。/////////////////////////////////////////////////////////////////////////////////////////////////////////一、基础配置寄存器00h / 01h8 位可读写1. 地址 00h TDCx_CONFIG1 主配置寄存器复位 00h位 位名称 详细功能D7 FORCE_CAL 强制校准使能0测量正常结束自动校准溢出 / 无 STOP 中断时不校准1无论测量是否异常终止强制执行自校准D6 PARITY_EN 奇偶校验开关0TIME/CLOCK_COUNT/CALIBRATION 寄存器校验位恒 01开启偶校验读取可校验数据传输错误D5 TRIGG_EDGE TRIGG 输出脉冲边沿0上升沿输出触发信号1下降沿输出触发信号D4 STOP_EDGE STOP 信号触发边沿0上升沿停止计时推荐高精度场景1下降沿停止计时D3 START_EDGE START 信号触发边沿0上升沿启动计时推荐1下降沿启动计时D2~D1 MEAS_MODE 测量模式选择00模式 112ns~2000ns 短测距仅环振计数01模式 2250ns~8ms 长测距推荐通用10/11硬件保留禁止使用D0 START_MEAS 测量启动位写 1清空所有测量寄存器、输出 TRIG 触发脉冲、启动一次完整测量测量完成后硬件自动清零2. 地址 01hTDCx_CONFIG2 高级配置寄存器复位 40h位 位名称 详细功能D7~D6 CALIBRATION2_PERIODS 二次校准时钟周期数决定校准精度002 个外部时钟0110默认10201140D5~D3 AVG_CYCLES 多周期平均次数低功耗 MCU 休眠模式000单次测量关闭平均0012 / 0104 / 0118 / 10016 / 10132 / 11064 / 111128平均模式下 CLOCK_COUNT 读取后需右移 log2 (次数) 再计算 TOFD2~D0 NUM_STOP 可采集 STOP 脉冲最大数量000单 STOP0012010301141005101/110/111无效强制单路 STOP/////////////////////////////////////////////////////////////////////////////////////////////////////////二、中断控制寄存器02h / 03h8 位3. 地址 02hTDCx_INT_STATUS 中断状态寄存器复位 00h写 1 清零标志存储所有测量 / 溢出事件状态仅写 1 可清除对应标志只读不会清零位 位名称 详细功能D7~D5 Reserved 硬件保留固定 0D4 MEAS_COMPLETE_FLAG 测量完成总标志1一组平均 / 单次测量全部结束写 1 清零D3 MEAS_STARTED_FLAG 测量启动标志1已捕获 START 脉冲计时开始写 1 清零D2 CLOCK_CNTR_OVF_INT 时钟粗计数器溢出中断1外部时钟计数超限测量立即终止写 1 清零D1 COARSE_CNTR_OVF_INT 环振粗计数器溢出中断1短时间环振计数超限测量终止写 1 清零D0 NEW_MEAS_INT 新测量完成主中断INTB 引脚触发源1全部 STOP 采集完成拉低 INTB写 1 清零4. 地址 03hTDCx_INT_MASK 中断屏蔽寄存器复位 07h控制中断是否输出到硬件INTB引脚寄存器状态位不受屏蔽影响位 位名称 详细功能D7~D3 Reserved 硬件保留固定 0D2 CLOCK_CNTR_OVF_MASK 时钟溢出中断屏蔽1溢出时 INTB 拉低输出中断0仅寄存器置位引脚无电平变化D1 COARSE_CNTR_OVF_MASK 环振溢出中断屏蔽1溢出触发 INTB0仅内部记录无硬件中断D0 NEW_MEAS_MASK 测量完成主中断屏蔽1测量结束拉低 INTB 唤醒 MCU0仅寄存器标记无引脚中断/////////////////////////////////////////////////////////////////////////////////////////////////////////三、计数器溢出阈值寄存器04h~07h8 位读写作用设置最大计时上限计数超过阈值立刻终止测量并触发溢出中断16 位阈值 高 8 位 8 | 低 8 位5. 04h TDCx_COARSE_CNTR_OVF_H 环振溢出阈值高 8 位复位 FFh6. 05h TDCx_COARSE_CNTR_OVF_L 环振溢出阈值低 8 位复位 FFh组合 COARSE_CNTR_OVF H8 | L模式 1 专用上限环振计数值超过则溢出停机手册禁止低 8 位设为 1。7. 06h TDCx_CLOCK_CNTR_OVF_H 时钟计数器溢出高 8 位复位 FFh8. 07h TDCx_CLOCK_CNTR_OVF_L 时钟计数器溢出低 8 位复位 FFh组合 CLOCK_CNTR_OVF H8 | L模式 2 专用上限外部时钟周期计数超限触发中断。/////////////////////////////////////////////////////////////////////////////////////////////////////////四、STOP 噪声屏蔽寄存器08h / 09h8 位读写近端杂波过滤START 之后前 N 个外部时钟周期内所有 STOP 脉冲全部忽略屏蔽近距离反射干扰9. 08h TDCx_CLOCK_CNTR_STOP_MASK_H 屏蔽窗口高 8 位复位 00h10. 09h TDCx_CLOCK_CNTR_STOP_MASK_L 屏蔽窗口低 8 位复位 00h组合 MASK H8 | L约束MASK 数值必须小于时钟溢出阈值否则未到有效窗口就溢出报错/////////////////////////////////////////////////////////////////////////////////////////////////////////五、TOF 时间原始计数值寄存器10h / 12h / 14h / 16h / 18h / 1Ah24 位只读命名 TDCx_TIMEnn1~6存储 START 到第 n 路 STOP 之间环形振荡器小数计数值寄存器统一格式Bit23 奇偶校验位PARITY_EN1 时有效Bit22~0 23 位原始环振计数| 地址 | 寄存器名 | 功能 ||------|----------|------|| 10h | TDCx_TIME1 | START → 第 1 路 STOP 环振计数值模式 2TOF 计算公式基准项 || 12h | TDCx_TIME2 | START → 第 2 路 STOP 环振计数值 || 14h | TDCx_TIME3 | START → 第 3 路 STOP 环振计数值 || 16h | TDCx_TIME4 | START → 第 4 路 STOP 环振计数值 || 18h | TDCx_TIME5 | START → 第 5 路 STOP 环振计数值 || 1Ah | TDCx_TIME6 | 5 路 STOP 模式下备用计时缓存/////////////////////////////////////////////////////////////////////////////////////////////////////////六、外部时钟整数计数寄存器11h / 13h / 15h / 17h / 19h24 位只读命名 TDCx_CLOCK_COUNTnn1~5仅测量模式 2 有效记录 START 到第 n 路 STOP 之间完整外部时钟周期整数寄存器统一格式Bit23 奇偶校验位Bit22~16 多周期平均扩展位存放累加余数Bit15~0 16 位有效时钟周期计数值| 地址 | 寄存器名 | 功能 ||------|----------|------|| 11h | TDCx_CLOCK_COUNT1 | 第 1 路 STOP 对应的外部时钟整数计数 || 13h | TDCx_CLOCK_COUNT2 | 第 2 路 STOP 对应的外部时钟整数计数 || 15h | TDCx_CLOCK_COUNT3 | 第 3 路 STOP 对应的外部时钟整数计数 || 17h | TDCx_CLOCK_COUNT4 | 第 4 路 STOP 对应的外部时钟整数计数 || 19h | TDCx_CLOCK_COUNT5 | 第 5 路 STOP 对应的外部时钟整数计数 |/////////////////////////////////////////////////////////////////////////////////////////////////////////七、自校准基准寄存器1Bh / 1Ch24 位只读MCU 读取后计算真实 LSB 皮秒分辨率补偿温漂、电压漂移是 TOF 换算核心参数22. 1Bh TDCx_CALIBRATION1 单时钟周期校准值存储1 个外部时钟周期对应的环振计数值校准点 123. 1Ch TDCx_CALIBRATION2 多周期校准值存储 CONFIG2.CALIBRATION2_PERIODS 设定数量的外部时钟对应的环振计数值校准点 2校准计算公式calCount (CALIBRATION2 - CALIBRATION1) / (CALIBRATION2_PERIODS - 1)normLSB 外部时钟周期 / calCount/////////////////////////////////////////////////////////////////////////////////////////////////////////标准测量寄存器操作流程1.SPI 写 CONFIG1 / CONFIG2 配置模式、平均次数、STOP 数量2.配置溢出阈值、STOP 屏蔽窗口寄存器3.置位 CONFIG1.START_MEAS 启动测量4.等待 INTB 硬件中断5.读取 CALIBRATION1 / CALIBRATION2 计算 LSB 分辨率6.读取 TIMEx / CLOCK_COUNTx代入对应模式公式算出真实飞行时间 TOF7.写 1 清除 INT_STATUS 中断标志重复下一次测量。//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////TDC7200寄存器功能整理一、基础配置寄存器00h-01h1.地址00hCONFIG1 主配置寄存器 复位 00h8位读写位 位名 功能说明D7 FORCE_CAL 强制校准0 测量中断溢出 / 无 STOP时不校准1 无论测量是否正常结束强制执行一次自校准D6 PARITY_EN 奇偶校验使能0 测量寄存器无校验位1TIME/CLOCK_COUNT/CALIBRATION 寄存器开启偶校验D5 TRIGG_EDGE TRIGG 触发输出边沿0 上升沿输出1 下降沿输出D4 STOP_EDGE STOP 信号触发边沿0 上升沿停止计时1 下降沿停止计时推荐上升沿保证精度D3 START_EDGE START 信号触发边沿0 上升沿启动计时1 下降沿启动计时推荐上升沿D2~D1 MEAS_MODE 测量模式选择00 模式 112ns~500ns 短时间测量仅环形振荡器计数01 模式 2250ns~8ms 长距离外部时钟粗计数 环振小数通用推荐10/11 保留禁用D0 START_MEAS 测量启动位写 1 立即触发新测量清空所有结果寄存器、产生 TRIGG 脉冲测量完成硬件自动清 02.地址01hCONFIG2 高级配置寄存器 复位 40h8位读写位 位名 功能说明D7~D6 CALIBRATION2_PERIODS 二次校准时钟周期数校准精度基准002 个外部时钟0110 个默认1020 个1140 个D5~D3 AVG_CYCLES 多周期平均次数低功耗MCU 休眠自动多次测量0012 次、0104 次、0118 次、10016 次、10132 次、11064 次、111128 次000 关闭平均单次测量D2~D0 NUM_STOP 支持的 STOP 通道数量000 单 STOP0012 路0103 路0114 路1005 路101/110/111 无效强制单路/////////////////////////////////////////////////////////////////////////////////////////////////////////二、中断控制寄存器02h ~ 03h3. 地址 02hINT_STATUS 中断状态寄存器复位 00h8 位读写清标志存储所有中断事件标志写 1 清零对应位只读标志不可自动清除位 位名 功能说明D7~D5 Reserved 保留位固定 0D4 MEAS_COMPLETE_FLAG 测量完成总标志1 一组平均 / 单次测量全部结束写 1 清零D3 MEAS_STARTED_FLAG 测量启动标志1 已捕获 START 信号计时开始写 1 清零D2 CLOCK_CNTR_OVF_INT 时钟粗计数器溢出中断1 外部时钟计数超限测量立即终止写 1 清零D1 COARSE_CNTR_OVF_INT 环振粗计数器溢出中断1 短时间计数超限测量立即终止写 1 清零D0 NEW_MEAS_INT 新测量完成中断主中断1 有效 STOP 全部采集完毕INTB 引脚拉低输出中断写 1 清零4. 地址 03hINT_MASK 中断屏蔽寄存器复位 07h8 位读写控制中断是否输出到硬件引脚 INTB寄存器内标志位不受屏蔽影响仅屏蔽引脚电平位 位名 功能说明D7~D3 Reserved 保留位固定 0D2 CLOCK_CNTR_OVF_MASK 时钟溢出中断屏蔽1 允许引脚输出0 仅寄存器置位引脚无中断D1 COARSE_CNTR_OVF_MASK 环振溢出中断屏蔽1 允许引脚输出0 屏蔽引脚D0 NEW_MEAS_MASK 测量完成主中断屏蔽1 允许 INTB 拉低0 仅寄存器记录MCU 无硬件中断/////////////////////////////////////////////////////////////////////////////////////////////////////////三、计数器溢出阈值寄存器04h ~ 07h作用设置最大计时时长超过则触发溢出中断并终止测量分高低 8 位组成 16 位阈值5. 04h COARSE_CNTR_OVF_H 环振溢出阈值高 8 位FFh6. 05h COARSE_CNTR_OVF_L 环振溢出阈值低 8 位FFh组合 COARSE_CNTR_OVF H8 | L模式 1 计时超过该值直接停止测量。7. 06h CLOCK_CNTR_OVF_H 时钟计数器溢出高 8 位FFh8. 07h CLOCK_CNTR_OVF_L 时钟计数器溢出低 8 位FFh组合 CLOCK_CNTR_OVF H8 | L模式 2 外部时钟计数超限触发中断/////////////////////////////////////////////////////////////////////////////////////////////////////////四、STOP 屏蔽窗口寄存器08h ~ 09h9. 08h CLOCK_CNTR_STOP_MASK_H 屏蔽窗口高 8 位00h10. 09h CLOCK_CNTR_STOP_MASK_L 屏蔽窗口低 8 位00h组合 MASK H8 | LSTART 后前 MASK 个外部时钟周期内所有 STOP 脉冲全部忽略用于过滤近距离杂波、超声波近端反射噪声要求 MASK 值必须小于 CLOCK 溢出阈值否则未到有效窗口就溢出报错。/////////////////////////////////////////////////////////////////////////////////////////////////////////五、TOF 测量结果寄存器10h ~ 1Ah全部 24 位只读格式Bit23 奇偶校验位Bit22~023 位原始计数值存储 START 与各 STOP 之间的环振计数值。11. 10h TIME1START 到第 1 路 STOP 的环振原始计数模式 2 公式计算 TOF 的基准时间项。12. 12h TIME2START 到第 2 路 STOP 环振计数13. 14h TIME3START 到第 3 路 STOP 环振计数14. 16h TIME4START 到第 4 路 STOP 环振计数15. 18h TIME5START 到第 5 路 STOP 环振计数16. 1Ah TIME6最大 5 路 STOP 场景下备用计时缓存/////////////////////////////////////////////////////////////////////////////////////////////////////////六、 外部时钟粗计数寄存器11h、13h、15h、17h、19h24 位只读仅测量模式 2 有效记录 START 至对应 STOP 之间完整外部时钟周期数Bit23 校验位Bit22~16 多周期平均扩展位Bit15~016 位时钟计数值计算 TOF 时需根据 AVG_CYCLES 右移平均次数 log2 位。17. 11h CLOCK_COUNT1 第 1 路 STOP 时钟周期数18. 13h CLOCK_COUNT2 第 2 路 STOP 时钟周期数19. 15h CLOCK_COUNT3 第 3 路 STOP 时钟周期数20. 17h CLOCK_COUNT4 第 4 路 STOP 时钟周期数21. 19h CLOCK_COUNT5 第 5 路 STOP 时钟周期数/////////////////////////////////////////////////////////////////////////////////////////////////////////七、自校准基准寄存器1Bh、1Ch24 位只读用于实时计算 LSB单环振皮秒分辨率补偿温漂、电压漂移是 TOF 换算核心参数。22. 1Bh CALIBRATION1单外部时钟周期对应的环振计数值校准点 123. 1Ch CALIBRATION2N 个外部时钟周期对应的环振计数值N 由 CONFIG2 的 CALIBRATION2_PERIODS 设定补充寄存器分组功能总览1. 配置组 (00/01h)工作模式、平均次数、STOP 通道、信号边沿、启动测量2. 中断组 (02/03h)读取测量 / 溢出状态控制硬件中断引脚输出3. 阈值组 (04~09h)设置最大计时时长、近端噪声屏蔽窗口4. 测量数据组 (10~19h,1Ah)存储每一路 STOP 的环振小数计数 外部时钟整数计数5. 校准组 (1Bh/1Ch)芯片自校准原始数据MCU 读取后换算真实皮秒 TOF 时间关键使用流程补充1. SPI 写入 CONFIG1/CONFIG2 配置模式、平均次数2. 配置溢出阈值与 STOP 屏蔽窗口3. 置位 CONFIG1.0 启动测量4. 等待 INTB 硬件中断5. SPI 读取 CALIBRATION1/CALIBRATION2 计算标准 LSB6. 读取 TIMEx、CLOCK_COUNTx代入公式算出真实飞行时间 TOF7. 写 1 清除 INT_STATUS 中断标志开启下一次测量//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////* USER CODE BEGIN Header *//********************************************************************************* file : main.c* brief : Main program body******************************************************************************* attention** Copyright (c) 2026 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 stdio.h#include string.h/* Private includes ----------------------------------------------------------*//* USER CODE BEGIN Includes *//* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*//* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*//* USER CODE BEGIN PD *//*外部晶振8MHz*/#define CLOCKperiod 1.0f/(8000000.0f)/* USER CODE END PD *//* Private macro -------------------------------------------------------------*//* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*/SPI_HandleTypeDef hspi1;TIM_HandleTypeDef htim1;UART_HandleTypeDef huart1;/* USER CODE BEGIN PV */typedef enum{blank 100,start,read,calculate,processing,send}state;uint8_t spi_INT_status;uint32_t time1;uint32_t time2;uint32_t clock_count1;uint32_t CALIBRATION1;uint32_t CALIBRATION2;float TOF1;float distance_buf[10];uint8_t measure_cnt 0;float normLSB;float calCount;state state1 blank;/* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/void SystemClock_Config(void);static void MX_GPIO_Init(void);static void MX_SPI1_Init(void);static void MX_TIM1_Init(void);static void MX_USART1_UART_Init(void);/* USER CODE BEGIN PFP */void TDC7200_Init(void){uint8_t config1[2] {0x40,0x00};/*写地址第六位置1*/uint8_t config2[2] {0x41,0x40};/*Calibration10clocksingle stop*/uint8_t INT_MASK[2] {0x43,0x01};/*使能measurement interrupt*/uint8_t COARSE_H[2] {0x44,0xFF};/*默认*/uint8_t COARSE_L[2] {0x45,0x00};/*默认*//*配置config1*/HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);HAL_SPI_Transmit(hspi1, config1, 2, 100);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);/*配置config2*/HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);HAL_SPI_Transmit(hspi1, config2, 2, 100);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);/*配置INT_MASK*/HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);HAL_SPI_Transmit(hspi1, INT_MASK, 2, 100);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);/*配置coarse_h*/HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);HAL_SPI_Transmit(hspi1, COARSE_H, 2, 100);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);/*配置coarse_h*/HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);HAL_SPI_Transmit(hspi1, COARSE_L, 2, 100);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);}void startfunction(void){uint8_t start[2] {0x40,0x01};/*准备开始一次测量*/HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);HAL_SPI_Transmit(hspi1, start, 2, 100);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);HAL_TIM_OnePulse_Start(htim1,TIM_CHANNEL_1);//给到激光器和TDC的start引脚上}void readfunction(void){uint8_t byte1[4];uint8_t byte2[4];uint8_t byte3[4];uint8_t byte4[4];uint8_t byte5[4];uint8_t TxData[2] {0x02,0xff};uint8_t spi_INT_status[2];/*读INT_STATUT*/HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);HAL_SPI_TransmitReceive(hspi1, TxData, spi_INT_status, 2, 100);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);/*读tim1*/uint8_t Tim1[4] {0x10, 0xff, 0xff, 0xff};/*读的话第六位为0即可*/if(spi_INT_status[1]0x01){HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);HAL_SPI_TransmitReceive(hspi1, Tim1, byte1, 4, 100);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);time1 (uint32_t)byte1[1] 16 | (uint32_t)byte1[2] 8 | (uint32_t)byte1[3];}/*读tim2*/uint8_t Tim2[4] {0x12, 0xff, 0xff, 0xff};if(spi_INT_status[1]0x01){HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);HAL_SPI_TransmitReceive(hspi1, Tim2, byte2, 4, 100);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);time2 (uint32_t)byte2[1] 16 | (uint32_t)byte2[2] 8 | (uint32_t)byte2[3];}/*读CLOCK_COUNT1*/uint8_t CLOCK_COUNT1_tx[4] {0x11, 0xff, 0xff, 0xff};if(spi_INT_status[1]0x01){HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);HAL_SPI_TransmitReceive(hspi1, CLOCK_COUNT1_tx, byte3, 4, 100);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);clock_count1 (uint32_t)byte3[1] 16 | (uint32_t)byte3[2] 8 | (uint32_t)byte3[3];}/*读CALIBRATION1*/uint8_t CALIBRATION1_tx[4] {0x1B, 0xff, 0xff, 0xff};if(spi_INT_status[1]0x01){HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);HAL_SPI_TransmitReceive(hspi1, CALIBRATION1_tx, byte4, 4, 100);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);CALIBRATION1 (uint32_t)byte4[1] 16 | (uint32_t)byte4[2] 8 | (uint32_t)byte4[3];}/*读CALIBRATION2*/uint8_t CALIBRATION2_tx[4] {0x1C, 0xff, 0xff, 0xff};if(spi_INT_status[1]0x01){HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);HAL_SPI_TransmitReceive(hspi1, CALIBRATION2_tx, byte5, 4, 100);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);CALIBRATION2 (uint32_t)byte5[1] 16 | (uint32_t)byte5[2] 8 | (uint32_t)byte5[3];}}void processingfunction(void){for(int i0; i8; i){for(int ji1; j9; j){if(distance_buf[i]distance_buf[j]){float m distance_buf[i];distance_buf[i] distance_buf[j];distance_buf[j] m;}}}}/* USER CODE END PFP *//* Private user code ---------------------------------------------------------*//* USER CODE BEGIN 0 *//* USER CODE END 0 *//*** brief The application entry point.* retval int*/int main(void){/* USER CODE BEGIN 1 *//* 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_SPI1_Init();MX_TIM1_Init();MX_USART1_UART_Init();TDC7200_Init();/* USER CODE BEGIN 2 *//* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE */switch(state1){case start:startfunction();break;case read:readfunction();state1 calculate;break;case processing:processingfunction();state1 send;break;default: break;}if(state1 calculate){calCount (float)(CALIBRATION2 - CALIBRATION1) / 9.0f;normLSB CLOCKperiod / calCount;TOF1 (time1*normLSB)(clock_count1*CLOCKperiod)-(time2*normLSB);distance_buf[measure_cnt] (TOF1/2.0f)*(3e8f);if(measure_cnt 9){measure_cnt;state1 start;}else{state1 processing;measure_cnt 0;}}if(state1 send){char tx[50];sprintf(tx,%.3f\r\n,distance_buf[5]);HAL_UART_Transmit(huart1, (uint8_t *)tx, strlen(tx), 100);state1 blank;}}}/* USER CODE BEGIN 3 *//* USER CODE END 3 *//*** brief System Clock Configuration* retval None*/void SystemClock_Config(void){RCC_OscInitTypeDef RCC_OscInitStruct {0};RCC_ClkInitTypeDef RCC_ClkInitStruct {0};/** 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.HSEPredivValue RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState RCC_HSI_ON;RCC_OscInitStruct.PLL.PLLState RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL RCC_PLL_MUL9;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_ClkInitStruct.SYSCLKSource RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(RCC_ClkInitStruct, FLASH_LATENCY_2) ! HAL_OK){Error_Handler();}}/*** brief SPI1 Initialization Function* param None* retval None*/static void MX_SPI1_Init(void){/* USER CODE BEGIN SPI1_Init 0 *//* USER CODE END SPI1_Init 0 *//* USER CODE BEGIN SPI1_Init 1 *//* USER CODE END SPI1_Init 1 *//* SPI1 parameter configuration*/hspi1.Instance SPI1;hspi1.Init.Mode SPI_MODE_MASTER;hspi1.Init.Direction SPI_DIRECTION_2LINES;hspi1.Init.DataSize SPI_DATASIZE_8BIT;hspi1.Init.CLKPolarity SPI_POLARITY_LOW;hspi1.Init.CLKPhase SPI_PHASE_1EDGE;hspi1.Init.NSS SPI_NSS_SOFT;hspi1.Init.BaudRatePrescaler SPI_BAUDRATEPRESCALER_8;hspi1.Init.FirstBit SPI_FIRSTBIT_MSB;hspi1.Init.TIMode SPI_TIMODE_DISABLE;hspi1.Init.CRCCalculation SPI_CRCCALCULATION_DISABLE;hspi1.Init.CRCPolynomial 10;if (HAL_SPI_Init(hspi1) ! HAL_OK){Error_Handler();}/* USER CODE BEGIN SPI1_Init 2 *//* USER CODE END SPI1_Init 2 */}/*** brief TIM1 Initialization Function* param None* retval None*/static void MX_TIM1_Init(void){/* USER CODE BEGIN TIM1_Init 0 *//* USER CODE END TIM1_Init 0 */TIM_ClockConfigTypeDef sClockSourceConfig {0};TIM_MasterConfigTypeDef sMasterConfig {0};TIM_OC_InitTypeDef sConfigOC {0};TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig {0};/* USER CODE BEGIN TIM1_Init 1 *//* USER CODE END TIM1_Init 1 */htim1.Instance TIM1;htim1.Init.Prescaler 0;htim1.Init.CounterMode TIM_COUNTERMODE_UP;htim1.Init.Period 65535;htim1.Init.ClockDivision TIM_CLOCKDIVISION_DIV1;htim1.Init.RepetitionCounter 0;htim1.Init.AutoReloadPreload TIM_AUTORELOAD_PRELOAD_DISABLE;if (HAL_TIM_Base_Init(htim1) ! HAL_OK){Error_Handler();}sClockSourceConfig.ClockSource TIM_CLOCKSOURCE_INTERNAL;if (HAL_TIM_ConfigClockSource(htim1, sClockSourceConfig) ! HAL_OK){Error_Handler();}if (HAL_TIM_PWM_Init(htim1) ! HAL_OK){Error_Handler();}if (HAL_TIM_OnePulse_Init(htim1, TIM_OPMODE_SINGLE) ! HAL_OK){Error_Handler();}sMasterConfig.MasterOutputTrigger TIM_TRGO_RESET;sMasterConfig.MasterSlaveMode TIM_MASTERSLAVEMODE_DISABLE;if (HAL_TIMEx_MasterConfigSynchronization(htim1, sMasterConfig) ! HAL_OK){Error_Handler();}sConfigOC.OCMode TIM_OCMODE_PWM1;sConfigOC.Pulse 1;sConfigOC.OCPolarity TIM_OCPOLARITY_HIGH;sConfigOC.OCNPolarity TIM_OCNPOLARITY_HIGH;sConfigOC.OCFastMode TIM_OCFAST_DISABLE;sConfigOC.OCIdleState TIM_OCIDLESTATE_RESET;sConfigOC.OCNIdleState TIM_OCNIDLESTATE_RESET;if (HAL_TIM_PWM_ConfigChannel(htim1, sConfigOC, TIM_CHANNEL_1) ! HAL_OK){Error_Handler();}sBreakDeadTimeConfig.OffStateRunMode TIM_OSSR_DISABLE;sBreakDeadTimeConfig.OffStateIDLEMode TIM_OSSI_DISABLE;sBreakDeadTimeConfig.LockLevel TIM_LOCKLEVEL_OFF;sBreakDeadTimeConfig.DeadTime 0;sBreakDeadTimeConfig.BreakState TIM_BREAK_DISABLE;sBreakDeadTimeConfig.BreakPolarity TIM_BREAKPOLARITY_HIGH;sBreakDeadTimeConfig.AutomaticOutput TIM_AUTOMATICOUTPUT_DISABLE;if (HAL_TIMEx_ConfigBreakDeadTime(htim1, sBreakDeadTimeConfig) ! HAL_OK){Error_Handler();}/* USER CODE BEGIN TIM1_Init 2 *//* USER CODE END TIM1_Init 2 */HAL_TIM_MspPostInit(htim1);}/*** brief USART1 Initialization Function* param None* retval None*/static void MX_USART1_UART_Init(void){/* USER CODE BEGIN USART1_Init 0 *//* USER CODE END USART1_Init 0 *//* USER CODE BEGIN USART1_Init 1 *//* USER CODE END USART1_Init 1 */huart1.Instance USART1;huart1.Init.BaudRate 115200;huart1.Init.WordLength UART_WORDLENGTH_8B;huart1.Init.StopBits UART_STOPBITS_1;huart1.Init.Parity UART_PARITY_NONE;huart1.Init.Mode UART_MODE_TX_RX;huart1.Init.HwFlowCtl UART_HWCONTROL_NONE;huart1.Init.OverSampling UART_OVERSAMPLING_16;if (HAL_UART_Init(huart1) ! HAL_OK){Error_Handler();}/* USER CODE BEGIN USART1_Init 2 *//* USER CODE END USART1_Init 2 */}/*** brief GPIO Initialization Function* param None* retval None*/static void MX_GPIO_Init(void){GPIO_InitTypeDef GPIO_InitStruct {0};/* USER CODE BEGIN MX_GPIO_Init_1 *//* USER CODE END MX_GPIO_Init_1 *//* GPIO Ports Clock Enable */__HAL_RCC_GPIOD_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(start_GPIO_Port, start_Pin, GPIO_PIN_RESET);/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);/*Configure GPIO pins : PA0 PA2 */GPIO_InitStruct.Pin GPIO_PIN_0|GPIO_PIN_2;GPIO_InitStruct.Mode GPIO_MODE_IT_RISING;GPIO_InitStruct.Pull GPIO_NOPULL;HAL_GPIO_Init(GPIOA, GPIO_InitStruct);/*Configure GPIO pins : start_Pin CS_Pin */GPIO_InitStruct.Pin start_Pin|CS_Pin;GPIO_InitStruct.Mode GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull GPIO_NOPULL;GPIO_InitStruct.Speed GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOA, GPIO_InitStruct);/* EXTI interrupt init*/HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);HAL_NVIC_EnableIRQ(EXTI0_IRQn);/* USER CODE BEGIN MX_GPIO_Init_2 *//* USER CODE END MX_GPIO_Init_2 */}/* USER CODE BEGIN 4 */void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){if(GPIO_Pin GPIO_PIN_0){/*GPIO0中断是用来TDC计数结束*/state1 read;}if(GPIO_Pin GPIO_PIN_2){/*GPIO2中断是用来开始一次测量*/state1 start;}}/* USER CODE END 4 *//*** 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 */
TDC7201与TDC7200芯片寄存器功能概述及main.c代码
发布时间:2026/7/3 2:56:41
TDC7201 全部寄存器完整功能手册前置说明1. TDC7201 内部包含两路独立 TDC 内核TDC1 / TDC2两套寄存器完全独立通过 CSB1 / CSB2 片选区分下文统一前缀 TDCx_ 代表任意一路内核寄存器2. 寄存器地址范围 00h ~ 1Ch分为配置寄存器、中断寄存器、溢出阈值寄存器、STOP 屏蔽寄存器、测量结果寄存器、校准寄存器六大类3. 8 位寄存器单字节读写24 位寄存器TIME/CLOCK_COUNT/CALIBRATION3 字节 SPI 读取Bit23 为奇偶校验位Bit22~0 为有效计数值。/////////////////////////////////////////////////////////////////////////////////////////////////////////一、基础配置寄存器00h / 01h8 位可读写1. 地址 00h TDCx_CONFIG1 主配置寄存器复位 00h位 位名称 详细功能D7 FORCE_CAL 强制校准使能0测量正常结束自动校准溢出 / 无 STOP 中断时不校准1无论测量是否异常终止强制执行自校准D6 PARITY_EN 奇偶校验开关0TIME/CLOCK_COUNT/CALIBRATION 寄存器校验位恒 01开启偶校验读取可校验数据传输错误D5 TRIGG_EDGE TRIGG 输出脉冲边沿0上升沿输出触发信号1下降沿输出触发信号D4 STOP_EDGE STOP 信号触发边沿0上升沿停止计时推荐高精度场景1下降沿停止计时D3 START_EDGE START 信号触发边沿0上升沿启动计时推荐1下降沿启动计时D2~D1 MEAS_MODE 测量模式选择00模式 112ns~2000ns 短测距仅环振计数01模式 2250ns~8ms 长测距推荐通用10/11硬件保留禁止使用D0 START_MEAS 测量启动位写 1清空所有测量寄存器、输出 TRIG 触发脉冲、启动一次完整测量测量完成后硬件自动清零2. 地址 01hTDCx_CONFIG2 高级配置寄存器复位 40h位 位名称 详细功能D7~D6 CALIBRATION2_PERIODS 二次校准时钟周期数决定校准精度002 个外部时钟0110默认10201140D5~D3 AVG_CYCLES 多周期平均次数低功耗 MCU 休眠模式000单次测量关闭平均0012 / 0104 / 0118 / 10016 / 10132 / 11064 / 111128平均模式下 CLOCK_COUNT 读取后需右移 log2 (次数) 再计算 TOFD2~D0 NUM_STOP 可采集 STOP 脉冲最大数量000单 STOP0012010301141005101/110/111无效强制单路 STOP/////////////////////////////////////////////////////////////////////////////////////////////////////////二、中断控制寄存器02h / 03h8 位3. 地址 02hTDCx_INT_STATUS 中断状态寄存器复位 00h写 1 清零标志存储所有测量 / 溢出事件状态仅写 1 可清除对应标志只读不会清零位 位名称 详细功能D7~D5 Reserved 硬件保留固定 0D4 MEAS_COMPLETE_FLAG 测量完成总标志1一组平均 / 单次测量全部结束写 1 清零D3 MEAS_STARTED_FLAG 测量启动标志1已捕获 START 脉冲计时开始写 1 清零D2 CLOCK_CNTR_OVF_INT 时钟粗计数器溢出中断1外部时钟计数超限测量立即终止写 1 清零D1 COARSE_CNTR_OVF_INT 环振粗计数器溢出中断1短时间环振计数超限测量终止写 1 清零D0 NEW_MEAS_INT 新测量完成主中断INTB 引脚触发源1全部 STOP 采集完成拉低 INTB写 1 清零4. 地址 03hTDCx_INT_MASK 中断屏蔽寄存器复位 07h控制中断是否输出到硬件INTB引脚寄存器状态位不受屏蔽影响位 位名称 详细功能D7~D3 Reserved 硬件保留固定 0D2 CLOCK_CNTR_OVF_MASK 时钟溢出中断屏蔽1溢出时 INTB 拉低输出中断0仅寄存器置位引脚无电平变化D1 COARSE_CNTR_OVF_MASK 环振溢出中断屏蔽1溢出触发 INTB0仅内部记录无硬件中断D0 NEW_MEAS_MASK 测量完成主中断屏蔽1测量结束拉低 INTB 唤醒 MCU0仅寄存器标记无引脚中断/////////////////////////////////////////////////////////////////////////////////////////////////////////三、计数器溢出阈值寄存器04h~07h8 位读写作用设置最大计时上限计数超过阈值立刻终止测量并触发溢出中断16 位阈值 高 8 位 8 | 低 8 位5. 04h TDCx_COARSE_CNTR_OVF_H 环振溢出阈值高 8 位复位 FFh6. 05h TDCx_COARSE_CNTR_OVF_L 环振溢出阈值低 8 位复位 FFh组合 COARSE_CNTR_OVF H8 | L模式 1 专用上限环振计数值超过则溢出停机手册禁止低 8 位设为 1。7. 06h TDCx_CLOCK_CNTR_OVF_H 时钟计数器溢出高 8 位复位 FFh8. 07h TDCx_CLOCK_CNTR_OVF_L 时钟计数器溢出低 8 位复位 FFh组合 CLOCK_CNTR_OVF H8 | L模式 2 专用上限外部时钟周期计数超限触发中断。/////////////////////////////////////////////////////////////////////////////////////////////////////////四、STOP 噪声屏蔽寄存器08h / 09h8 位读写近端杂波过滤START 之后前 N 个外部时钟周期内所有 STOP 脉冲全部忽略屏蔽近距离反射干扰9. 08h TDCx_CLOCK_CNTR_STOP_MASK_H 屏蔽窗口高 8 位复位 00h10. 09h TDCx_CLOCK_CNTR_STOP_MASK_L 屏蔽窗口低 8 位复位 00h组合 MASK H8 | L约束MASK 数值必须小于时钟溢出阈值否则未到有效窗口就溢出报错/////////////////////////////////////////////////////////////////////////////////////////////////////////五、TOF 时间原始计数值寄存器10h / 12h / 14h / 16h / 18h / 1Ah24 位只读命名 TDCx_TIMEnn1~6存储 START 到第 n 路 STOP 之间环形振荡器小数计数值寄存器统一格式Bit23 奇偶校验位PARITY_EN1 时有效Bit22~0 23 位原始环振计数| 地址 | 寄存器名 | 功能 ||------|----------|------|| 10h | TDCx_TIME1 | START → 第 1 路 STOP 环振计数值模式 2TOF 计算公式基准项 || 12h | TDCx_TIME2 | START → 第 2 路 STOP 环振计数值 || 14h | TDCx_TIME3 | START → 第 3 路 STOP 环振计数值 || 16h | TDCx_TIME4 | START → 第 4 路 STOP 环振计数值 || 18h | TDCx_TIME5 | START → 第 5 路 STOP 环振计数值 || 1Ah | TDCx_TIME6 | 5 路 STOP 模式下备用计时缓存/////////////////////////////////////////////////////////////////////////////////////////////////////////六、外部时钟整数计数寄存器11h / 13h / 15h / 17h / 19h24 位只读命名 TDCx_CLOCK_COUNTnn1~5仅测量模式 2 有效记录 START 到第 n 路 STOP 之间完整外部时钟周期整数寄存器统一格式Bit23 奇偶校验位Bit22~16 多周期平均扩展位存放累加余数Bit15~0 16 位有效时钟周期计数值| 地址 | 寄存器名 | 功能 ||------|----------|------|| 11h | TDCx_CLOCK_COUNT1 | 第 1 路 STOP 对应的外部时钟整数计数 || 13h | TDCx_CLOCK_COUNT2 | 第 2 路 STOP 对应的外部时钟整数计数 || 15h | TDCx_CLOCK_COUNT3 | 第 3 路 STOP 对应的外部时钟整数计数 || 17h | TDCx_CLOCK_COUNT4 | 第 4 路 STOP 对应的外部时钟整数计数 || 19h | TDCx_CLOCK_COUNT5 | 第 5 路 STOP 对应的外部时钟整数计数 |/////////////////////////////////////////////////////////////////////////////////////////////////////////七、自校准基准寄存器1Bh / 1Ch24 位只读MCU 读取后计算真实 LSB 皮秒分辨率补偿温漂、电压漂移是 TOF 换算核心参数22. 1Bh TDCx_CALIBRATION1 单时钟周期校准值存储1 个外部时钟周期对应的环振计数值校准点 123. 1Ch TDCx_CALIBRATION2 多周期校准值存储 CONFIG2.CALIBRATION2_PERIODS 设定数量的外部时钟对应的环振计数值校准点 2校准计算公式calCount (CALIBRATION2 - CALIBRATION1) / (CALIBRATION2_PERIODS - 1)normLSB 外部时钟周期 / calCount/////////////////////////////////////////////////////////////////////////////////////////////////////////标准测量寄存器操作流程1.SPI 写 CONFIG1 / CONFIG2 配置模式、平均次数、STOP 数量2.配置溢出阈值、STOP 屏蔽窗口寄存器3.置位 CONFIG1.START_MEAS 启动测量4.等待 INTB 硬件中断5.读取 CALIBRATION1 / CALIBRATION2 计算 LSB 分辨率6.读取 TIMEx / CLOCK_COUNTx代入对应模式公式算出真实飞行时间 TOF7.写 1 清除 INT_STATUS 中断标志重复下一次测量。//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////TDC7200寄存器功能整理一、基础配置寄存器00h-01h1.地址00hCONFIG1 主配置寄存器 复位 00h8位读写位 位名 功能说明D7 FORCE_CAL 强制校准0 测量中断溢出 / 无 STOP时不校准1 无论测量是否正常结束强制执行一次自校准D6 PARITY_EN 奇偶校验使能0 测量寄存器无校验位1TIME/CLOCK_COUNT/CALIBRATION 寄存器开启偶校验D5 TRIGG_EDGE TRIGG 触发输出边沿0 上升沿输出1 下降沿输出D4 STOP_EDGE STOP 信号触发边沿0 上升沿停止计时1 下降沿停止计时推荐上升沿保证精度D3 START_EDGE START 信号触发边沿0 上升沿启动计时1 下降沿启动计时推荐上升沿D2~D1 MEAS_MODE 测量模式选择00 模式 112ns~500ns 短时间测量仅环形振荡器计数01 模式 2250ns~8ms 长距离外部时钟粗计数 环振小数通用推荐10/11 保留禁用D0 START_MEAS 测量启动位写 1 立即触发新测量清空所有结果寄存器、产生 TRIGG 脉冲测量完成硬件自动清 02.地址01hCONFIG2 高级配置寄存器 复位 40h8位读写位 位名 功能说明D7~D6 CALIBRATION2_PERIODS 二次校准时钟周期数校准精度基准002 个外部时钟0110 个默认1020 个1140 个D5~D3 AVG_CYCLES 多周期平均次数低功耗MCU 休眠自动多次测量0012 次、0104 次、0118 次、10016 次、10132 次、11064 次、111128 次000 关闭平均单次测量D2~D0 NUM_STOP 支持的 STOP 通道数量000 单 STOP0012 路0103 路0114 路1005 路101/110/111 无效强制单路/////////////////////////////////////////////////////////////////////////////////////////////////////////二、中断控制寄存器02h ~ 03h3. 地址 02hINT_STATUS 中断状态寄存器复位 00h8 位读写清标志存储所有中断事件标志写 1 清零对应位只读标志不可自动清除位 位名 功能说明D7~D5 Reserved 保留位固定 0D4 MEAS_COMPLETE_FLAG 测量完成总标志1 一组平均 / 单次测量全部结束写 1 清零D3 MEAS_STARTED_FLAG 测量启动标志1 已捕获 START 信号计时开始写 1 清零D2 CLOCK_CNTR_OVF_INT 时钟粗计数器溢出中断1 外部时钟计数超限测量立即终止写 1 清零D1 COARSE_CNTR_OVF_INT 环振粗计数器溢出中断1 短时间计数超限测量立即终止写 1 清零D0 NEW_MEAS_INT 新测量完成中断主中断1 有效 STOP 全部采集完毕INTB 引脚拉低输出中断写 1 清零4. 地址 03hINT_MASK 中断屏蔽寄存器复位 07h8 位读写控制中断是否输出到硬件引脚 INTB寄存器内标志位不受屏蔽影响仅屏蔽引脚电平位 位名 功能说明D7~D3 Reserved 保留位固定 0D2 CLOCK_CNTR_OVF_MASK 时钟溢出中断屏蔽1 允许引脚输出0 仅寄存器置位引脚无中断D1 COARSE_CNTR_OVF_MASK 环振溢出中断屏蔽1 允许引脚输出0 屏蔽引脚D0 NEW_MEAS_MASK 测量完成主中断屏蔽1 允许 INTB 拉低0 仅寄存器记录MCU 无硬件中断/////////////////////////////////////////////////////////////////////////////////////////////////////////三、计数器溢出阈值寄存器04h ~ 07h作用设置最大计时时长超过则触发溢出中断并终止测量分高低 8 位组成 16 位阈值5. 04h COARSE_CNTR_OVF_H 环振溢出阈值高 8 位FFh6. 05h COARSE_CNTR_OVF_L 环振溢出阈值低 8 位FFh组合 COARSE_CNTR_OVF H8 | L模式 1 计时超过该值直接停止测量。7. 06h CLOCK_CNTR_OVF_H 时钟计数器溢出高 8 位FFh8. 07h CLOCK_CNTR_OVF_L 时钟计数器溢出低 8 位FFh组合 CLOCK_CNTR_OVF H8 | L模式 2 外部时钟计数超限触发中断/////////////////////////////////////////////////////////////////////////////////////////////////////////四、STOP 屏蔽窗口寄存器08h ~ 09h9. 08h CLOCK_CNTR_STOP_MASK_H 屏蔽窗口高 8 位00h10. 09h CLOCK_CNTR_STOP_MASK_L 屏蔽窗口低 8 位00h组合 MASK H8 | LSTART 后前 MASK 个外部时钟周期内所有 STOP 脉冲全部忽略用于过滤近距离杂波、超声波近端反射噪声要求 MASK 值必须小于 CLOCK 溢出阈值否则未到有效窗口就溢出报错。/////////////////////////////////////////////////////////////////////////////////////////////////////////五、TOF 测量结果寄存器10h ~ 1Ah全部 24 位只读格式Bit23 奇偶校验位Bit22~023 位原始计数值存储 START 与各 STOP 之间的环振计数值。11. 10h TIME1START 到第 1 路 STOP 的环振原始计数模式 2 公式计算 TOF 的基准时间项。12. 12h TIME2START 到第 2 路 STOP 环振计数13. 14h TIME3START 到第 3 路 STOP 环振计数14. 16h TIME4START 到第 4 路 STOP 环振计数15. 18h TIME5START 到第 5 路 STOP 环振计数16. 1Ah TIME6最大 5 路 STOP 场景下备用计时缓存/////////////////////////////////////////////////////////////////////////////////////////////////////////六、 外部时钟粗计数寄存器11h、13h、15h、17h、19h24 位只读仅测量模式 2 有效记录 START 至对应 STOP 之间完整外部时钟周期数Bit23 校验位Bit22~16 多周期平均扩展位Bit15~016 位时钟计数值计算 TOF 时需根据 AVG_CYCLES 右移平均次数 log2 位。17. 11h CLOCK_COUNT1 第 1 路 STOP 时钟周期数18. 13h CLOCK_COUNT2 第 2 路 STOP 时钟周期数19. 15h CLOCK_COUNT3 第 3 路 STOP 时钟周期数20. 17h CLOCK_COUNT4 第 4 路 STOP 时钟周期数21. 19h CLOCK_COUNT5 第 5 路 STOP 时钟周期数/////////////////////////////////////////////////////////////////////////////////////////////////////////七、自校准基准寄存器1Bh、1Ch24 位只读用于实时计算 LSB单环振皮秒分辨率补偿温漂、电压漂移是 TOF 换算核心参数。22. 1Bh CALIBRATION1单外部时钟周期对应的环振计数值校准点 123. 1Ch CALIBRATION2N 个外部时钟周期对应的环振计数值N 由 CONFIG2 的 CALIBRATION2_PERIODS 设定补充寄存器分组功能总览1. 配置组 (00/01h)工作模式、平均次数、STOP 通道、信号边沿、启动测量2. 中断组 (02/03h)读取测量 / 溢出状态控制硬件中断引脚输出3. 阈值组 (04~09h)设置最大计时时长、近端噪声屏蔽窗口4. 测量数据组 (10~19h,1Ah)存储每一路 STOP 的环振小数计数 外部时钟整数计数5. 校准组 (1Bh/1Ch)芯片自校准原始数据MCU 读取后换算真实皮秒 TOF 时间关键使用流程补充1. SPI 写入 CONFIG1/CONFIG2 配置模式、平均次数2. 配置溢出阈值与 STOP 屏蔽窗口3. 置位 CONFIG1.0 启动测量4. 等待 INTB 硬件中断5. SPI 读取 CALIBRATION1/CALIBRATION2 计算标准 LSB6. 读取 TIMEx、CLOCK_COUNTx代入公式算出真实飞行时间 TOF7. 写 1 清除 INT_STATUS 中断标志开启下一次测量//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////* USER CODE BEGIN Header *//********************************************************************************* file : main.c* brief : Main program body******************************************************************************* attention** Copyright (c) 2026 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 stdio.h#include string.h/* Private includes ----------------------------------------------------------*//* USER CODE BEGIN Includes *//* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*//* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*//* USER CODE BEGIN PD *//*外部晶振8MHz*/#define CLOCKperiod 1.0f/(8000000.0f)/* USER CODE END PD *//* Private macro -------------------------------------------------------------*//* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*/SPI_HandleTypeDef hspi1;TIM_HandleTypeDef htim1;UART_HandleTypeDef huart1;/* USER CODE BEGIN PV */typedef enum{blank 100,start,read,calculate,processing,send}state;uint8_t spi_INT_status;uint32_t time1;uint32_t time2;uint32_t clock_count1;uint32_t CALIBRATION1;uint32_t CALIBRATION2;float TOF1;float distance_buf[10];uint8_t measure_cnt 0;float normLSB;float calCount;state state1 blank;/* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/void SystemClock_Config(void);static void MX_GPIO_Init(void);static void MX_SPI1_Init(void);static void MX_TIM1_Init(void);static void MX_USART1_UART_Init(void);/* USER CODE BEGIN PFP */void TDC7200_Init(void){uint8_t config1[2] {0x40,0x00};/*写地址第六位置1*/uint8_t config2[2] {0x41,0x40};/*Calibration10clocksingle stop*/uint8_t INT_MASK[2] {0x43,0x01};/*使能measurement interrupt*/uint8_t COARSE_H[2] {0x44,0xFF};/*默认*/uint8_t COARSE_L[2] {0x45,0x00};/*默认*//*配置config1*/HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);HAL_SPI_Transmit(hspi1, config1, 2, 100);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);/*配置config2*/HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);HAL_SPI_Transmit(hspi1, config2, 2, 100);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);/*配置INT_MASK*/HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);HAL_SPI_Transmit(hspi1, INT_MASK, 2, 100);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);/*配置coarse_h*/HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);HAL_SPI_Transmit(hspi1, COARSE_H, 2, 100);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);/*配置coarse_h*/HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);HAL_SPI_Transmit(hspi1, COARSE_L, 2, 100);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);}void startfunction(void){uint8_t start[2] {0x40,0x01};/*准备开始一次测量*/HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);HAL_SPI_Transmit(hspi1, start, 2, 100);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);HAL_TIM_OnePulse_Start(htim1,TIM_CHANNEL_1);//给到激光器和TDC的start引脚上}void readfunction(void){uint8_t byte1[4];uint8_t byte2[4];uint8_t byte3[4];uint8_t byte4[4];uint8_t byte5[4];uint8_t TxData[2] {0x02,0xff};uint8_t spi_INT_status[2];/*读INT_STATUT*/HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);HAL_SPI_TransmitReceive(hspi1, TxData, spi_INT_status, 2, 100);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);/*读tim1*/uint8_t Tim1[4] {0x10, 0xff, 0xff, 0xff};/*读的话第六位为0即可*/if(spi_INT_status[1]0x01){HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);HAL_SPI_TransmitReceive(hspi1, Tim1, byte1, 4, 100);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);time1 (uint32_t)byte1[1] 16 | (uint32_t)byte1[2] 8 | (uint32_t)byte1[3];}/*读tim2*/uint8_t Tim2[4] {0x12, 0xff, 0xff, 0xff};if(spi_INT_status[1]0x01){HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);HAL_SPI_TransmitReceive(hspi1, Tim2, byte2, 4, 100);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);time2 (uint32_t)byte2[1] 16 | (uint32_t)byte2[2] 8 | (uint32_t)byte2[3];}/*读CLOCK_COUNT1*/uint8_t CLOCK_COUNT1_tx[4] {0x11, 0xff, 0xff, 0xff};if(spi_INT_status[1]0x01){HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);HAL_SPI_TransmitReceive(hspi1, CLOCK_COUNT1_tx, byte3, 4, 100);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);clock_count1 (uint32_t)byte3[1] 16 | (uint32_t)byte3[2] 8 | (uint32_t)byte3[3];}/*读CALIBRATION1*/uint8_t CALIBRATION1_tx[4] {0x1B, 0xff, 0xff, 0xff};if(spi_INT_status[1]0x01){HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);HAL_SPI_TransmitReceive(hspi1, CALIBRATION1_tx, byte4, 4, 100);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);CALIBRATION1 (uint32_t)byte4[1] 16 | (uint32_t)byte4[2] 8 | (uint32_t)byte4[3];}/*读CALIBRATION2*/uint8_t CALIBRATION2_tx[4] {0x1C, 0xff, 0xff, 0xff};if(spi_INT_status[1]0x01){HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);HAL_SPI_TransmitReceive(hspi1, CALIBRATION2_tx, byte5, 4, 100);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);CALIBRATION2 (uint32_t)byte5[1] 16 | (uint32_t)byte5[2] 8 | (uint32_t)byte5[3];}}void processingfunction(void){for(int i0; i8; i){for(int ji1; j9; j){if(distance_buf[i]distance_buf[j]){float m distance_buf[i];distance_buf[i] distance_buf[j];distance_buf[j] m;}}}}/* USER CODE END PFP *//* Private user code ---------------------------------------------------------*//* USER CODE BEGIN 0 *//* USER CODE END 0 *//*** brief The application entry point.* retval int*/int main(void){/* USER CODE BEGIN 1 *//* 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_SPI1_Init();MX_TIM1_Init();MX_USART1_UART_Init();TDC7200_Init();/* USER CODE BEGIN 2 *//* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE */switch(state1){case start:startfunction();break;case read:readfunction();state1 calculate;break;case processing:processingfunction();state1 send;break;default: break;}if(state1 calculate){calCount (float)(CALIBRATION2 - CALIBRATION1) / 9.0f;normLSB CLOCKperiod / calCount;TOF1 (time1*normLSB)(clock_count1*CLOCKperiod)-(time2*normLSB);distance_buf[measure_cnt] (TOF1/2.0f)*(3e8f);if(measure_cnt 9){measure_cnt;state1 start;}else{state1 processing;measure_cnt 0;}}if(state1 send){char tx[50];sprintf(tx,%.3f\r\n,distance_buf[5]);HAL_UART_Transmit(huart1, (uint8_t *)tx, strlen(tx), 100);state1 blank;}}}/* USER CODE BEGIN 3 *//* USER CODE END 3 *//*** brief System Clock Configuration* retval None*/void SystemClock_Config(void){RCC_OscInitTypeDef RCC_OscInitStruct {0};RCC_ClkInitTypeDef RCC_ClkInitStruct {0};/** 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.HSEPredivValue RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState RCC_HSI_ON;RCC_OscInitStruct.PLL.PLLState RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL RCC_PLL_MUL9;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_ClkInitStruct.SYSCLKSource RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(RCC_ClkInitStruct, FLASH_LATENCY_2) ! HAL_OK){Error_Handler();}}/*** brief SPI1 Initialization Function* param None* retval None*/static void MX_SPI1_Init(void){/* USER CODE BEGIN SPI1_Init 0 *//* USER CODE END SPI1_Init 0 *//* USER CODE BEGIN SPI1_Init 1 *//* USER CODE END SPI1_Init 1 *//* SPI1 parameter configuration*/hspi1.Instance SPI1;hspi1.Init.Mode SPI_MODE_MASTER;hspi1.Init.Direction SPI_DIRECTION_2LINES;hspi1.Init.DataSize SPI_DATASIZE_8BIT;hspi1.Init.CLKPolarity SPI_POLARITY_LOW;hspi1.Init.CLKPhase SPI_PHASE_1EDGE;hspi1.Init.NSS SPI_NSS_SOFT;hspi1.Init.BaudRatePrescaler SPI_BAUDRATEPRESCALER_8;hspi1.Init.FirstBit SPI_FIRSTBIT_MSB;hspi1.Init.TIMode SPI_TIMODE_DISABLE;hspi1.Init.CRCCalculation SPI_CRCCALCULATION_DISABLE;hspi1.Init.CRCPolynomial 10;if (HAL_SPI_Init(hspi1) ! HAL_OK){Error_Handler();}/* USER CODE BEGIN SPI1_Init 2 *//* USER CODE END SPI1_Init 2 */}/*** brief TIM1 Initialization Function* param None* retval None*/static void MX_TIM1_Init(void){/* USER CODE BEGIN TIM1_Init 0 *//* USER CODE END TIM1_Init 0 */TIM_ClockConfigTypeDef sClockSourceConfig {0};TIM_MasterConfigTypeDef sMasterConfig {0};TIM_OC_InitTypeDef sConfigOC {0};TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig {0};/* USER CODE BEGIN TIM1_Init 1 *//* USER CODE END TIM1_Init 1 */htim1.Instance TIM1;htim1.Init.Prescaler 0;htim1.Init.CounterMode TIM_COUNTERMODE_UP;htim1.Init.Period 65535;htim1.Init.ClockDivision TIM_CLOCKDIVISION_DIV1;htim1.Init.RepetitionCounter 0;htim1.Init.AutoReloadPreload TIM_AUTORELOAD_PRELOAD_DISABLE;if (HAL_TIM_Base_Init(htim1) ! HAL_OK){Error_Handler();}sClockSourceConfig.ClockSource TIM_CLOCKSOURCE_INTERNAL;if (HAL_TIM_ConfigClockSource(htim1, sClockSourceConfig) ! HAL_OK){Error_Handler();}if (HAL_TIM_PWM_Init(htim1) ! HAL_OK){Error_Handler();}if (HAL_TIM_OnePulse_Init(htim1, TIM_OPMODE_SINGLE) ! HAL_OK){Error_Handler();}sMasterConfig.MasterOutputTrigger TIM_TRGO_RESET;sMasterConfig.MasterSlaveMode TIM_MASTERSLAVEMODE_DISABLE;if (HAL_TIMEx_MasterConfigSynchronization(htim1, sMasterConfig) ! HAL_OK){Error_Handler();}sConfigOC.OCMode TIM_OCMODE_PWM1;sConfigOC.Pulse 1;sConfigOC.OCPolarity TIM_OCPOLARITY_HIGH;sConfigOC.OCNPolarity TIM_OCNPOLARITY_HIGH;sConfigOC.OCFastMode TIM_OCFAST_DISABLE;sConfigOC.OCIdleState TIM_OCIDLESTATE_RESET;sConfigOC.OCNIdleState TIM_OCNIDLESTATE_RESET;if (HAL_TIM_PWM_ConfigChannel(htim1, sConfigOC, TIM_CHANNEL_1) ! HAL_OK){Error_Handler();}sBreakDeadTimeConfig.OffStateRunMode TIM_OSSR_DISABLE;sBreakDeadTimeConfig.OffStateIDLEMode TIM_OSSI_DISABLE;sBreakDeadTimeConfig.LockLevel TIM_LOCKLEVEL_OFF;sBreakDeadTimeConfig.DeadTime 0;sBreakDeadTimeConfig.BreakState TIM_BREAK_DISABLE;sBreakDeadTimeConfig.BreakPolarity TIM_BREAKPOLARITY_HIGH;sBreakDeadTimeConfig.AutomaticOutput TIM_AUTOMATICOUTPUT_DISABLE;if (HAL_TIMEx_ConfigBreakDeadTime(htim1, sBreakDeadTimeConfig) ! HAL_OK){Error_Handler();}/* USER CODE BEGIN TIM1_Init 2 *//* USER CODE END TIM1_Init 2 */HAL_TIM_MspPostInit(htim1);}/*** brief USART1 Initialization Function* param None* retval None*/static void MX_USART1_UART_Init(void){/* USER CODE BEGIN USART1_Init 0 *//* USER CODE END USART1_Init 0 *//* USER CODE BEGIN USART1_Init 1 *//* USER CODE END USART1_Init 1 */huart1.Instance USART1;huart1.Init.BaudRate 115200;huart1.Init.WordLength UART_WORDLENGTH_8B;huart1.Init.StopBits UART_STOPBITS_1;huart1.Init.Parity UART_PARITY_NONE;huart1.Init.Mode UART_MODE_TX_RX;huart1.Init.HwFlowCtl UART_HWCONTROL_NONE;huart1.Init.OverSampling UART_OVERSAMPLING_16;if (HAL_UART_Init(huart1) ! HAL_OK){Error_Handler();}/* USER CODE BEGIN USART1_Init 2 *//* USER CODE END USART1_Init 2 */}/*** brief GPIO Initialization Function* param None* retval None*/static void MX_GPIO_Init(void){GPIO_InitTypeDef GPIO_InitStruct {0};/* USER CODE BEGIN MX_GPIO_Init_1 *//* USER CODE END MX_GPIO_Init_1 *//* GPIO Ports Clock Enable */__HAL_RCC_GPIOD_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(start_GPIO_Port, start_Pin, GPIO_PIN_RESET);/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);/*Configure GPIO pins : PA0 PA2 */GPIO_InitStruct.Pin GPIO_PIN_0|GPIO_PIN_2;GPIO_InitStruct.Mode GPIO_MODE_IT_RISING;GPIO_InitStruct.Pull GPIO_NOPULL;HAL_GPIO_Init(GPIOA, GPIO_InitStruct);/*Configure GPIO pins : start_Pin CS_Pin */GPIO_InitStruct.Pin start_Pin|CS_Pin;GPIO_InitStruct.Mode GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull GPIO_NOPULL;GPIO_InitStruct.Speed GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOA, GPIO_InitStruct);/* EXTI interrupt init*/HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);HAL_NVIC_EnableIRQ(EXTI0_IRQn);/* USER CODE BEGIN MX_GPIO_Init_2 *//* USER CODE END MX_GPIO_Init_2 */}/* USER CODE BEGIN 4 */void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){if(GPIO_Pin GPIO_PIN_0){/*GPIO0中断是用来TDC计数结束*/state1 read;}if(GPIO_Pin GPIO_PIN_2){/*GPIO2中断是用来开始一次测量*/state1 start;}}/* USER CODE END 4 *//*** 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 */