找回密码
 立即注册
楼主: wlhuangcn

【求助】关于MT6816读取数据的问题

[复制链接]

865

主题

1万

回帖

2万

积分

管理员

积分
25102
发表于 2026-7-22 21:07:13 | 显示全部楼层

好的,我已经完整阅读了该论坛帖子。下面我来为您做一个详细的分析和解答。


关于 MT6816 角度传感器通过 STC 单片机 SPI 读取数据的问题分析

帖子核心问题回顾

楼主 wlhua* 使用 STC 单片机(从代码看是 STC32G 或 STC8H 系列)的硬件 SPI 读取 MT6816 角度数据,返回始终为 0。改用软件模拟 SPI 后可以正常读取数据(弱磁标识有效),说明硬件 SPI 配置存在问题。


问题分析

从楼主贴出的代码来看,硬件 SPI 配置存在以下几个关键疑点

1. GPIO 模式配置问题

SPI_Pin_Cfg.Mode = GPIO_OUT_PP; // MOSI(P1.3)、SCK(P1.5)、CS(P1.6) 设为推挽输出 ✓
SPI_Pin_Cfg.Pin = GPIO_Pin_3 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_Inilize_Ret = GPIO_Inilize(GPIO_P1, &SPI_Pin_Cfg);

SPI_Pin_Cfg.Mode = GPIO_HighZ;  // MISO(P1.4) 设为高阻输入 ✓
SPI_Pin_Cfg.Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4;
GPIO_Inilize_Ret = GPIO_Inilize(GPIO_P1, &SPI_Pin_Cfg);

这里 P1.0、P1.1 也被设为了高阻,但代码中并未使用这两个引脚做 SPI,这本身不是问题,但需注意 P1.0/P1.1 如果被其他外设复用可能会受影响。

2. SPI 模式配置——最可能的问题所在

SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;  // CPOL=1
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; // CPHA=1  → 模式3 ✓

**CPOL=1, CPHA=1 确实是 SPI 模式3**,这个配置本身是对的。但问题可能出在:

MT6816 的数据手册中,读操作时序要求:

  • 先发送命令字节(高位为 1 表示读,低 7 位为寄存器地址)
  • 然后接收 2 个字节的数据(16 位角度值)
  • 片选 CS 在传输期间保持低电平

3. 硬件 SPI 读取时序不匹配——核心问题

楼主读取函数的代码(帖子中未完整显示,但从上下文推断):

u8 MT6816_Read_Reg(u8 RegisterAddr)
{
    u8 ReadCommand = 0x00;
    u8 ReceiveData = 0x00;
    bit EnableAllINT_Flag;
    ReadCommand = RegisterAddr | 0x80;  // 读命令
    // ... 后续代码未完整显示
}

硬件 SPI 读 MT6816 的典型问题:

MT6816 的读时序是:主机发送命令字节的同时,从机返回数据。但很多硬件 SPI 在发送完最后一个字节后,需要**额外再发送一个 dummy 字节(0x00)**才能把从机的最后一个字节时钟出来。

对于 MT6816 这类 16 位数据输出的传感器,正确的硬件 SPI 读取流程应该是:

CS = 0;
SPI_Write(ReadCmd);      // 发送读命令(8位)
SPI_Write(0x00);         // 发送 dummy 字节,同时接收高8位数据
SPI_Write(0x00);         // 发送 dummy 字节,同时接收低8位数据
CS = 1;

而楼主的代码可能只发送了一个命令字节就试图读取,导致数据为 0。


解决方案

方案一:修正硬件 SPI 读取函数(推荐)

// 读取 MT6816 16位角度数据(硬件SPI模式3)
u16 MT6816_ReadAngle(void)
{
    u8 i;
    u16 angle = 0;
    u8 rx_h, rx_l;
  
    SPI_MT6816_CSN = 0;                     // 片选拉低
    NOP40();                                // 等待tCSS
  
    SPI_ReadWriteByte(0x83);                // 发送读命令(读角度寄存器0x03)
    rx_h = SPI_ReadWriteByte(0x00);         // 发送dummy,接收高8位
    rx_l = SPI_ReadWriteByte(0x00);         // 发送dummy,接收低8位
  
    SPI_MT6816_CSN = 1;                     // 片选拉高
    NOP40();                                // 等待tCSH
  
    angle = ((u16)rx_h << 8) | rx_l;        // 合并16位数据
    return angle;
}

// 硬件SPI读写一个字节
u8 SPI_ReadWriteByte(u8 dat)
{
    SPI_DATA = dat;                         // 写入发送数据
    while((SPI_STAT & 0x80) == 0);          // 等待SPIF置位
    SPI_STAT = 0x80;                        // 清除SPIF标志
    return SPI_DATA;                        // 返回接收数据
}

方案二:使用软件模拟 SPI(已验证可行)

参考帖子中 社区* 提供的代码,软件 SPI 已经验证可以正常读取:

// 软件SPI发送8位数据
void SPI_SEND_U8_DATA(u8 dat)
{
    u8 i;
    for(i = 0; i < 8; i++)
    {
        if(dat & 0x80)  SPI_MOSI = 1;
        else            SPI_MOSI = 0;
        SPI_CLK = 0;                // 下降沿
        dat <<= 1;
        NOP10();
        SPI_CLK = 1;                // 上升沿
        NOP2();
    }
}

// 软件SPI接收n位数据
u8 read_angle_8(u8 n)
{
    u8 i;
    u8 dat = 0;
    for(i = 0; i < n; i++)
    {
        SPI_MOSI = 0;
        SPI_CLK = 0;                // 下降沿
        NOP10();
        dat <<= 1;
        SPI_CLK = 1;                // 上升沿
        NOP2();
        if(SPI_MISO) dat++;
    }
    return dat;
}

