无刷电机小车开发记录04——互补PWM驱动移植

前言


  上篇文章记录了为GD32的BSP添加了PWM信号输入捕获的驱动,并实现了对SC60228DC磁编码器数据的读取(PWM接口),最后还做了一点简单的测试。今天过来继续修轮子,适配一下PWM驱动。这里不得不提一下,造轮子或者修轮子可能是比较枯燥的,如果有也想搞一搞这个小车但懒得造轮子的小伙伴可以等我都弄完了直接用完适配好的程序,可能大多数同学都更喜欢玩上层实现具体功能的部分。不过对于我来说,在这之前还有很多轮子要修。


相关硬件电路


  介于上篇文章有小伙伴产生了一些疑问,所以后面的文章我尽量把相关的一些东西提前罗列一下,比如今天要调试的是驱动无刷电机的PWM信号。那下面就是其中一路电机的驱动电路原理图,无刷电机的三项引线分别由三个NCE6005AS的双N沟道MOS管驱动。其中G2拉高,G1拉低时,高侧MOS管导通,该项被接入VDD,相反则低测MOS导通,该项被接入GND。而Mos管由EG2134的三半桥栅极驱动器驱动,最初的介绍视频里面也提过,我这里用的是全国产化的方案,所以相对国外的一些集成IC来说,器件要零散一些,但主要功能一致。而栅极驱动器的驱动信号则是三路互补PWM,其中HINx和LINx为一组。

如下是EG2134的输入输出逻辑真值表:

想了解更多器件信息,可参阅其芯片手册:EG2134芯片手册

PWM驱动移植


源文件适配

  目前我用的这块GD32E503器件还没有适配PWM驱动,所以还是有两个选择,如果能找到一个类似的驱动移植就会简单一点,否则就要走第二条路,完全自己适配,就要麻烦很多。首先对于RTT的PWM驱动有现成的,只要打开“RT_USING_PWM”宏即可把“rt_drv_pwm.c”添加到工程里。

而对于BSP的底层驱动,我用的这块器件并没有适配,但好在RTT对于arm内核的GD32器件的适配度还是挺高的,可以在arm内核的BSP内找到相关驱动,那闲话少说,先拷贝过来再说。

  接下来的工作就是要看一下驱动是否匹配,把不匹配的地方适配一下就可以了。首先来说,RTT层的PWM功能还是比较完善的,已经支持了互补PWM模式的配置,也有配置死区的接口。但看了一下GD32的BSP层的驱动,只适配了普通的PWM功能,没有互补模式。所以着重的工作就是适配互补模式的PWM。首先看”drv_pwm.c”下的第一个结构体TIMER_PORT_CHANNEL_MAP_S,用来定义PWM用到的timer以及输出通道和输出引脚。原本的定义首先没有互补通道的IO配置,其次直接用GD32固件库的Port和pin定义的,所以配置只能固化到代码里。

1typedef struct
2{

3    rt_int8_t TimerIndex; // timer index:0~13
4    rt_uint32_t Port;     // gpio port:GPIOA/GPIOB/GPIOC/...
5    rt_uint32_t pin;      // gpio pin:GPIO_PIN_0~GPIO_PIN_15
6    rt_uint16_t channel;  // timer channel
7    char *name;
8} TIMER_PORT_CHANNEL_MAP_S;

这里我想实现更多的使用配置文件配置,而配置文件配置如果也采用uint32类型的Port的寄存器地址去定义是很不直观的。所以添加了互补通道的同时,也修改了一下定义方式,具体怎么用且往后看。

1typedef struct
2{

3    rt_int8_t TimerIndex; // timer index:0~13
4    char        *OP_Port;    //A,B,C,D...
5    rt_uint16_t OP_pin;     // GPIO_pin:0~15
6    char        *ON_Port;    //A,B,C,D...
7    rt_base_t ON_pin;      // GPIO_pin:0~15
8    rt_uint16_t channel;  // timer channel
9    char *name;
10} TIMER_PORT_CHANNEL_MAP_S;

再往下看就是原本驱动里面对PWM引脚等信息的固化配置,比如PWM配置的是Timer3的ch2,输出引脚是GPIOB_8:

1static struct gd32_pwm gd32_pwm_obj[] = {
2#ifdef RT_USING_PWM1
3    {.tim_handle = {3, GPIOB, GPIO_PIN_8, 2"pwm1"}},
4#endif
5#ifdef RT_USING_PWM2
6    {.tim_handle = {3, GPIOB, GPIO_PIN_8, 2"pwm2"}},
7#endif
8...
9...
10};

