DRV8301 SPI调试问题(接收一直为0x0000)

1.VDD_SPI要上电

2.EN_GATE引脚要拉高电平,低电平SPI通信不开启

3.PVDD要在正常工作范围6—60v内,否则触发欠压保护和过压保护都将不响应spi命令

4. DRV8301 SPI的采样是下降沿采样,且空闲状态要为低电平,也就是要在第二沿设置采样

即设置CPOL为0,CPHA为1,与DRV8301相匹配才能正常通信

首先是基础定义

//DRV8301 SPI配置变量定义
uint16_t DEVICE_Faults_READ = 0x8000; //获取设备出错SPI需要发送的16位数据
uint16_t DEVICE_ID_READ = 0x8800;//获取设备ID需要发送的16位数据
uint16_t GATEDRIVE_Control_READ = 0x9000;//读取门级驱动数据要发送的16位数据
uint16_t CSAM_Control_READ = 0x9800; //读取电流增益器数据要发送的16位数据
uint8_t Faults_Data[2];//SPI读取Faults寄存器的值
uint8_t ID_Data[2];//SPI读取ID寄存器的值
uint8_t Gate_Data_R[2];//SPI读取Gata寄存器的值
uint16_t Gate_Data_W;//SPI最终要写入Gata寄存器的值
uint8_t CSAM_Data_R[2];//SPI读取CSAM寄存器的值
uint16_t CSAM_Data_W;//SPI最终要写入CSAM寄存器的值
uint8_t test_Gate[2];
uint8_t test_GSAM[2];//测试值反馈

相关SPI收发配置函数

//测试SPI函数
uint8_t SPI1_ReadWriteByte(uint8_t TxData)//发送一个字节,并从寄存器返回一个值
{
	uint8_t Rxdata;
	HAL_SPI_TransmitReceive(&hspi1,&TxData,&Rxdata,1,1000);
	return Rxdata;
}

//SPI读16位函数
void SPI_Read(uint8_t* pBuffer,uint16_t ReadAddr)
{
	uint16_t i;
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
	SPI1_ReadWriteByte((uint8_t)(ReadAddr >> 8));//右移8位,强制转换保留低八位数据,也就是发送了高8位数据对应的地址给halspi发送
	SPI1_ReadWriteByte((uint8_t)ReadAddr);//强制转换保留低8位数据,也就是发送了低8位数据对应的地址给halspi发送
	for(i = 0;i<2;i++)
	{
		pBuffer[i]=SPI1_ReadWriteByte(0xFF);//根据SPI通讯原理,要读出下一个周期spi发出的数据,要发送对应格式位的数据
	}
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
}

//SPI写16位函数
void SPI_Write(uint16_t WriteAddr)
{
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
	SPI1_ReadWriteByte((uint8_t)(WriteAddr >> 8));
	SPI1_ReadWriteByte((uint8_t)WriteAddr);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
}

最后按照我的需求配置控制寄存器

