1、原理图

2、CUBEMAX配置

SPI通讯速率不能过快,可能会导致芯片通信失败

3、代码部分

MS31860T.h

#ifndef MS31860T_H
#define MS31860T_H

#include "stm32f1xx_hal.h"

// 菊花链芯片数量
#define NUM_CHIPS 2

// 外部变量声明
extern uint8_t ch1; // 存储芯片1通道状态
extern uint8_t ch2; // 存储芯片2通道状态

// 引脚控制宏
#define MS31860T_LATCH_LOW()     HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET)
#define MS31860T_LATCH_HIGH()    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET)
#define MS31860T_ENABLE1_HIGH()  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET)
#define MS31860T_ENABLE1_LOW()   HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET)
#define MS31860T_ENABLE2_HIGH()  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET)
#define MS31860T_ENABLE2_LOW()   HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET)

// 函数声明
HAL_StatusTypeDef MS31860T_Init(void);
HAL_StatusTypeDef MS31860T_SetChannels(uint8_t chip1_mask, uint8_t chip2_mask);
void MS31860T_data(void);

#endif // MS31860T_H

MS31860T.c

#include "ms31860t.h"

// 全局变量
uint8_t ch1 = 0x00; // 存储芯片1通道状态
uint8_t ch2 = 0x00; // 存储芯片2通道状态  

/**
 * @brief  初始化两个MS31860T芯片
 * @retval 操作结果
 */
HAL_StatusTypeDef MS31860T_Init(void)
{
    // 使能两个芯片输出
    MS31860T_ENABLE1_HIGH();
    MS31860T_ENABLE2_HIGH();
    HAL_Delay(100);  // 等待芯片稳定
    
    // 初始化所有通道关闭
    return MS31860T_SetChannels(0x00, 0x00);
}

/**
 * @brief  设置两个芯片的输出通道
 * @param  chip1_mask: 第一个芯片通道掩码(bit0=OUT1, bit7=OUT8)
 * @param  chip2_mask: 第二个芯片通道掩码(bit0=OUT1, bit7=OUT8)
 * @retval 操作结果
 */
HAL_StatusTypeDef MS31860T_SetChannels(uint8_t chip1_mask, uint8_t chip2_mask)
{
    uint8_t tx_data[NUM_CHIPS] = {chip2_mask, chip1_mask}; // 注意顺序:先发第二个芯片(链末)
    HAL_StatusTypeDef status;

    MS31860T_LATCH_LOW();
    status = HAL_SPI_Transmit(&hspi2, tx_data, NUM_CHIPS, 100);
    MS31860T_LATCH_HIGH();

    return status;
}

/**
 * @brief  处理串口接收数据并控制设备
 */
void MS31860T_data(void)
{
	U3RxCnt = 0;//计数清0

	if(U3RxBuf[3] == 0x09 && U3RxBuf[5] == 0x01)//打开逆变器
	{
		MS31860T_SetChannels(ch1 |= 0x00, ch2 |= 0x80); //芯片1的8个通道(顺序通道8-通道1):00000000,芯片2的8个通道:10000000
	}
	else if(U3RxBuf[3] == 0x09 && U3RxBuf[5] == 0x00)//关闭逆变器
	{
		MS31860T_SetChannels(ch1 &= ~0x00, ch2 &= ~0x80);
	}


	if(U3RxBuf[3] == 0x02 && U3RxBuf[5] == 0x01)//打开户外灯
	{
		MS31860T_SetChannels(ch1 |= 0x00, ch2 |= 0x01); //00000000,00000001
	}
	else if(U3RxBuf[3] == 0x02 && U3RxBuf[5] == 0x00)//关闭户外灯
	{
		MS31860T_SetChannels(ch1 &= ~0x00, ch2 &= ~0x01);
	}


	if(U3RxBuf[3] == 0x08 && U3RxBuf[5] == 0x01)//打开水泵
	{
		MS31860T_SetChannels(ch1 |= 0x02, ch2 |= 0x00); //00000010,00000000
	}
	else if(U3RxBuf[3] == 0x08 && U3RxBuf[5] == 0x00)//关闭水泵
	{
		MS31860T_SetChannels(ch1 &= ~0x02, ch2 &= ~0x00);
	}

}

main.c

int main(void)
{
  /* USER CODE BEGIN 2 */

  //初始化两个MS31860T芯片
  MS31860T_Init();
  MS31860T_SetChannels(0x00, 0x00);

  HAL_Delay(100);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {

	  //处理485接收数据
	  Process_UART3_Data();
	  //485收到一帧完整的数据
	  if(UART3_Flag_Rx == 1)
	  {

		if(U3RxBuf[1] == 0x03)
		{
		  ADC_TX();
		}
		else if(U3RxBuf[1] == 0x06)
		{
		  MS31860T_data();
		}
		UART3_Flag_Rx = 0; // 清除标志位
	  }
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

更多推荐