修改后的代码如下,其中所以配置都由宏定义实现,而具体的宏定义后面可以用Kconfig实现图形化配置:

1static struct gd32_pwm gd32_pwm_obj[] = {
2#ifdef RT_USING_PWM1
3    {.tim_handle = {RT_USING_PWM1_TIMER_INDEX, RT_USING_PWM1_OP_PORT, RT_USING_PWM1_OP_PIN, RT_USING_PWM1_ON_PORT, RT_USING_PWM1_ON_PIN, RT_USING_PWM1_CH, RT_USING_PWM1_NAME}},
4#endif
5#ifdef RT_USING_PWM2
6    {.tim_handle = {RT_USING_PWM2_TIMER_INDEX, RT_USING_PWM2_OP_PORT, RT_USING_PWM2_OP_PIN, RT_USING_PWM2_ON_PORT, RT_USING_PWM2_ON_PIN, RT_USING_PWM2_CH, RT_USING_PWM2_NAME}},
7#endif
8    ...
9    ...
10};

上面提到过为了配置的时候更直观,没有直接使用寄存器地址值,而是用的字符’A’,’B’等去代表GPIOA,GPIOB。对于PIN的定义也类似,所以这里需要添加一个配置参数到具体的Port和pin的转换接口:

1static rt_uint32_t get_gpio_periph_port(char pot)
2
{
3    rt_uint32_t Port=0;
4    switch(pot)
5    {
6    case 'A':
7        Port = GPIOA;
8        break;
9    case 'B':
10        Port = GPIOB;
11        break;
12    case 'C':
13        Port = GPIOC;
14        break;
15    case 'D':
16        Port = GPIOD;
17        break;
18    case 'E':
19        Port = GPIOE;
20        break;
21    case 'F':
22        Port = GPIOF;
23        break;
24    case 'G':
25        Port = GPIOG;
26        break;
27    default:
28        Port = 0;
29        break;
30    }
31    return Port;
32}
33static rt_uint32_t get_gpio_periph_pin(rt_uint16_t pn)
34
{
35    rt_uint32_t Pin=0;
36    if(pn < 16)
37    {
38        Pin = GPIO_PIN_0 << (pn);
39    }
40    else {
41        LOG_E("Unsport gpio pin!\n");
42    }
43    return Pin;
44}

有了上面的对应接口,原驱动里的一些配置代码跟随做一下调整即可。我下面只给出改动稍大的一些地方,比如对于gpio的初始化代码,要添加一路互补IO的初始化,如果不适用互补PWM,配置文件里面不进行配置即可,这里就会跳过互补IO的初始化:

1static void gpio_config(void)
2
{
3    rt_int16_t i;
4    rt_uint32_t port;
5    rt_uint32_t pin;
6    /* config the GPIO as analog mode */
7    for (i = 0; i < sizeof(gd32_pwm_obj) / sizeof(gd32_pwm_obj[0]); ++i)
8    {
9        port = get_gpio_periph_port(*(gd32_pwm_obj[i].tim_handle.OP_Port));
10        pin = get_gpio_periph_pin(gd32_pwm_obj[i].tim_handle.OP_pin);
11        if(port)
12            gpio_init(port, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, pin);
13        port = get_gpio_periph_port(*(gd32_pwm_obj[i].tim_handle.ON_Port));
14        pin = get_gpio_periph_pin(gd32_pwm_obj[i].tim_handle.ON_pin);
15        if(port)
16            gpio_init(port, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, pin);
17    }
18}

源文件方面最后一个要修改的地方就是enable接口,主要是看configuration内的complementary互补模式是否被开启,如果开启则同时使能互补通道即可。