// 读取MT6825角度(兼容MT6816)
u16 read_6825_angle(void)
{
    u8 l_data, h_data, low_data;
  
    SPI_CS = 0;                     // 启动SPI
    SPI_SEND_U8_DATA(0x83);         // 发送读命令
    h_data = read_angle_8(8);       // 接收高8位
    l_data = read_angle_8(8);       // 接收低8位
    low_data = read_angle_8(2);     // 接收低2位(MT6825特有)
    SPI_CS = 1;
  
    l_data = (l_data & 0xfc) | low_data;
    return (((u16)h_data << 8) | l_data);
}

注意:MT6816 是 14 位分辨率,角度数据为 16 位(高 14 位有效,低 2 位为状态位),而 MT6825 是 18 位分辨率。如果使用 MT6816,读取 2 个字节即可,不需要再读额外的 2 位。


调试建议

  1. 用示波器/逻辑分析仪抓波形:对比硬件 SPI 和软件 SPI 的时序,看 CS、SCK、MOSI、MISO 的波形差异,这是最直接的排查手段。
  2. 降低 SPI 速度:楼主代码中 SPI_Speed_8(时钟分频 8),可以尝试改为 SPI_Speed_16SPI_Speed_64,排除速度过快导致的问题。
  3. 检查 MT6816 的 CS 片选时序:MT6816 对 CS 的建立时间(tCSS)和保持时间(tCSH)有要求,硬件 SPI 如果 CS 控制不当可能导致通信失败。
  4. 确认 MISO 引脚配置:MISO 必须设为高阻输入(楼主已配置为 GPIO_HighZ,正确)。
  5. 检查硬件连接:确认 MT6816 的 VDD、GND、CS、SCK、MOSI、MISO 接线正确,上拉电阻是否合适。

总结

问题 原因 解决方案
硬件 SPI 读回 0 时序不匹配,缺少 dummy 字节 发送命令后补发 dummy 字节以时钟出数据
软件 SPI 可读 时序完全可控 可作为临时方案或参考时序
数据是否正确待验证 需确认寄存器地址和位定义 参考 MT6816 数据手册核对

建议:先用软件 SPI 调通协议、确认数据正确后,再对照软件 SPI 的时序用逻辑分析仪抓波形,然后调整硬件 SPI 配置使其时序一致。如果硬件 SPI 实在调不通,软件 SPI 完全够用,且移植性更好。


🔍 搜索 "https://www.stcaimcu.com/thread-24254-1-1.html"

⏱️ 查找用时 3.5s | 总回答用时 24.6s

回复

使用道具 举报 送花

已绑定手机

6

主题

35

回帖

668

积分

高级会员

积分
668
 楼主| 发表于 2026-7-23 16:31:56 | 显示全部楼层
神*** 发表于 2026-7-22 21:07
好的,我已经完整阅读了该论坛帖子。下面我来为您做一个详细的分析和解答。

关于 MT6816 角度传感器通过 S ...

谢谢!当前使用软件SPI已能正常获取角度。

点评

争取 硬件 SPI 也可以  详情 回复 发表于 2026-7-23 18:02
回复

使用道具 举报 送花

865

主题

1万

回帖

2万

积分

管理员

积分
25102
发表于 2026-7-23 18:02:57 | 显示全部楼层
wlhua*** 发表于 2026-7-23 16:31
谢谢!当前使用软件SPI已能正常获取角度。

争取 硬件 SPI 也可以
回复

使用道具 举报 送花

已绑定手机

6

主题

35

回帖

668

积分

高级会员

积分
668
 楼主| 发表于 2026-7-25 20:29:07 | 显示全部楼层
神*** 发表于 2026-7-23 18:02
争取 硬件 SPI 也可以

硬件SPI测试过多次,读取到的数据始终是0,原来的设想是在零介入的情况下使用硬件SPI结合DMA按给定频率自动获取数据,因硬件SPI不能正确获取数据,所以就放弃了!现在只能使用软件SPI才能正确读取数据。
回复

使用道具 举报 送花

已绑定手机

6

主题

502

回帖

2465

积分

金牌会员

积分
2465
发表于 2026-8-31 20:34:39 | 显示全部楼层
挺好
学习
回复

使用道具 举报 送花

1

主题

122

回帖

1469

积分

金牌会员

积分
1469
发表于 2026-8-31 21:26:18 | 显示全部楼层
先查配置
回复

使用道具 举报 送花

已绑定手机

6

主题

502

回帖

2465

积分

金牌会员

积分
2465
发表于 2026-9-3 19:25:43 | 显示全部楼层
可能时时序问题
学习
回复

使用道具 举报 送花

已绑定手机

6

主题

35

回帖

668

积分

高级会员

积分
668
 楼主| 发表于 2026-9-6 00:43:09 | 显示全部楼层
patch*** 发表于 2026-9-3 19:25
可能时时序问题

我认为是硬件SPI的片选信号状态转换后的电平稳定时间问题,这个时间不可配置,属于硬件SPI的固有特性,所以硬件SPI获取不到数据。
回复

使用道具 举报 送花

已绑定手机

6

主题

502

回帖

2465

积分

金牌会员

积分
2465
发表于 2026-9-6 12:08:21 | 显示全部楼层
wlhua*** 发表于 2026-9-6 00:43
我认为是硬件SPI的片选信号状态转换后的电平稳定时间问题,这个时间不可配置,属于硬件SPI的固有特性,所 ...

用示波器看一下,硬件spi和软件spi的pwm脉宽是有差别的,一般情况下软件spi要宽一些,就是周期长
学习
回复

使用道具 举报 送花

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

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-9-22 06:03 , Processed in 0.074896 second(s), 91 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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