- 打卡等级:常住居民III
- 打卡总天数:114
- 最近打卡:2026-07-02 14:01:19
已绑定手机
高级会员
- 积分
- 548
|
第一次使用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时序图
-
数据收发截图
|