1static rt_err_t drv_pwm_enable(TIMER_PORT_CHANNEL_MAP_S *pstTimerMap, struct rt_pwm_configuration *configuration,
2                               rt_bool_t enable)
3{
4    int channel;
5    if(configuration->channel == 0 || configuration->channel > 4)
6        return RT_ERROR;
7    channel = configuration->channel-1;
8    if (!enable)
9    {
10        timer_channel_output_state_config(index_to_timer(pstTimerMap->TimerIndex), channel,
11                                          TIMER_CCX_DISABLE);
12        if(configuration->complementary == RT_TRUE)
13        {
14            timer_channel_complementary_output_state_config(index_to_timer(pstTimerMap->TimerIndex), channel,
15                                              TIMER_CCXN_DISABLE);
16        }
17    }
18    else
19    {
20        timer_channel_output_state_config(index_to_timer(pstTimerMap->TimerIndex), channel,
21                                          TIMER_CCX_ENABLE);
22        if(configuration->complementary == RT_TRUE)
23        {
24            timer_channel_complementary_output_state_config(index_to_timer(pstTimerMap->TimerIndex), channel,
25                    TIMER_CCXN_ENABLE);
26        }
27    }
28    LOG_I("pwm[%d][%d] enable:%d!", pstTimerMap->TimerIndex, channel, enable);
29    return RT_EOK;
30}

构建管理文件适配

接下来修改对应的SConscript文件和Kconfig文件。先在”libraries\gd32_drivers\”下的SConscript文件内添加如下代码,即开启RT_USING_PWM宏后,就把上面移植过来的“drv_pwm.c”添加到工程内。

1# add pwm drivers.
2if GetDepend('RT_USING_PWM'):
3    src +
= ['drv_pwm.c']

最后在“board\”目录下的Kconfig文件内,添加如下代码。利用select语句联动了RT_USING_PWM定义,我这里开启了6路PWM的配置:

1menuconfig BSP_USING_PWM
2        bool "Enable PWM"
3        default n
4        select RT_USING_PWM
5        if BSP_USING_PWM
6            config RT_USING_PWM1
7                bool "Enable PWM1"
8                default n
9            if RT_USING_PWM1
10                config RT_USING_PWM1_NAME
11                    string "PWM DEV NAME"
12                    default PWM1
13                config RT_USING_PWM1_TIMER_INDEX
14                    int "Timer Index"
15                    default 0
16                config RT_USING_PWM1_OP_PORT
17                    string "PWM output_P Port (A,B,C...)"
18                    default A
19                config RT_USING_PWM1_OP_PIN
20                    int "PWM output_P pin (0~15)"
21                    default 0
22                config RT_USING_PWM1_ON_PORT
23                    string "PWM output_N Port (A,B,C...)"
24                    default A
25                config RT_USING_PWM1_ON_PIN
26                    int "PWM output_N pin (0~15)"
27                    default 0
28                config RT_USING_PWM1_CH
29                    int "PWM output channel"
30                    default 0
31            endif
32            config RT_USING_PWM2
33                bool "Enable PWM2"
34                default n
35            if RT_USING_PWM2
36                config RT_USING_PWM2_NAME
37                    string "PWM DEV NAME"
38                    default PWM2
39                config RT_USING_PWM2_TIMER_INDEX
40                    int "Timer Index"
41                    default 0
42                config RT_USING_PWM2_OP_PORT
43                    string "PWM output_P Port (A,B,C...)"
44                    default A
45                config RT_USING_PWM2_OP_PIN
46                    int "PWM output_P pin (0~15)"
47                    default 0
48                config RT_USING_PWM2_ON_PORT
49                    string "PWM output_N Port (A,B,C...)"
50                    default A
51                config RT_USING_PWM2_ON_PIN
52                    int "PWM output_N pin (0~15)"
53                    default 0
54                config RT_USING_PWM2_CH
55                    int "PWM output channel"
56                    default 0
57            endif
58            config RT_USING_PWM3
59                bool "Enable PWM3"
60                default n
61            if RT_USING_PWM3
62                config RT_USING_PWM3_NAME
63                    string "PWM DEV NAME"
64                    default PWM3
65                config RT_USING_PWM3_TIMER_INDEX
66                    int "Timer Index"
67                    default 0
68                config RT_USING_PWM3_OP_PORT
69                    string "PWM output_P Port (A,B,C...)"
70                    default A
71                config RT_USING_PWM3_OP_PIN
72                    int "PWM output_P pin (0~15)"
73                    default 0
74                config RT_USING_PWM3_ON_PORT
75                    string "PWM output_N Port (A,B,C...)"
76                    default A
77                config RT_USING_PWM3_ON_PIN
78                    int "PWM output_N pin (0~15)"
79                    default 0
80                config RT_USING_PWM3_CH
81                    int "PWM output channel"
82                    default 0
83            endif
84            config RT_USING_PWM4
85                bool "Enable PWM4"
86                default n
87            if RT_USING_PWM4
88                config RT_USING_PWM4_NAME
89                    string "PWM DEV NAME"
90                    default PWM4
91                config RT_USING_PWM4_TIMER_INDEX
92                    int "Timer Index"
93                    default 0
94                config RT_USING_PWM4_OP_PORT
95                    string "PWM output_P Port (A,B,C...)"
96                    default A
97                config RT_USING_PWM4_OP_PIN
98                    int "PWM output_P pin (0~15)"
99                    default 0
100                config RT_USING_PWM4_ON_PORT
101                    string "PWM output_N Port (A,B,C...)"
102                    default A
103                config RT_USING_PWM4_ON_PIN
104                    int "PWM output_N pin (0~15)"
105                    default 0
106                config RT_USING_PWM4_CH
107                    int "PWM output channel"
108                    default 0
109            endif
110            config RT_USING_PWM5
111                bool "Enable PWM5"
112                default n
113            if RT_USING_PWM5
114                config RT_USING_PWM5_NAME
115                    string "PWM DEV NAME"
116                    default PWM5
117                config RT_USING_PWM5_TIMER_INDEX
118                    int "Timer Index"
119                    default 0
120                config RT_USING_PWM5_OP_PORT
121                    string "PWM output_P Port (A,B,C...)"
122                    default A
123                config RT_USING_PWM5_OP_PIN
124                    int "PWM output_P pin (0~15)"
125                    default 0
126                config RT_USING_PWM5_ON_PORT
127                    string "PWM output_N Port (A,B,C...)"
128                    default A
129                config RT_USING_PWM5_ON_PIN
130                    int "PWM output_N pin (0~15)"
131                    default 0
132                config RT_USING_PWM5_CH
133                    int "PWM output channel"
134                    default 0
135            endif
136            config RT_USING_PWM6
137                bool "Enable PWM6"
138                default n
139            if RT_USING_PWM6
140                config RT_USING_PWM6_NAME
141                    string "PWM DEV NAME"
142                    default PWM6
143                config RT_USING_PWM6_TIMER_INDEX
144                    int "Timer Index"
145                    default 0
146                config RT_USING_PWM6_OP_PORT
147                    string "PWM output_P Port (A,B,C...)"
148                    default A
149                config RT_USING_PWM6_OP_PIN
150                    int "PWM output_P pin (0~15)"
151                    default 0
152                config RT_USING_PWM6_ON_PORT
153                    string "PWM output_N Port (A,B,C...)"
154                    default A
155                config RT_USING_PWM6_ON_PIN
156                    int "PWM output_N pin (0~15)"
157                    default 0
158                config RT_USING_PWM6_CH
159                    int "PWM output channel"
160                    default 0
161            endif
162        endif

