[资料干货] 八通道低侧驱动芯片SGM42406的使用分享
本文介绍了SGM42406低侧驱动芯片的功能特点及应用。该芯片包含8个相同驱动器,支持串行保护功能和感性负载消磁,可驱动多种负载类型。文章详细解析了芯片手册信息,包括引脚功能、通信时序(类似SPI)、菊花链连接方式以及故障检测机制。同时提供了基于C语言的驱动代码实现,包含初始化、数据读写等核心功能接口。通过宏定义可适配SGM42406A/B不同型号,代码结构清晰,包含头文件和源文件实现,为开发者使
·
SGM42406由8个相同的低侧驱动器组成,具备串行保护功能;并且集成了用于感性负载消磁的二极管,且可驱动不同类型的负载,例如有刷电机、继电器、发光二极管、单极步进电机等。
我们使用的是16引脚的SGM42406B,使用4线串行接口进行通信,如下图所示:


接下来我就先分享一下自己解读SGM42406芯片手册的获取到的一些主要信息,然后展示一下基于C语言的芯片驱动代码。
SGM42406属于低侧驱动芯片,所谓的低侧驱动,即指驱动芯片被放置在负载和地(GND)之间,而负载的另一端直接连接到电源正极,并通过控制芯片对地的通断,来控制负载的电源回路,该芯片的功能框图如下所示:

主要的引脚及功能描述和标注如下图所示:

对于芯片的使能引脚ENABLE这里需要注意一点:
对应SGM42406A型号,控制ENABLE为高电平,即为使能芯片工作;
对应SGM42406B型号,控制nENABLE为低电平,即为使能芯片工作。
SGM42406与MCU之间通过4线串行通信,通信时序可以参考SPI总线实现,可以用硬件SPI,也可以用软件SPI实现功能,即LATCH引脚对应CS信号,CLK对应CLOCK信号,DIN对应MOSI信号,DOUT对应MISO信号,通信时序如下图所示:

通过MCU将数据写入单个芯片的数据寄存器的时序如下图所示:

当然,很重要的一个信息就是芯片支持菊花链(Daisy-Chain)操作,其实菊花链连接在很多芯片上都有,不仅方便数据拓展,同时也节约MCU引脚资源。下面是该芯片的菊花链应用:

即级联的各个芯片共用LATCH,CLK,前一级芯片的DOUT引脚连接到下一级芯片的DIN引脚。
另外,芯片支持故障检测及状态输出,即当芯片出现过温、过流和短路现象时,会通过FAULT引脚输出低电平信号,MCU可以检测FAULT引脚的数据。然后如果想知道具体是哪个OUT输出造成的过流或者短路,可以通过回读故障寄存器的值来识别。
该芯片的主要寄存器主要包括三个,即:
数据寄存器:Data Register
芯片根据数据寄存器控制输出的开和关:

故障寄存器:Fault Register
用于记录芯片的过流和过载故障信息:

控制寄存器:Control Register
芯片通过设置控制寄存器来配置通电时间和输出PWM占空比,驱动电机时会用到:

