找回密码
 立即注册
查看: 129|回复: 6

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

[复制链接]
  • 打卡等级:常住居民III
  • 打卡总天数:114
  • 最近打卡:2026-07-02 14:01:19
已绑定手机

6

主题

28

回帖

548

积分

高级会员

积分
548
发表于 2026-6-19 21:38:42 | 显示全部楼层 |阅读模式
第一次使用SPI,第一次使用MT6816,配置硬件SPI模式3,用于读取MT6816的角度数据,返回的数据总是0,不知道是什么原因,麻烦有用过的高手指点一下,谢谢!代码如下:
一、GPIO配置


        SPI_Pin_Cfg.Mode = GPIO_OUT_PP; // 定义GPIO的类型为推挽输出
        SPI_Pin_Cfg.Pin = GPIO_Pin_3 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; // 配置端口I/O引脚
        GPIO_Inilize_Ret  = GPIO_Inilize(GPIO_P1, &SPI_Pin_Cfg); // 执行GPIO配置
        SPI_Pin_Cfg.Mode = GPIO_HighZ; // 定义GPIO的类型为推挽输出
        SPI_Pin_Cfg.Pin         = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4;         // 配置端口I/O引脚
        GPIO_Inilize_Ret  = GPIO_Inilize(GPIO_P1, &SPI_Pin_Cfg); // 执行GPIO配置
        
        P1 = 0xFF; // 初始化GPIO状态

二、SPI配置

void SPI_InitialConfig(void)
{
        SPI_InitTypeDef                        SPI_InitStructure; // 定义结构体变量
        SPI_InitStructure.SPI_Enable    = ENABLE;  // SPI启动,SPEN=1 使能SPI
        SPI_InitStructure.SPI_SSIG      = ENABLE;    // SSIG=1 忽略硬件NSS:SSIG=1 就是用来禁用硬件 SS 引脚、软件自定义片选
        SPI_InitStructure.SPI_FirstBit  = SPI_MSB;   // 数据移位方向 SPI_MSB, SPI_LSB,DORD=0 高位在前
        SPI_InitStructure.SPI_Mode      = SPI_Mode_Master;  // 主从选择   SPI_Mode_Master, SPI_Mode_Slave
        SPI_InitStructure.SPI_CPOL      = SPI_CPOL_High; // 时钟相位   SPI_CPOL_High,   SPI_CPOL_Low 模式3
        SPI_InitStructure.SPI_CPHA      = SPI_CPHA_2Edge; // 数据边沿   SPI_CPHA_1Edge,  SPI_CPHA_2Edge
        SPI_InitStructure.SPI_Speed     = SPI_Speed_8;  // SPI速度    SPI_Speed_4, SPI_Speed_16, SPI_Speed_64, SPI_Speed_128
        SPI_Init(&SPI_InitStructure); // 执行SPI 初始化参数配置
        SPI_SW(SPI_P54_P13_P14_P15);        // SPI引脚映射:MOSI(P1.3)/MISO(P1.4)/SCK(P1.5)
        SPI_MT6816_CSN = 1; // MT6816片选默认拉高/CSN_1(P1.6)
        SPI_ClearFlag();                /* 写 1 清除 SPIF和WCOL 标志 */
}


三、读取MT6816数据代码


u8 MT6816_Read_Reg(u8 RegisterAddr)
{
        u8 ReadCommand = 0x00;        // 定义局部变量
        u8 ReceiveData = 0x00;// 定义局部变量
        
        bit EnableAllINT_Flag;        // 备份原始中断状态
        ReadCommand = RegisterAddr | 0x80;// D7位置位表示为读模式,D6-D0为目标寄存器地址
        EnableAllINT_Flag = EA;// 保存当前总中断状态,避免强行改写
        EA = 0;// 关闭总中断,防止SPI时序出错
        SPI_MT6816_CSN = 0;// 片选低电平,启动MT6816的SPI接口
        NOP6();// 电平稳定延迟,4个NOP,≈166.7ns,满足电平建立时间(24MHz)
        SPI_RW_Byte(ReadCommand);        // 发送读指令和目标寄存器地址,前8位:指令+地址
        ReceiveData = SPI_RW_Byte(0xFF);// 后8位:发哑字节出时钟,同时读数据
        NOP6();// 电平稳定延迟
        SPI_MT6816_CSN = 1;// 片选高电平,关闭MT6816的SPI接口
        NOP6();// 电平稳定延迟
        printf("MT6816寄存器数据:%d \n\r",ReceiveData);// 【测试】
         P1 = 0xFF;// 恢复P1口初始状态【是否需要?】
        EA = EnableAllINT_Flag;// 恢复中断        
        return ReceiveData;
}