到此,就可以利用menuconfig或者IDE的图形界面进行配置了:

实现效果


为了测试效果,我这里在main函数内对6路PWM进行了初始化:

1rt_device_t pwm1_LA=RT_NULL, pwm2_LB=RT_NULL, pwm3_LC=RT_NULL, pwm4_RA=RT_NULL, pwm5_RB=RT_NULL, pwm6_RC=RT_NULL;
2int main(void)
3
{
4    ...
5    ...
6    pwm1_LA = rt_device_find(RT_USING_PWM1_NAME);
7    if(pwm1_LA != RT_NULL)
8    {
9        struct rt_device_pwm *pwm_dev = (struct rt_device_pwm *)pwm1_LA;
10        rt_pwm_set(pwm_dev,RT_USING_PWM1_CH+1,10000,5000);
11        rt_pwm_enable(pwm_dev,-(RT_USING_PWM1_CH+1));
12        rt_kprintf("%s init OK!\n", pwm_dev->parent.parent.name);
13    }
14    pwm2_LB = rt_device_find(RT_USING_PWM2_NAME);
15    if(pwm2_LB != RT_NULL)
16    {
17        struct rt_device_pwm *pwm_dev = (struct rt_device_pwm *)pwm2_LB;
18        rt_pwm_set(pwm_dev,RT_USING_PWM2_CH+1,10000,1000);
19        rt_pwm_enable(pwm_dev,-(RT_USING_PWM2_CH+1));
20        rt_kprintf("%s init OK!\n", pwm_dev->parent.parent.name);
21    }
22    pwm3_LC = rt_device_find(RT_USING_PWM3_NAME);
23    if(pwm3_LC != RT_NULL)
24    {
25        struct rt_device_pwm *pwm_dev = (struct rt_device_pwm *)pwm3_LC;
26        rt_pwm_set(pwm_dev,RT_USING_PWM3_CH+1,10000,8000);
27        rt_pwm_enable(pwm_dev,-(RT_USING_PWM3_CH+1));
28        rt_kprintf("%s init OK!\n", pwm_dev->parent.parent.name);
29    }
30    pwm4_RA = rt_device_find(RT_USING_PWM4_NAME);
31    if(pwm4_RA != RT_NULL)
32    {
33        struct rt_device_pwm *pwm_dev = (struct rt_device_pwm *)pwm4_RA;
34        rt_pwm_set(pwm_dev,RT_USING_PWM4_CH+1,10000,5000);
35        rt_pwm_enable(pwm_dev,-(RT_USING_PWM4_CH+1));
36        rt_kprintf("%s init OK!\n", pwm_dev->parent.parent.name);
37    }
38    pwm5_RB = rt_device_find(RT_USING_PWM5_NAME);
39    if(pwm5_RB != RT_NULL)
40    {
41        struct rt_device_pwm *pwm_dev = (struct rt_device_pwm *)pwm5_RB;
42        rt_pwm_set(pwm_dev,RT_USING_PWM5_CH+1,10000,1000);
43        rt_pwm_enable(pwm_dev,-(RT_USING_PWM5_CH+1));
44        rt_kprintf("%s init OK!\n", pwm_dev->parent.parent.name);
45    }
46    pwm6_RC = rt_device_find(RT_USING_PWM6_NAME);
47    if(pwm6_RC != RT_NULL)
48    {
49        struct rt_device_pwm *pwm_dev = (struct rt_device_pwm *)pwm6_RC;
50        rt_pwm_set(pwm_dev,RT_USING_PWM6_CH+1,10000,8000);
51        rt_pwm_enable(pwm_dev,-(RT_USING_PWM6_CH+1));
52        rt_kprintf("%s init OK!\n", pwm_dev->parent.parent.name);
53    }
54    ...
55    ...
56}