//SPI参数配置函数
void DRV8301_SPI_setting()
{
	//配置Gate寄存器
	SPI_Read(Gate_Data_R, GATEDRIVE_Control_READ);//发送读取门级寄存器命令,并将读取的值赋予Gate_Data_R
	Gate_Data_W = ((uint16_t)Gate_Data_R[0] << 8 | (uint16_t)Gate_Data_R[1]);//将8位数组转换位16位数据
	Gate_Data_W &=~(1<<0);
	Gate_Data_W &=~(1<<1);//配置D0位与D1为0,使栅极驱动电流峰值为1.7A>大于计算所得1.2A
	Gate_Data_W &=~(1<<2);//配置Gate_reset的模式为NORMAL MODE
	Gate_Data_W &=~(1<<3);//配置为6PWM模式
	Gate_Data_W &=~(1<<4);
	Gate_Data_W |=(1<<5);//配置D4为0、D5为1,过流时不通过DRV8301限制电流只触发NOTCW信号
	Gate_Data_W |=(1<<6);
	Gate_Data_W &=~(1<<7);
	Gate_Data_W |=(1<<8);
	Gate_Data_W &=~(1<<9);
	Gate_Data_W |=(1<<10);//配置D6~D10位为10101即21号电压值0.730v对应电流56A
	Gate_Data_W &=~(1<<11);
	Gate_Data_W |=(1<<12);
	Gate_Data_W &=~(1<<13);
	Gate_Data_W &=~(1<<14);//配置地址位位0x0010对应Gate寄存器
	Gate_Data_W &=~(1<<15);//15位置0表示写入
	SPI_Write(Gate_Data_W);//发送带有写入信号的数据进行配置
	SPI_Read(test_Gate, GATEDRIVE_Control_READ);//将写好的值读取一遍
	//配置CSAM寄存器
	SPI_Read(CSAM_Data_R, CSAM_Control_READ);//发送读取CSAM寄存器命令,并将读取的值赋予CSAM_Data_R
	CSAM_Data_W = ((uint16_t)CSAM_Data_R[0] << 8 | (uint16_t)CSAM_Data_R[1]);//将8位数组转换位16位数据
	CSAM_Data_W &=~(1<<0);//存储RAW值
	CSAM_Data_W &=~(1<<1);//配置D0位与D1位为0,同时汇报过流与过温警报
	CSAM_Data_W |= (1<<2);
	CSAM_Data_W |= (1<<3);//配置D2与D3位为1,增益为80倍,所用电机电流最高预估225mA放大后波动+_0.36V
	CSAM_Data_W &=~(1<<4);//不启用第一个分流放大器的矫正功能
	CSAM_Data_W &=~(1<<5);//不启用第二个分流放大器的矫正功能
	CSAM_Data_W &=~(1<<6);//限流模式下的反应,因为没有配置限流模式,所以用不到
	CSAM_Data_W |=(1<<11);
	CSAM_Data_W |=(1<<12);
	CSAM_Data_W &=~(1<<13);
	CSAM_Data_W &=~(1<<14);//配置地址位位0x0011对应CSAM寄存器,7—10位为reserved无法进行读写
	CSAM_Data_W &=~(1<<15);//15位置0表示写入
	SPI_Write(CSAM_Data_W);//发送带有写入信号的数据进行配置
	SPI_Read(test_GSAM, GATEDRIVE_Control_READ);//将写好的值读取一遍
}

具体还没有测试,因为板子暂时没打算接上PVDD,需要检查会不会烧掉之类的(毕竟第一次设计PCB,还是这种大电流的,很慌)

  • 2
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 20
    评论
好的,关于使用STM32普通IO口模拟SPI对DRV8353S的0x02地址写入0x1234并读取的流程,可以参考以下步骤: 1. 配置GPIO口 首先需要配置三个GPIO口作为SPI的时钟、数据输入和数据输出,可以使用STM32的GPIO库进行配置。 例如,以下代码配置PA5、PA6和PA7口分别作为SPI的时钟、数据输入和数据输出口: ``` GPIO_InitTypeDef GPIO_InitStruct = {0}; // 时钟口配置 GPIO_InitStruct.Pin = GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 数据输入口配置 GPIO_InitStruct.Pin = GPIO_PIN_6; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 数据输出口配置 GPIO_InitStruct.Pin = GPIO_PIN_7; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); ``` 2. 实现SPI模拟函数 在配置好GPIO口后,需要实现SPI的模拟函数,包括发送数据和接收数据。 例如,以下代码实现了一个简单的SPI模拟函数,每次发送一位数据并接收一位数据: ``` void spi_write_read(uint8_t *tx_data, uint8_t *rx_data) { uint8_t tx_bit, rx_bit; for (int i = 0; i < 8; i++) { tx_bit = (tx_data[0] >> (7 - i)) & 0x01; HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, tx_bit); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); rx_bit = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6); rx_data[0] |= (rx_bit << (7 - i)); } } ``` 3. 写入数据到0x02地址 在实现好SPI模拟函数后,可以使用该函数向0x02地址写入数据0x1234。需要按照DRV8353S的通讯协议,先发送地址0x02,再发送数据0x12和0x34。 例如,以下代码向0x02地址写入数据0x1234: ``` uint8_t tx_data[3] = {0x02, 0x12, 0x34}; uint8_t rx_data[3] = {0}; HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); spi_write_read(tx_data, rx_data); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); ``` 4. 读取0x02地址的数据 在向0x02地址写入数据后,可以继续使用SPI模拟函数读取该地址的数据,以验证写入是否成功。需要先发送地址0x02,再接收两个字节的数据。 例如,以下代码从0x02地址读取数据并打印: ``` tx_data[0] = 0x02; rx_data[0] = 0; rx_data[1] = 0; HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); spi_write_read(tx_data, rx_data); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); uint16_t read_data = (rx_data[1] << 8) | rx_data[2]; printf("Read data from 0x02: 0x%04x\n", read_data); ``` 完整的代码示例可以参考以下链接:https://github.com/yuchengstudio/STM32-SPI-GPIO-Simulation-Demo
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值