u8 SPI_RW_Byte(u8 TxDat)
{
        SPDAT = TxDat;
        while( !(SPSTAT & 0x80) );         // 查询等待传输完成,SPI传输速度快,不需要用中断方式
        SPI_ClearFlag();        // 写 1 清除 SPIF和WCOL 标志
        return SPDAT;   // 返回接收数据
}


四、测试说明
1、从单片机发送0x84命令,再发送0xff以读取MT6816的0x04寄存器的数据,在没有磁铁的情况下,不应返回0,至少应返回0x02;
2、使用USB转SPI转换器,从电脑工具的窗口中可以看到单片机发出的数据是正确的,单片机也能接收到USP转SPI转换器工具软件返回的数据(默认返回0x12)。

MT6816时序图

MT6816时序图

数据收发截图

数据收发截图
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:920
  • 最近打卡:2026-07-05 05:06:57

24

主题

551

回帖

2399

积分

荣誉版主

积分
2399
发表于 2026-6-20 05:45:36 | 显示全部楼层
我用软件模拟SPI,读MT6825,效果良好。
//SPI先接收高位,形参为接收的bit数,1---8bit
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 ++;                //用于8位机
                }
        }
        return dat;
}

//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();
        }
}



u16 read_6825_angle(void)
{
        u8 l_data;
        u8 h_data;
       
        u8 low_data;
       
        SPI_CS = 0;        //启动SPI
       
        SPI_SEND_U8_DATA(0x83);
       
        h_data = read_angle_8(8);
        l_data = read_angle_8(8);
        low_data = read_angle_8(2);
       
        SPI_CS = 1;
       
        l_data = (l_data & 0xfc) | low_data;
        return (((u16)h_data << 8) | l_data) ;
}
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:114
  • 最近打卡:2026-07-02 14:01:19
已绑定手机

6

主题

28

回帖

548

积分

高级会员

积分
548
发表于 2026-6-20 10:26:49 | 显示全部楼层
社区*** 发表于 2026-6-20 05:45
我用软件模拟SPI,读MT6825,效果良好。
//SPI先接收高位,形参为接收的bit数,1---8bit
u8 read_angle_8(u8 ...

谢谢回复!我参照你的代码试试!
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:114
  • 最近打卡:2026-07-02 14:01:19
已绑定手机

6

主题

28

回帖

548

积分

高级会员

积分
548
发表于 2026-6-20 21:37:10 | 显示全部楼层
社区*** 发表于 2026-6-20 05:45
我用软件模拟SPI,读MT6825,效果良好。
//SPI先接收高位,形参为接收的bit数,1---8bit
u8 read_angle_8(u8 ...

用软件SPI才能读取数据,硬件SPI怎么弄都不行!现在还不确定数据是否正确,但起码在没有磁铁时,弱磁标识有效了,把磁铁靠上后,弱磁标识无效,证明读取过程应该是正确的!
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:1
  • 最近打卡:2026-06-27 19:06:37
已绑定手机

0

主题

1

回帖

4

积分

新手上路

积分
4
发表于 2026-6-27 19:06:37 | 显示全部楼层
项目做的怎么样了,做好了我付费购买,我要用Ai8051U读取两路 MT6816 值,然后通过段数码管显示出来。
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:114
  • 最近打卡:2026-07-02 14:01:19
已绑定手机

6

主题

28

回帖

548

积分

高级会员

积分
548
发表于 6 天前 | 显示全部楼层
gsyf*** 发表于 2026-6-27 19:06
项目做的怎么样了,做好了我付费购买,我要用Ai8051U读取两路 MT6816 值,然后通过段数码管显示出来。 ...

软SPI可以读出数据,然后计算度数,能读一路就能读多路,现在用32G串口输出角度,要段码显示需要做一个7段码查表后显示即可。

角度

角度
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:920
  • 最近打卡:2026-07-05 05:06:57

24

主题

551

回帖

2399

积分

荣誉版主

积分
2399
发表于 5 天前 | 显示全部楼层
用软件模拟SPI,更灵活,也便于移植。
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2026-7-5 07:49 , Processed in 0.077826 second(s), 78 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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