还实现了一个如下的测试命令,这样除了可以使用驱动里实现的PWM命令外,也可以使用自己的测试命令测试,更方便一些:

1static int motorLA_pwm(int argc, char **argv)
2
{
3    rt_err_t result = RT_EOK;
4    rt_uint32_t period, pulse;
5    struct rt_device_pwm *pwm_dev = (struct rt_device_pwm *)pwm1_LA;
6    if(argc >= 3)
7    {
8        period = atoi(argv[1]);
9        pulse = atoi(argv[2]);
10        rt_pwm_set(pwm_dev,RT_USING_PWM1_CH+1,period,pulse);
11        rt_kprintf("set %s:[period]%d-[pulse]%d!\n",pwm_dev->parent.parent.name, period, pulse);
12    }
13    else {
14        rt_kprintf("Usage: \n");
15        rt_kprintf("motorXN_pwm   - set the pwm's period and pulse\n");
16        rt_kprintf("eg:motorLA_pwm 10000 5000 is set motorLA pwm's period to 10us, pulse to 5us\n");
17        result = -RT_ERROR;
18    }
19    return RT_EOK;
20}
21MSH_CMD_EXPORT(motorLA_pwm, motorLA_pwm  );

下图是开机上电终端打印的信息,由于我开启了PWM驱动的调试,所以打印了很多相关的调试信息:

如下是测试的PWM1的波形输出,黄色的通道一测试的正向PWM信号,蓝色的通道二测试的是互补的反向PWM信号:


下图是设置PWM1的占空比为1/10后的效果:

相关链接


本系列首篇文章连接:

https://club.rt-thread.org/ask/article/5c0c4ba7eb4ab1ad.html


———————End——————




👇 点击阅读原文进入官网