然后我再分享一下SGM42406的基于C语言的驱动代码,主要包括两个文件,一个是SGM42406.c源文件,一个是SGM42406.h头文件,其中延时时间这块需要根据不同MCU平台及硬件参数自行调整,确保时序波形不失真的情况下可以满足速度要求。
其中头文件的主要代码如下所示,主要包括硬件GPIO配置(不同MCU可以自行修改),回调函数定义及对外函数接口声明等,另外可以通过使能和不使能SGM42406_B宏来配置为SGM42406A还是SGM42406B的驱动代码:
复制
#ifndef __SGM42406_H__#define __SGM42406_H__#include "at32f403a_407.h"#include <string.h>#define SGM42406_EN_GPIO GPIOB#define SGM42406_CLK_GPIO GPIOB#define SGM42406_LATCH_GPIO GPIOA#define SGM42406_DIN_GPIO GPIOB#define SGM42406_FAULT_GPIO GPIOA#define SGM42406_DOUT_GPIO GPIOB#define SGM42406_EN_PIN GPIO_PINS_2#define SGM42406_CLK_PIN GPIO_PINS_7#define SGM42406_LATCH_GPIN GPIO_PINS_4 // NSS pin#define SGM42406_DIN_PIN GPIO_PINS_9#define SGM42406_FAULT_PIN GPIO_PINS_8#define SGM42406_DOUT_PIN GPIO_PINS_8#define SGM42406_CLK_HIGH() gpio_bits_write(SGM42406_CLK_GPIO, SGM42406_CLK_PIN, TRUE)#define SGM42406_CLK_LOW() gpio_bits_write(SGM42406_CLK_GPIO, SGM42406_CLK_PIN, FALSE)#define SGM42406_LATCH_HIGH() gpio_bits_write(SGM42406_LATCH_GPIO, SGM42406_LATCH_GPIN, TRUE)#define SGM42406_LATCH_LOW() gpio_bits_write(SGM42406_LATCH_GPIO, SGM42406_LATCH_GPIN, FALSE)#define SGM42406_EN_HIGH() gpio_bits_write(SGM42406_EN_GPIO, SGM42406_EN_PIN, TRUE)#define SGM42406_EN_LOW() gpio_bits_write(SGM42406_EN_GPIO, SGM42406_EN_PIN, FALSE)#define SGM42406_DIN_HIGH() gpio_bits_write(SGM42406_DIN_GPIO, SGM42406_DIN_PIN, TRUE)#define SGM42406_DIN_LOW() gpio_bits_write(SGM42406_DIN_GPIO, SGM42406_DIN_PIN, FALSE)#define SGM42406_READ_DOUT() gpio_input_data_bit_read(SGM42406_DOUT_GPIO,SGM42406_DOUT_PIN)#define SGM42406_READ_FAULT() gpio_input_data_bit_read(SGM42406_FAULT_GPIO,SGM42406_FAULT_PIN)#define SGM42406_DELAY_TIME 0 //4#define SGM42406_Btypedef enum {SGM42406_L = 0,SGM42406_H,}sgm42406_pin_sta_e;typedef enum {SGM42406_READ_CONTORL_REG = 0,SGM42406_READ_DATA_REG,}sgm42406_read_reg_e;typedef struct {void (* set_LATCH_pin_sta)(u8 status);void (* set_CLK_pin_sta)(u8 status);void (* set_DIN_pin_sta)(u8 status);#ifdef SGM42406_Avoid (* set_ENABLE_pin_sta)(u8 status);#elif defined(SGM42406_B)void (* set_NENABLE_pin_sta)(u8 status);#endifu8 (* get_DOUT_pin_sta) (void);u8 (* get_NFAULT_pin_sta) (void);void (* sgm42406_delay_us) (u32 us);}sgm42406_driver, *sgm42406_driver_t;void sgm42406_init(void);void sgm42406_command_clk(u8 clk_times);s8 sgm42406_write_data(u8 *write_buff, u32 len);void sgm42406_read_fault_reg(u16 *read_buff, u8 chip_sum);void sgm42406_write_control_reg(u8 *write_buff, u32 len);void sgm42406_read_control_or_data_reg(sgm42406_read_reg_e reg, u8 *read_buff, u32 len);void sgm42406_fault_reg_reset(void);void set_clk_sta(u8 sta);void set_din_sta(u8 sta);void set_latch_sta(u8 sta);extern u8 get_nfault_sta(void);sgm42406_driver_t get_sgm42406_dev_handle(void);#endif /* __SGM42406_H__ */
其中源文件的主要代码如下所示,主要包括芯片初始化接口、回调函数实现接口、写数据接口和读故障寄存器数据接口等:
复制
#include "sgm42406.h"sgm42406_driver sgm42406_dev0;void set_clk_sta(u8 sta){switch(sta){case 1:SGM42406_CLK_HIGH();break;case 0:SGM42406_CLK_LOW();break;}}void set_din_sta(u8 sta){switch(sta){case 1:SGM42406_DIN_HIGH();break;case 0:SGM42406_DIN_LOW();break;}}void set_latch_sta(u8 sta){switch(sta){case 1:SGM42406_LATCH_HIGH();break;case 0:SGM42406_LATCH_LOW();break;}}void set_enable_sta(u8 sta){switch(sta){case 1:SGM42406_EN_HIGH();break;case 0:SGM42406_EN_LOW();break;}}u8 get_dout_sta(void){return SGM42406_READ_DOUT();}u8 get_nfault_sta(void){return SGM42406_READ_FAULT();}void sgm42406_delay(u32 us){u32 j = 0;//while(us--){for(j = 0; j < us; j++){__asm("nop");}}}/*** [url=/u/brief]@brief[/url] 娉ㄥ唽sgm42406璁惧**/static void sgm42406_register(void){sgm42406_dev0.set_CLK_pin_sta = set_clk_sta;sgm42406_dev0.set_DIN_pin_sta = set_din_sta;sgm42406_dev0.set_LATCH_pin_sta = set_latch_sta;#ifdef SGM42406_Asgm42406_dev0.set_ENABLE_pin_sta = set_pin_sta;#elif defined(SGM42406_B)sgm42406_dev0.set_NENABLE_pin_sta = set_enable_sta;#endifsgm42406_dev0.get_DOUT_pin_sta = get_dout_sta;sgm42406_dev0.get_NFAULT_pin_sta = get_nfault_sta;sgm42406_dev0.sgm42406_delay_us = sgm42406_delay;}/*** @brief Get the sgm42406 dev handle object** [url=/u/return]@return[/url] sgm42406_driver_t*/sgm42406_driver_t get_sgm42406_dev_handle(void){return &sgm42406_dev0;}void sgm42406_init(void){sgm42406_driver_t pd;sgm42406_register();pd = get_sgm42406_dev_handle();pd->set_NENABLE_pin_sta(SGM42406_L);pd->set_LATCH_pin_sta(SGM42406_H);pd->set_CLK_pin_sta(SGM42406_H);pd->set_DIN_pin_sta(SGM42406_L);}void sgm42406_command_clk(u8 clk_times){sgm42406_driver_t pd;int i = 0;pd = get_sgm42406_dev_handle();pd->set_LATCH_pin_sta(SGM42406_L);pd->set_CLK_pin_sta(SGM42406_L);pd->sgm42406_delay_us(1);for(i = 0; i < clk_times; i++){pd->set_CLK_pin_sta(SGM42406_H);pd->sgm42406_delay_us(SGM42406_DELAY_TIME);pd->set_CLK_pin_sta(SGM42406_L);pd->sgm42406_delay_us(SGM42406_DELAY_TIME);}pd->set_LATCH_pin_sta(SGM42406_H);pd->sgm42406_delay_us(SGM42406_DELAY_TIME);}/*** @brief 杈撳嚭闀垮害涓簂en鐨勬暟鎹?** @param buff 瑕佽緭鍑烘暟鎹殑鍦板潃* @param len 杈撳嚭鐨勫瓧鑺傛暟* @return int8_t 鎴愬姛0锛屽け璐?1*/s8 sgm42406_write_data(u8 *write_buff, u32 len){sgm42406_driver_t pd;u8 send_data = 0;int i = 0;int j = 0;pd = get_sgm42406_dev_handle();pd->set_LATCH_pin_sta(SGM42406_L);for(i = len; i > 0; i--) //SGM42406鑺墖涓暟{send_data = write_buff[i-1]; //涓轰粈涔堣鍏堝啓鏈€鍚庝竴涓猙uff鏁版嵁锛?for(j = 0; j < 8; j++) //鍐?bit鏁版嵁{pd->set_CLK_pin_sta(SGM42406_L);if((send_data << j) & 0x80){pd->set_DIN_pin_sta(SGM42406_H);}else{pd->set_DIN_pin_sta(SGM42406_L);}pd->sgm42406_delay_us(SGM42406_DELAY_TIME);pd->set_CLK_pin_sta(SGM42406_H);pd->sgm42406_delay_us(SGM42406_DELAY_TIME);}pd->set_DIN_pin_sta(SGM42406_L);pd->sgm42406_delay_us(SGM42406_DELAY_TIME);pd->set_CLK_pin_sta(SGM42406_H);}pd->set_LATCH_pin_sta(SGM42406_H);return 0;}/*璇诲彇 16浣嶆晠闅滃瘎瀛樺櫒 锛岃鎺ュ彛闇€瑕佷慨鏀?/void sgm42406_read_fault_reg(u16 *read_buff, u8 chip_sum){sgm42406_driver_t pd;//u16 *pread = read_buff;u16 read_data = 0;int i = 0;int j = 0;pd = get_sgm42406_dev_handle();#if 0pd->sgm42406_delay_us(500);pd->set_LATCH_pin_sta(SGM42406_H);pd->set_CLK_pin_sta(SGM42406_H);pd->sgm42406_delay_us(2);pd->set_CLK_pin_sta(SGM42406_L);pd->set_LATCH_pin_sta(SGM42406_L);pd->sgm42406_delay_us(5);pd->set_LATCH_pin_sta(SGM42406_H);pd->sgm42406_delay_us(5);#elsepd->set_CLK_pin_sta(SGM42406_H);pd->set_LATCH_pin_sta(SGM42406_H);pd->sgm42406_delay_us(5);pd->set_CLK_pin_sta(SGM42406_L);pd->sgm42406_delay_us(5);pd->set_LATCH_pin_sta(SGM42406_L);pd->sgm42406_delay_us(5);pd->set_LATCH_pin_sta(SGM42406_H);pd->sgm42406_delay_us(5);pd->set_CLK_pin_sta(SGM42406_H);#endiffor(i = 0; i < chip_sum; i++){for(j = 0; j < 16; j++){pd->set_CLK_pin_sta(SGM42406_H);pd->sgm42406_delay_us(SGM42406_DELAY_TIME);pd->set_CLK_pin_sta(SGM42406_L);//pd->sgm42406_delay_us(2);read_data |= (pd->get_DOUT_pin_sta() << (15-j)); //鍏堣鏈€楂樹綅pd->sgm42406_delay_us(SGM42406_DELAY_TIME);}//memcpy(&pread[i], &read_data, 2);read_buff[i] = read_data;read_data = 0;}//pd->sgm42406_delay_us(500);}void sgm42406_write_control_reg(u8 *write_buff, u32 len){sgm42406_driver_t pd;pd = get_sgm42406_dev_handle();pd->set_LATCH_pin_sta(SGM42406_H);pd->set_CLK_pin_sta(SGM42406_H);pd->sgm42406_delay_us(2);pd->set_CLK_pin_sta(SGM42406_L);// pd->sgm42406_delay_us(2);sgm42406_command_clk(1);sgm42406_command_clk(2);sgm42406_command_clk(2);sgm42406_command_clk(3);sgm42406_write_data(write_buff, len);}void sgm42406_read_control_or_data_reg(sgm42406_read_reg_e reg, u8 *read_buff, u32 len){sgm42406_driver_t pd;u8 *pread = read_buff;u8 read_data = 0;int i = 0;int j = 0;pd = get_sgm42406_dev_handle();pd->set_CLK_pin_sta(SGM42406_L);switch(reg){case SGM42406_READ_CONTORL_REG:sgm42406_command_clk(1);sgm42406_command_clk(4);sgm42406_command_clk(2);sgm42406_command_clk(3);break;case SGM42406_READ_DATA_REG:sgm42406_command_clk(1);sgm42406_command_clk(4);sgm42406_command_clk(4);sgm42406_command_clk(3);break;}for(i = 0; i < len; i++){for(j = 0; j < 8; j++){read_data |= (pd->get_DOUT_pin_sta() << j);pd->sgm42406_delay_us(2);pd->set_CLK_pin_sta(SGM42406_H);pd->sgm42406_delay_us(2);pd->set_CLK_pin_sta(SGM42406_L);pd->sgm42406_delay_us(1);}memcpy(&pread[i], &read_data, 1);read_data = 0;}}void sgm42406_fault_reg_reset(void){sgm42406_driver_t pd;pd = get_sgm42406_dev_handle();pd->set_LATCH_pin_sta(SGM42406_H);pd->set_CLK_pin_sta(SGM42406_H);pd->sgm42406_delay_us(SGM42406_DELAY_TIME);pd->set_CLK_pin_sta(SGM42406_L);pd->sgm42406_delay_us(SGM42406_DELAY_TIME);sgm42406_command_clk(1);sgm42406_command_clk(2);sgm42406_command_clk(4);sgm42406_command_clk(3);pd->set_CLK_pin_sta(SGM42406_H);}
以上的对SGM42406的解读分享,给大家提供参考。










。
---------------------
作者:dffzh
链接:https://bbs.21ic.com/icview-3495603-1-1.html?_dsign=4ba244d0
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。
更多推荐



所有评论(0)