TMC2240步进电机驱动芯片寄存器配置和电路设计
前言:原来使用过tmc2226驱动芯片,不过都是使用的基础功能,简单的配置一下电流和细分,通过STEP、DIR信号来控制电机转动就OK了,现在又开始使用tmc2240,网上详细的寄存器配置资料真是少之又少,大部分是厂家引流用的芯片介绍VIP文章(当然我也不是tmc的人,才写的这个文章)面对一百多页的英文数据手册让我这个四级都没过的人直接劝退,翻译成中文都很让人晦涩难懂。我直接把整个PDF喂给了AI,一步一步询问出了部分功能的配置方法。
1.TMC2240芯片介绍
TMC2240 是一款智能高性能步进电机驱动器 IC,具有串行通信接口(SPI、UART)和广泛的诊断功能。
它结合了业界最先进的步进电机驱动器,该驱动器基于 256 步内置分度器和两个完全集成的 36V、3.0AMAX H 桥以及非耗散集成电流感应 (ICS)。
TMC2240 具有丰富的诊断和保护功能,例如短路保护/OCP、热关断、欠压锁定。在热关断和欠压锁定事件期间,驱动器被禁用。
此外,TMC2240 还提供测量驱动器温度、估计电机温度和测量一个外部模拟输入的功能。(叽里呱啦一大堆,我全复制粘贴,看看就行了)
MicroPlyer™(微步插值器)、 CoolStep™(电流节能控制) 、 SpreadCycle™(高精度斩波算法) 、StallGuard2™(无传感器失速检测和机械负载测量)、 StealthChop2™(静音斩波模式) 、StallGuard4™
(这些功能才是重点,后面依次介绍和寄存器详细配置)
2.TMC2240原理图设计
2.1 STEP(Pin 31)为脉冲引脚 , DIR(Pin 32)为方向控制引脚
STEP(Pin 31)为脉冲引脚上可以把上面的led指示灯电路删除,有可能影响脉冲个数,请参考这篇文章https://blog.csdn.net/weixin_44119021/article/details/152267849?spm=1001.2014.3001.5502
2.2 DRV_ENN(Pin 9)为使能引脚
当DRV_ENN为低电平时,驱动器使能,电机可以正常驱动。
当DRV_ENN为高电平时,驱动器被禁用,所有功率MOSFET被关闭,电机线圈处于高阻态(自由状态)
在系统上电或初始化期间,保持驱动器禁用直到配置完成(默认上拉电阻拉高电平,配置完通过单片机引脚拉低电平)。
2.3 IREF引脚(Pin 1):用于电流缩放的模拟参考电流。提供外部电阻到地。
全量程电流IFS由IREF引脚上的电阻RREF和DRV_CONF寄存器中的CURRENT_RANGE设置共同决定。
全量程电流 IFS 的计算公式为:IFS = KIFS / RREF
其中:
IFS = 全量程电流(A)
KIFS = 电流常数(A·kΩ),取决于 CURRENT_RANGE 设置
RREF = IREF 引脚电阻值(kΩ)
12kΩ 电阻对应最大 3A 全量程电流,适合驱动大功率步进电机,可以根据自己的电机电流大小,选择合适的采样电阻。
2.4 SPI或UART通信方式:(原理图为spi)
当10引脚UART_EN连接低电平时,SPI接口被启用,就可以通过26-29引脚使用spi通信。
当10引脚UART_EN连接高电平时,UART接口被启用,则26-29引脚变成UART的地址引脚,
12引脚DIAG1/SW变为UART模式下的单线I/O.。
2.5 时钟CLK输入引脚(Pin 30):
内部时钟模式:将CLK引脚直接接地(GND),芯片使用内部振荡器(典型频率12.5MHz)(最常用)
外部时钟模式:向CLK引脚提供外部时钟信号(频率范围12MHz至20MHz),芯片使用外部时钟。
2.6 DIAG1/SW引脚(Pin 12)和DIAG0引脚(Pin 11):
是两个多功能诊断输出引脚,其功能可通过寄存器配置实现灵活应用。
1.故障诊断输出:
过温保护(OT)
过流保护(OCP)
欠压锁定(UVLO)
电机开路检测(Open Load)
2.堵转检测输出
输出信号类型可以通过配置GCONF (0x0)寄存器的diag1 pushpull位和diago pushpull位,需根据实际电路设计选择(推挽/开漏)。
2.7 其他功能(暂时未用)
1.OV引脚(Pin 13):过压保护输出
OV引脚是一个开漏输出(Open-Drain),用于指示电源电压(VS)是否超过设定的过压保护阈值。当VS超过阈值时,OV引脚会拉低电平,触发外部保护电路(如泄放电阻或MOSFET)以降低电压。
2.AIN引脚(Pin 2):
通用模拟输入: 该引脚是一个多功能模拟输入接口,可用于连接外部模拟信号传感器(如温度传感器、电位器等)。
诊断与配置 : 结合芯片内部ADC,可将模拟信号转换为数字值供系统读取(例如用于电机温度监测或环境参数检测)
3.ENCN(Pin 6)、ENCB(Pin 7)、ENCA(Pin 8) 的编码器功能
启用条件:需通过SPI设置寄存器 ENCMODE (0x07) 切换为编码器模式
3.TMC2240的SPI通信
3.1SPI数据包结构
TMC2240使用40位SPI(串行外设接口,SPI是摩托罗拉的商标)数据报用于与微控制器进行通信。配备硬件SPI功能的微控制器通常能够使用8位整数倍进行通信。设备上的CSN线必须在数据报传输的整个过程中保持激活状态(即低电平)。
发送到设备的每个数据报都包含一个地址字节,其后跟着四个数据字节。这使得可以直接与寄存器集进行32位数据字级别的通信。即使某个寄存器使用的数据位数少于32位,也可以通过32个数据位来访问它。
为了简化,每个寄存器由一个字节地址指定:
对于读取访问,地址字节的最高有效位是0。
对于写访问,地址字节的最高有效位为1。
所有寄存器都是可读的,其中大多数是读写类型的,一些是只读类型的,一些是写入清除类型的(例如GSTAT寄存器)
3.2 STM32F4单片机的SPI外设初始化
3.3 TMC2240寄存器数据读写
static uint8_t SPIReadAndWrite(uint8_t dat)
{uint8_t Rxdata;HAL_SPI_TransmitReceive(&hspi1, &dat, &Rxdata, 1, 1000);return Rxdata;
}
/*** @Name TMC2240Reg_Write //tmc516芯片通用* @brief tmc2240寄存器数据写入* @param motor: [输入] 电机序号
** reg: [输入] 寄存器地址
** data: [输入] 寄存器数据
* @retval retData: 上次写入的数据*/
uint32_t TMC2240Reg_Write(uint8_t motor_num, uint8_t reg, uint32_t data)
{uint32_t retData = 0;uint8_t sendBuff[4] = {0, 0, 0, 0};uint8_t rcvBuf[4] = {0, 0, 0, 0};uint8_t tmc_status;sendBuff[0] = (data >> 24) & 0xFF;sendBuff[1] = (data >> 16) & 0xFF;sendBuff[2] = (data >> 8) & 0xFF;sendBuff[3] = data & 0xFF;TMC2240_Cs(motor_num, 0);tmc_status = SPIReadAndWrite(reg | 0x80); //写命令 1xxxxxxxxrcvBuf[0] = SPIReadAndWrite(sendBuff[0]);rcvBuf[1] = SPIReadAndWrite(sendBuff[1]);rcvBuf[2] = SPIReadAndWrite(sendBuff[2]);rcvBuf[3] = SPIReadAndWrite(sendBuff[3]);TMC2240_Cs(motor_num, 1);retData = rcvBuf[0] << 24 | rcvBuf[1] << 16 | rcvBuf[2] << 8 | rcvBuf[3];return retData;
}/*** @Name TMC2240Reg_Read //tmc516芯片通用* @brief* @param motor: [输入]电机序号
** reg: [输入]寄存器地址* @retval*/
uint32_t TMC2240Reg_Read(uint8_t motor_num, uint8_t reg)
{uint32_t retData = 0;uint8_t rcvBuf[4] = {0, 0, 0, 0};uint8_t tmc_status;uint8_t i;TMC2240_Cs(motor_num, 0);SPIReadAndWrite(reg); //读命令 0xxxxxxxxSPIReadAndWrite(0x00);SPIReadAndWrite(0x00);SPIReadAndWrite(0x00);SPIReadAndWrite(0x00);TMC2240_Cs(motor_num, 1);for(i = 0; i < 5; i++) //延时{ }TMC2240_Cs(motor_num, 0);tmc_status = SPIReadAndWrite(reg); //读命令 0xxxxxxxxrcvBuf[0] = SPIReadAndWrite(0x00);rcvBuf[1] = SPIReadAndWrite(0x00);rcvBuf[2] = SPIReadAndWrite(0x00);rcvBuf[3] = SPIReadAndWrite(0x00);TMC2240_Cs(motor_num, 1);retData = rcvBuf[0] << 24 | rcvBuf[1] << 16 | rcvBuf[2] << 8 | rcvBuf[3];return retData;}
4.TMC2240的常用功能寄存器配置
4.1电流配置
4.1.1 设置电流范围 (DRV_CONF)
在 DRV_CONF 寄存器(地址 0x0A)中设置 CURRENT_RANGE[1:0]:(原理图部分讲过)
全量程电流 IFS 的计算公式为:IFS = KIFS / RREF
4.1.2 全局电流缩放 (GLOBAL_SCALER)
在 GLOBAL_SCALER 寄存器(地址 0x0B)中微调电流:
值范围:32-255 (对应 32/256 到 255/256)
0 或 256 = 满量程
1-31 = 无效
4.1.3 配置运行和保持电流 (IHOLD_IRUN)
在 IHOLD_IRUN 寄存器(地址 0x10)中设置:
IRUN[4:0] (位 12:8):运行电流比例 (0-31 = 1/32 到 32/32)
IHOLD[4:0] (位 4:0):保持电流比例 (0-31 = 1/32 到 32/32)
IRUNDELAY[3:0] (位 27:24):电流上升延时
IHOLDDELAY[3:0] (位 19:16):电流下降延时
实际电流计算公式:I_actual = IFS × (IRUN/32) × (GLOBAL_SCALER/256)
4.1.4 配置功率下降延时 (TPOWERDOWN)
在 TPOWERDOWN 寄存器(地址 0x11)中设置从运行电流降到保持电流的延时,一般不用设置,芯片复位后有默认参数。
4.1.5 完整配置示例(根据自己需求修改)
假设要配置:
满量程电流:2A (RREF=12kΩ, CURRENT_RANGE=01)
运行电流:1.2A
保持电流:0.4A
电流升降平滑延时
// 1. 设置电流范围 (2A)
spi_write(0x8A, 0x00000001);// 2. 设置全局缩放 (100%)
spi_write(0x8B, 0x00000000); // 0 = 256/256// 3. 计算电流比例
// IRUN = (1.2A / 2A) × 32 = 19.2 → 19
// IHOLD = (0.4A / 2A) × 32 = 6.4 → 6
uint32_t ihold_irun = (2 << 24) | (3 << 16) | (19 << 8) | (6 << 0);
spi_write(0x90, ihold_irun);// 4. 设置功率下降延时
spi_write(0x91, 0x00000020);
4.2 细分配置
4.2.1 TMC2240 中配置微步细分(Microstepping) 是通过设置 CHOPCONF 寄存器中的 MRES 位来实现的。
建议在初始化时一次性配置好所有 CHOPCONF 参数,避免频繁修改。
不需要配置的寄存器位可以用官方手册的复位后的默认参数
4.3 SpreadCycle和StealthChop2
4.3.1SpreadCycle和StealthChop2对比
SpreadCycle:高动态性能,有斩波噪声,适用于高速和高动态应用。
StealthChop2:静音,但动态性能相对较低,适用于低速和静音应用。
4.3.2 SpreadCycle功能详解
SpreadCycle是TMC2240中一种高精度的电流控制斩波模式,旨在提供高动态性能和平稳的运行特性。它通过智能控制衰减相位来优化电流调节,减少转矩纹波,提高微步进精度。
工作原理:
SpreadCycle采用固定频率的斩波算法,每个斩波周期包含多个相位(通常包括一个开启相位、一个慢衰减相位、一个快衰减相位和另一个慢衰减相位)。这种结构允许在每个周期内精确控制电流,从而实现平滑的电流波形。
核心特点:
高动态响应:适用于高速运动和高加速度应用。
平滑运行:通过优化衰减时间,减少电流纹波,使电机运行更平稳。
自动调整:可以自动调整衰减时间以适应不同的电机参数和运行条件。
寄存器配置示例:
以下是一个典型的SpreadCycle配置示例(CHOPCONF寄存器):
使用数据手册推荐的默认值,需要根据自己的电机基于实际应用需求微调参数
// 假设使用16微步,其他参数如下:
TOFF = 3; // 慢衰减时间设置
TBL = 2; // 空白时间设置(36个时钟周期)
HSTRT = 5; // hysteresis start值
HEND = 2; // hysteresis end值
CHM = 0; // 选择SpreadCycle模式// 将这些参数组合成CHOPCONF寄存器的值:
uint32_t CHOPCONF_Data = (TOFF & 0x0F) | ((TBL & 0x03) << 15) | ((HSTRT & 0x07) << 4) | ((HEND & 0x0F) << 0) | (0 << 14); // CHM=0 for SpreadCycle
4.3.3 StealthChop2功能详解
StealthChop是TMC2240的一种静音驱动模式,它通过电压PWM控制来实现几乎无声的电机运行。与SpreadCycle的电流斩波不同,StealthChop通过调节施加在线圈上的电压有效值来控制电流,从而避免斩波噪声。
工作原理:
StealthChop通过测量电机线圈的电流,并调节PWM占空比来使电流达到目标值。它使用一种称为“StealthChop2”的自动调谐算法,该算法在电机首次运行时学习电机参数(如线圈电阻、电感等),并不断适应变化(如温度引起的参数变化)。
主要特点:
绝对静音:在低速和静止时几乎无噪声。
自动调谐:能够自动学习电机参数并优化PWM设置。
电压控制:基于电压PWM,而不是电流斩波。
寄存器配置示例:
以下是一个典型的StealthChop配置示例:
启用StealthChop模式:
GCONF |= (1 << 2); // en_pwm_mode = 1 (启用StealthChop模式)
// 确保禁用直接模式(如果不需要)
GCONF &= ~(1 << 16); // direct_mode = 0
配置PWM参数(PWMCONF寄存器):
PWM频率(PWM_FREQ):通常设置为1或2,对应24kHz或36kHz(取决于时钟)。
自动调谐(pwm_autoscale和pwm_autograd):设置为1以启用自动调谐。
PWM_REG:调节器的响应速度,通常设置为4-8。
uint32_t PWMCONF = 0;
// 自动调谐设置
PWMCONF |= (1 << 18); // pwm_autoscale = 1(自动电流调节)
PWMCONF |= (1 << 19); // pwm_autograd = 1(自动梯度调节)
// PWM频率选择(根据应用需求)
PWMCONF |= (1 << 16); // PWM_FREQ = 1 (24kHz)
// 调节器参数
PWMCONF |= (4 << 24); // PWM_REG = 4 (调节强度,1-15)
// 静止模式选项
PWMCONF |= (0 << 23); // pwm_dis_reg_stst = 0 (静止时也调节)
PWMCONF |= (0 << 22); // pwm_meas_sd_enable = 0 (仅on-phase测量)
设置速度阈值(TPWMTHRS):
当电机速度超过这个阈值时,可以自动切换到SpreadCycle模式(如果启用的话)。
// TPWMTHRS (0x13) - StealthChop最大速度阈值
// StealthChop2 处理低速静音, SpreadCycle 处理高速性能
// TPWMTHRS 寄存器里存放的是一个时间值,而不是直接的速度值。这个时间值 TSTEP 表示完成一个 256 微步所需要的时间(以芯片时钟周期为单位)。
// 当实测的 TSTEP 时间 > TPWMTHRS:电机速度较慢,使用 StealthChop2 模式。
// 当实测的 TSTEP 时间 <=TPWMTHRS:电机速度较快,自动切换至 SpreadCycle 模式。
// 速度越快,完成一个微步的时间越短,TSTEP 值就越小。因此,你设置一个较小的 TPWMTHRS 值,就意味着在更高的速度下才会切换。
// 参数调试:使用你要设定的速度让电机运行,读取TMC2240_TSTEP寄存器值,TMC2240Reg_Read( MOTORx ,TMC2240_TSTEP ); 读取的值就是设置值 0x00完全静音
// 建议的切换点通常在中低速区域(例如100-500 RPM范围内选择)
uint32_t TPWMTHRS = 0x00000100; // 示例值,根据实际调整// 设置为0可强制始终使用StealthChop
// TPWMTHRS = 0x00000000; // 总是StealthChop模式,完全静音
4.4 StallGuard2和StallGuard4
StallGuard2和StallGuard4是TMC2240中两种不同的无传感器负载检测技术,它们分别针对不同的斩波模式优化
🔍 StallGuard2 与 StallGuard4 的区别
-
对应的斩波模式
StallGuard2:与 SpreadCycle 斩波模式配合使用。
StallGuard4:与 StealthChop 斩波模式配合使用。 -
工作原理
StallGuard2:基于电机线圈的反电动势(back EMF)和电流波形来检测负载。它测量电机负载角,当负载增加时,负载角增大,SG_RESULT值降低。
StallGuard4:专门为电压模式PWM(StealthChop)设计,通过监测电机线圈的电流和电压相位关系来检测负载。它使用不同的信号处理机制,适用于StealthChop的静音操作。 -
配置寄存器
StallGuard2:使用 COOLCONF 寄存器(地址0x6D)中的 SGT 字段(有符号7位,-64至+63)来设置灵敏度。
StallGuard4:使用 SG4_THRS 寄存器(地址0x74)来设置阈值,并且有额外的过滤和测量选项。 -
输出结果
StallGuard2:提供10位的 SG_RESULT(在 DRV_STATUS 寄存器中),值范围0-1023,值越小表示负载越大。
StallGuard4:提供9位的 SG4_RESULT(在 SG4_RESULT 寄存器中),值范围0-510,同样值越小表示负载越大。此外,还可以读取四个独立的测量值 SG4_IND_0 到 SG4_IND_3。 -
滤波和更新率
StallGuard2:可以通过 sflt 位(在 COOLCONF 中)启用滤波,滤波后更新率降低(每4个全步更新一次)。
StallGuard4:可以通过 sg4_filt_en 位(在 SG4_THRS 中)启用滤波,滤波后提供四个独立测量的平均值,更新率同样降低。 -
失速检测方式
StallGuard2:当 SG_RESULT 下降到0(或接近0)时,表示失速。可以通过设置 SGT 来调整失速检测的阈值。
StallGuard4:当 SG4_RESULT 下降到低于 SG4_THRS 的两倍时,表示失速。即:SG4_RESULT < 2 * SG4_THRS 时触发失速。 -
适用场景
StallGuard2:适用于需要高动态响应和精确负载检测的应用,如3D打印机、CNC机床等。
StallGuard4:适用于要求静音操作的应用,如办公设备、医疗设备、家庭自动化等,同时需要负载检测。 -
配置复杂性
StallGuard2:需要调整 SGT 值来适应不同的电机和机械系统,调试相对直观。
StallGuard4:需要调整 SG4_THRS,并且由于StealthChop的特性,调试可能更复杂,因为电压模式PWM对电机参数变化更敏感。 -
速度范围
StallGuard2:在较低速度(如10-1000 RPM)下工作良好,速度过高时检测精度下降。
StallGuard4:同样在中等速度范围内工作,但具体范围可能因电机和设置而异。
📊 如何选择
如果你的应用需要高动态性能和精确的负载检测,并且对噪音不敏感,选择 SpreadCycle + StallGuard2。
如果你的应用要求静音操作,同时需要负载检测,选择 StealthChop + StallGuard4。
🔄 同时使用两者
TMC2240允许在同一个应用中根据速度阈值切换斩波模式,从而在不同速度段使用不同的StallGuard技术。例如:
低速时使用 StealthChop + StallGuard4(静音)
高速时使用 SpreadCycle + StallGuard2(高动态)
通过设置 TPWMTHRS 和 TCOOLTHRS 等速度阈值寄存器来实现自动切换。
4.4.1 StallGuard2 配置步骤
- 启用 SpreadCycle 模式
StallGuard2 只在 SpreadCycle 模式下工作:
// 在 CHOPCONF 寄存器中设置 chm=0 (SpreadCycle)
// 地址 0x6C, chm 位在 bit 14
uint32_t chopconf = (0 << 14); // chm=0: SpreadCycle
spi_write(0xEC, chopconf); // 0xEC = 0x6C + 0x80
- 设置速度阈值 (TCOOLTHRS)
StallGuard2 需要在特定速度范围内工作:
// TCOOLTHRS 寄存器 (地址 0x14)
// 设置 StallGuard2 使能的最小速度阈值
// TSTEP < TCOOLTHRS 时 StallGuard2 工作// 示例:设置速度阈值对应 ~100 RPM
uint32_t tcoolthrs = 2000; // 需要根据实际应用调整
spi_write(0x94, tcoolthrs); // 0x94 = 0x14 + 0x80
- 配置 StallGuard2 灵敏度 (SGT)
对于 SpreadCycle 模式 (StallGuard2)
SGT (在 COOLCONF 中) 灵敏度阈值。这是一个有符号 7 位整数(-64 到 -1)(0xC0 - 0xFF) ,(0 - 63) 0x00 - 0x3F 这是最重要的调试参数。
SGT 值越负(例如 -40),灵敏度越高(更容易触发失速检测)。
SGT 值越正(例如 +20),灵敏度越低(需要更大的负载才能触发)。
sflit (在 COOLCONF 中) 滤波使能。对 StallGuard2 结果进行滤波,使读数更稳定,但会降低响应速度。
在 COOLCONF 寄存器中设置灵敏度:
// COOLCONF 寄存器 (地址 0x6D)
// SGT[6:0] 在 bit 6:0 (有符号7位数,-64 到 +63)// 灵敏度设置:
// 负值:更敏感(更容易检测到失速)
// 正值:更不敏感
// 0:中等灵敏度int8_t sgt_value = -10; // 示例:较高灵敏度
uint32_t coolconf = ((uint8_t)sgt_value & 0x7F) | (1 << 24); // sflt=1 启用滤波
spi_write(0xED, coolconf); // 0xED = 0x6D + 0x80
确定最佳 SGT 值
读取 StallGuard2 结果 (DRV_STATUS)
SG_RESULT[9:0] (位 15:0):StallGuard2 测量结果。值越小表示负载越大,当值接近0时表示可能失速。
stallGuard (位 24):失速标志位。当 StallGuard2 检测到失速时,该位被置1。
- 配置诊断输出(可选)
设置 DIAG 引脚输出 StallGuard2 检测结果:
// GCONF 寄存器 (地址 0x00)
// 设置 diag0_stall 或 diag1_stalluint32_t gconf = (1 << 7); // diag0_stall = 1 (DIAG0 输出失速信号)
spi_write(0x80, gconf); // 0x80 = 0x00 + 0x80
4.4.2 StallGuard4 配置步骤
StallGuard4 是 TMC2240 中专为 StealthChop 模式优化的负载检测功能。
1.启用 StealthChop 模式
// GCONF 寄存器 (0x00) - 启用 StealthChop
uint32_t gconf = (1 << 2); // en_pwm_mode = 1
spi_write(0x80, gconf); // 0x80 = 0x00 + 0x80
2.设置速度阈值
// TCOOLTHRS (0x14) - StallGuard4 最低工作速度
uint32_t tcoolthrs = 1000; // 需要根据应用调整
spi_write(0x94, tcoolthrs);// TPWMTHRS (0x13) - StealthChop 最高速度
uint32_t tpwmthrs = 500; // 低于此速度使用 StealthChop
spi_write(0x93, tpwmthrs);
3.配置 StallGuard4 阈值
// SG4_THRS 寄存器 (0x74)
uint8_t sg4_thrs = 60; // 灵敏度阈值 (0-255)
spi_write(0xF4, sg4_thrs); // 0xF4 = 0x74 + 0x80
4.启用滤波模式
// 在 SG4_THRS 寄存器中启用滤波
uint8_t sg4_thrs_value = 60;
// sg4_filt_en = 1 (启用4点滤波)
uint32_t sg4_thrs_reg = sg4_thrs_value | (1 << 8);
spi_write(0xF4, sg4_thrs_reg);
5.配置模式切换优化
// 启用优化的 StealthChop/SpreadCycle 切换
// 在 COOLCONF 寄存器中设置 sg_angle_offset
uint32_t coolconf = spi_read(0x6D);
coolconf |= (1 << 25); // sg_angle_offset = 1
spi_write(0xED, coolconf);
6.配置诊断输出
// GCONF 寄存器 - 设置 DIAG 引脚输出失速信号
uint32_t gconf = spi_read(0x00);
gconf |= (1 << 7); // diag0_stall = 1
// 或 gconf |= (1 << 8); // diag1_stall = 1
spi_write(0x80, gconf);