RTThread物联网操作系统 帮助您了解RT-Thread相关的资讯.
评论
  •     为控制片内设备并且查询其工作状态,MCU内部总是有一组特殊功能寄存器(SFR,Special Function Register)。    使用Eclipse环境调试MCU程序时,可以利用 Peripheral Registers Viewer来查看SFR。这个小工具是怎样知道某个型号的MCU有怎样的寄存器定义呢?它使用一种描述性的文本文件——SVD文件。这个文件存储在下面红色字体的路径下。    例:南京沁恒  &n
    电子知识打边炉 2025-01-04 20:04 98浏览
  • 每日可见的315MHz和433MHz遥控模块,你能分清楚吗?众所周知,一套遥控设备主要由发射部分和接收部分组成,发射器可以将控制者的控制按键经过编码,调制到射频信号上面,然后经天线发射出无线信号。而接收器是将天线接收到的无线信号进行解码,从而得到与控制按键相对应的信号,然后再去控制相应的设备工作。当前,常见的遥控设备主要分为红外遥控与无线电遥控两大类,其主要区别为所采用的载波频率及其应用场景不一致。红外遥控设备所采用的射频信号频率一般为38kHz,通常应用在电视、投影仪等设备中;而无线电遥控设备
    华普微HOPERF 2025-01-06 15:29 125浏览
  • 村田是目前全球量产硅电容的领先企业,其在2016年收购了法国IPDiA头部硅电容器公司,并于2023年6月宣布投资约100亿日元将硅电容产能提升两倍。以下内容主要来自村田官网信息整理,村田高密度硅电容器采用半导体MOS工艺开发,并使用3D结构来大幅增加电极表面,因此在给定的占位面积内增加了静电容量。村田的硅技术以嵌入非结晶基板的单片结构为基础(单层MIM和多层MIM—MIM是指金属 / 绝缘体/ 金属) 村田硅电容采用先进3D拓扑结构在100um内,使开发的有效静电容量面积相当于80个
    知白 2025-01-07 15:02 66浏览
  • By Toradex 秦海1). 简介嵌入式平台设备基于Yocto Linux 在开发后期量产前期,为了安全以及提高启动速度等考虑,希望将 ARM 处理器平台的 Debug Console 输出关闭,本文就基于 NXP i.MX8MP ARM 处理器平台来演示相关流程。 本文所示例的平台来自于 Toradex Verdin i.MX8MP 嵌入式平台。  2. 准备a). Verdin i.MX8MP ARM核心版配合Dahlia载板并
    hai.qin_651820742 2025-01-07 14:52 40浏览
  • 随着市场需求不断的变化,各行各业对CPU的要求越来越高,特别是近几年流行的 AIOT,为了有更好的用户体验,CPU的算力就要求更高了。今天为大家推荐由米尔基于瑞芯微RK3576处理器推出的MYC-LR3576核心板及开发板。关于RK3576处理器国产CPU,是这些年的骄傲,华为手机全国产化,国人一片呼声,再也不用卡脖子了。RK3576处理器,就是一款由国产是厂商瑞芯微,今年第二季推出的全新通用型的高性能SOC芯片,这款CPU到底有多么的高性能,下面看看它的几个特性:8核心6 TOPS超强算力双千
    米尔电子嵌入式 2025-01-03 17:04 55浏览
  • 自动化已成为现代制造业的基石,而驱动隔离器作为关键组件,在提升效率、精度和可靠性方面起到了不可或缺的作用。随着工业技术不断革新,驱动隔离器正助力自动化生产设备适应新兴趋势,并推动行业未来的发展。本文将探讨自动化的核心趋势及驱动隔离器在其中的重要角色。自动化领域的新兴趋势智能工厂的崛起智能工厂已成为自动化生产的新标杆。通过结合物联网(IoT)、人工智能(AI)和机器学习(ML),智能工厂实现了实时监控和动态决策。驱动隔离器在其中至关重要,它确保了传感器、执行器和控制单元之间的信号完整性,同时提供高
    腾恩科技-彭工 2025-01-03 16:28 170浏览
  • 在智能家居领域中,Wi-Fi、蓝牙、Zigbee、Thread与Z-Wave等无线通信协议是构建短距物联局域网的关键手段,它们常在实际应用中交叉运用,以满足智能家居生态系统多样化的功能需求。然而,这些协议之间并未遵循统一的互通标准,缺乏直接的互操作性,在进行组网时需要引入额外的网关作为“翻译桥梁”,极大地增加了系统的复杂性。 同时,Apple HomeKit、SamSung SmartThings、Amazon Alexa、Google Home等主流智能家居平台为了提升市占率与消费者
    华普微HOPERF 2025-01-06 17:23 141浏览
  • 大模型的赋能是指利用大型机器学习模型(如深度学习模型)来增强或改进各种应用和服务。这种技术在许多领域都显示出了巨大的潜力,包括但不限于以下几个方面: 1. 企业服务:大模型可以用于构建智能客服系统、知识库问答系统等,提升企业的服务质量和运营效率。 2. 教育服务:在教育领域,大模型被应用于个性化学习、智能辅导、作业批改等,帮助教师减轻工作负担,提高教学质量。 3. 工业智能化:大模型有助于解决工业领域的复杂性和不确定性问题,尽管在认知能力方面尚未完全具备专家级的复杂决策能力。 4. 消费
    丙丁先生 2025-01-07 09:25 80浏览
  • PLC组态方式主要有三种,每种都有其独特的特点和适用场景。下面来简单说说: 1. 硬件组态   定义:硬件组态指的是选择适合的PLC型号、I/O模块、通信模块等硬件组件,并按照实际需求进行连接和配置。    灵活性:这种方式允许用户根据项目需求自由搭配硬件组件,具有较高的灵活性。    成本:可能需要额外的硬件购买成本,适用于对系统性能和扩展性有较高要求的场合。 2. 软件组态   定义:软件组态主要是通过PLC
    丙丁先生 2025-01-06 09:23 83浏览
  • 这篇内容主要讨论三个基本问题,硅电容是什么,为什么要使用硅电容,如何正确使用硅电容?1.  硅电容是什么首先我们需要了解电容是什么?物理学上电容的概念指的是给定电位差下自由电荷的储藏量,记为C,单位是F,指的是容纳电荷的能力,C=εS/d=ε0εrS/4πkd(真空)=Q/U。百度百科上电容器的概念指的是两个相互靠近的导体,中间夹一层不导电的绝缘介质。通过观察电容本身的定义公式中可以看到,在各个变量中比较能够改变的就是εr,S和d,也就是介质的介电常数,金属板有效相对面积以及距离。当前
    知白 2025-01-06 12:04 167浏览
  • 彼得·德鲁克被誉为“现代管理学之父”,他的管理思想影响了无数企业和管理者。然而,关于他的书籍分类,一种流行的说法令人感到困惑:德鲁克一生写了39本书,其中15本是关于管理的,而其中“专门写工商企业或为企业管理者写的”只有两本——《为成果而管理》和《创新与企业家精神》。这样的表述广为流传,但深入探讨后却发现并不完全准确。让我们一起重新审视这一说法,解析其中的矛盾与根源,进而重新认识德鲁克的管理思想及其著作的真正价值。从《创新与企业家精神》看德鲁克的视角《创新与企业家精神》通常被认为是一本专为企业管
    优思学院 2025-01-06 12:03 113浏览
  • 本文介绍Linux系统更换开机logo方法教程,通用RK3566、RK3568、RK3588、RK3576等开发板,触觉智能RK3562开发板演示,搭载4核A53处理器,主频高达2.0GHz;内置独立1Tops算力NPU,可应用于物联网网关、平板电脑、智能家居、教育电子、工业显示与控制等行业。制作图片开机logo图片制作注意事项(1)图片必须为bmp格式;(2)图片大小不能大于4MB;(3)BMP位深最大是32,建议设置为8;(4)图片名称为logo.bmp和logo_kernel.bmp;开机
    Industio_触觉智能 2025-01-06 10:43 87浏览
  • 根据Global Info Research项目团队最新调研,预计2030年全球封闭式电机产值达到1425百万美元,2024-2030年期间年复合增长率CAGR为3.4%。 封闭式电机是一种电动机,其外壳设计为密闭结构,通常用于要求较高的防护等级的应用场合。封闭式电机可以有效防止外部灰尘、水分和其他污染物进入内部,从而保护电机的内部组件,延长其使用寿命。 环洋市场咨询机构出版的调研分析报告【全球封闭式电机行业总体规模、主要厂商及IPO上市调研报告,2025-2031】研究全球封闭式电机总体规
    GIRtina 2025-01-06 11:10 103浏览
  • 根据环洋市场咨询(Global Info Research)项目团队最新调研,预计2030年全球无人机锂电池产值达到2457百万美元,2024-2030年期间年复合增长率CAGR为9.6%。 无人机锂电池是无人机动力系统中存储并释放能量的部分。无人机使用的动力电池,大多数是锂聚合物电池,相较其他电池,锂聚合物电池具有较高的能量密度,较长寿命,同时也具有良好的放电特性和安全性。 全球无人机锂电池核心厂商有宁德新能源科技、欣旺达、鹏辉能源、深圳格瑞普和EaglePicher等,前五大厂商占有全球
    GIRtina 2025-01-07 11:02 63浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