es8388音频芯片驱动之一:寄存器读写驱动

原创 嵌入式Lee 2024-06-17 08:02

.前言

前面我们UAC系列文章分享过MICSPK的案例,分别使用的是SOC自带的ADC采集音频,PDM或者PWM播放音频,这是比较低成本的方案,一般来说除非是专用的多媒体SOC,通用SOC自带的ADC等性能一般都不会很突出。在高性能要求时,一般会外置音频芯片来实现音频采集与播放。我们就以es8388为例来分享整个驱动过程。本文先介绍es8388的微控制器配置接口,实现寄存器的读写配置。

参考官方的两个文档,ES8388 DS.pdf》和《ES8388 user Guide.pdf》。

二. es8388的微控制器接口介绍

ES8388支持SPIIIC两种接口方式来进行配置,需要注意的是SPI只支持写,而IIC支持读写寄存器。一般来说会选择IIC因为支持读写,并且IIC也只需要2个引脚,而SPI需要3个引脚。但是如果对启动速度要求很严格则可以选择SPI方式,可以本地缓存寄存器内容的方式来解决只能写不能读的问题,因为ES8388支持SPI最大10M的速率,而IIC只支持最大400KHz的速率,使用SPI可以大大减少配置时间。所以对于驱动开发者来说,类似这些都是需要考虑的细节,并且也是需要有意识地主动去考虑的问题。

2.1 引脚


涉及到的引脚有CECCLKCDATA

SPI接口时,CE作为SPI_CSn,CCLK作为SPI_CLK,CDATA作为SPI_DIN(SPI_MOSI).

IIC接口时,CCLK作为SCLCDATA作为SDA

那么如何确定是使用SPI接口还是IIC接口呢,通过CE即可,如果CE固定为高或者低无需接控制器,则使用IIC,此时CE的电平代表IIC设备地址的最低位。

如果CE由高到低变化则表示使用SPI接口,此时CE需要接控制器。

2.2 SPI接口

ES8388作为从,CE高到低表示使用SPI接口,最大支持10M速率。

由于只有CDATA一个数据引脚即作为MOSI,所以只能写寄存器不能读寄存器。

SPI_CLK上升沿采样CDATA数据,高位在前。时序如下

CE作为SPI通讯开始,SPI_CLK上升沿采样,先发7位设备地址0x10(此时地址的最低位固定为0),然后是R/Wb(0表示写,1表示读),然后是8位寄存器地址,最后是8位数据,也就是CE拉低的过程一次发完三个字节的数据。

2.3IIC接口

CE固定为高或者为低,对应7位设备地址分别为0x100x11

高位在前,最大支持400kHz速率。

时序图如下

写寄存器,先发start,然后发7位设备地址+R/Wr位为0ES8388ACK

然后发寄存器地址,ES8388ACK

再发寄存器值,ES8388ACK

STOP

读寄存器,先发start,然后发7位设备地址+R/Wr0ES8388ACK

然后发寄存器地址,ES8388ACK

再发start,然后发7位设备地址+R/Wr1ES8388ACK

再读寄存器值,发NACK

STOP

三. 驱动

我们使用IIC方式,CE接高电平,所以7位设备地址是0x11. 前面我们已经分享了很多IO模拟IIC方式驱动各种IIC设备的案例。现在我们也可以设计既支持IO模拟IIC,也可以支持硬件IIC方式,通过宏区分,这样使用IO方式可以快速验证评估,后续再使用硬件IIC优化性能, 很多时候对性能要求没这么高使用IO模拟方式反而更灵活简单可靠。

由于前面已经分享了很多IO模拟IIC的驱动了,这里就直接上代码。

es8388_itf.c/es8388_itf.h:需要用户实现es8388.c需要的接口es8388_write_reg,es8388_read_reg,ES8388_LOG,

以及其他初始化过程等, 也可以进一步封装,对外提供es8388操作的接口。

io_iic.c,io_iic.h:IO模拟IIC的实现,完全可移植,无需任何修改,如果es8388_itf.h中定义宏#define USE_IO_IIC 1则使用IO模拟IIC的方式,使用该部分实现,否则使用硬件IIC

Io_iic.c

#include "io_iic.h"
/**
 *                     _______________________    *    SCL ____________|                       |__ *        ———————————————————————— *    SDA                         |______________ *        (1)      (2)        (4)         (6) *                        (3)           (5) *    其中(3) SDA低建立时间 (5) SDA高保持时间 *    (1) 拉高SDA  (4)拉高SDA产生上升沿 *    (2) SCL拉高 SCL高时SDA上升沿即停止信号 */void io_iic_start(io_iic_dev_st* dev){    /* SCL高时,SDA下降沿 */    dev->sda_write(1);               /* (1) SDA拉高以便后面产生下降沿  */    dev->scl_write(1);               /* (2) 拉高SCL                   */    if(dev->delay_pf != 0)           /* (3) SCL高保持*/    {        dev->delay_pf(dev->delayus);    }    dev->sda_write(0);              /* (4)SCL高时SDA下降沿 启动    */    if(dev->delay_pf != 0)          /* (5)SCL高保持               */    {        dev->delay_pf(dev->delayus);    }    dev->scl_write(0);             /* (6)SCL恢复                 */}
/**
 *                     _______________________    *    SCL ____________|                       |____ *                                 ———————————————— *    SDA ————————————————————————| *        (1)      (2)        (4)         (6) *                        (3)           (5) *    其中(3) SDA低建立时间 (5) SDA高保持时间 *    (1) 拉低SDA  (4)拉高SDA产生上升沿 *    (2) SCL拉高 SCL高时SDA上升沿即停止信号 */void io_iic_stop(io_iic_dev_st* dev){    /* SCL高时,SDA上升沿 */    dev->sda_write(0);               /* (1)SDA先输出低以便产生上升沿 */    dev->scl_write(1);               /* (2)SCL高                   */    if(dev->delay_pf != 0)           /* (3)SCL高保持               */    {        dev->delay_pf(dev->delayus);    }     dev->sda_write(1);               /* (4)SCL高时SDA上升沿 停止    */    if(dev->delay_pf != 0)           /* (5)SCL高保持               */    {        dev->delay_pf(dev->delayus);    }    dev->scl_write(0);               /* (6)SCL恢复                 */}
/** *   |       B0               | B1~B6|    B7               |           NACK/ACK      | *                 ___________      _            __________              ____________ *    ____________|           |   x  |__________|          |____________|            | * (1)[2]      (4)                                      (6)[7]        (9)[10]       (12) *        (3)           (5)                                     (8)           (11)  * 其中(1)(6)(12)拉低SCL;(4)(9)拉高SCL; * [2]输出  [7]转为读 [10]读ACK; * (3)(8)低保持时间,(5)(11)高保持时间。 */int io_iic_write(io_iic_dev_st* dev, uint8_t val){    uint8_t tmp = val;    uint8_t ack = 0;    if(dev == 0)    {        return -1;    }    if((dev->scl_write == 0) || (dev->sda_write == 0) || (dev->sda_read == 0) || (dev->sda_2read == 0))    {        return -1;    }    /* SCL下降沿后准备数据,对方上升沿采集数据,高位在前 */    for(uint8_t i=0; i<8; i++)    {        dev->scl_write(0);               /* (1) SCL拉低以便修改数据    */        if((tmp & 0x80) != 0)            /* [2] 准备SDA数据            */        {            dev->sda_write(1);         }        else        {            dev->sda_write(0);          }        if(dev->delay_pf != 0)        {            dev->delay_pf(dev->delayus); /* (3) SCL拉低时间即数据建立时间 */        }        dev->scl_write(1);                /*(4) SCL上升沿对方采样        */        if(dev->delay_pf != 0)        {             dev->delay_pf(dev->delayus); /* (5) SCL高保持时间,数据保持时间 */        }        tmp <<= 1;                       /* 处理下一位           */    }    dev->scl_write(0);                   /* (6)SCL归0  完成8个CLK */    dev->sda_2read();                    /* [7]SDA转为读          */    if(dev->delay_pf != 0)    {         dev->delay_pf(dev->delayus);     /* (8)第九个时钟拉低时间  */    }    dev->scl_write(1);                   /* (9)SCL上升沿          */    ack = dev->sda_read();               /* [10]上升沿后读         */    if(dev->delay_pf != 0)    {         dev->delay_pf(dev->delayus);     /* (11)第九个时钟高保持    */    }    dev->scl_write(0);                   /* (12)恢复SCL到低        */    return (ack==0) ? 0 : -1;}
/** *   |       B0               | B1~B6|    B7               |           NACK/ACK      | *                 ___________      _            __________              ____________ *    ____________|           |   x  |__________|          |____________|            | * (1)[2]      (4)[5]                                    (7)[8]       (10)         (12) *        (3)           (6)                                     (9)           (11)  * 其中(1)(7)(12)拉低SCL;(4)(10)拉高SCL; * [2]转为读  [5]读 [8]输出ACK; * (3)(9)低保持时间,(6)(11)高保持时间。 */int io_iic_read(io_iic_dev_st* dev, uint8_t* val, uint8_t ack){    uint8_t tmp = 0;    if((dev == 0) || (val == 0))    {        return -1;    }    if((dev->scl_write == 0) || (dev->sda_write == 0) || (dev->sda_read == 0) || (dev->sda_2read == 0))    {        return -1;    }    /* SCL下降沿后对方准备数据,上升沿读数据,高位在前 */    for(uint8_t i=0; i<8; i++)    {        tmp <<= 1;                      /* 处理下一位,先移动后读取             */        dev->scl_write(0);              /* (1)                               */        dev->sda_2read();               /* [2]转为读输入高阻,以便对方能输出     */        if(dev->delay_pf != 0)                   {            dev->delay_pf(dev->delayus);/* (3)SCL低保持时间                    */        }        dev->scl_write(1);              /* (4)SCL上升沿                        */        if(dev->sda_read())             /* (5)读数据(SCL低时对方已经准备好数据)  */        {             tmp |= 0x01;                /* 高位在前,最后左移到高位              */        }              if(dev->delay_pf != 0)                  {             dev->delay_pf(dev->delayus);/* (6)SCL高保持时间                     */        }    }    dev->scl_write(0);                  /* (7)恢复SCL时钟为低                   */    dev->sda_write(ack);                /* [8]准备ACK信号(SCL低才能更行SDL)      */    if(dev->delay_pf != 0)    {         dev->delay_pf(dev->delayus);    /* (9)第九个SCL拉低时间                  */    }    dev->scl_write(1);                  /* (10)SCL上升沿发数据触发对方读          */    if(dev->delay_pf != 0)    {         dev->delay_pf(dev->delayus);    /* (11)第九个SCL拉高保持时间              */    }    dev->scl_write(0);                  /* (12)第九个SCL完成恢复低                */    //dev->sda_write(1);                /* 这里无需驱动SDA,后面可能还是读),需要发送时再驱动 */    *val = tmp;    return 0;}
void io_iic_init(io_iic_dev_st* dev){    if((dev != 0) && (dev->init != 0))    {        dev->init();    }}
void io_iic_deinit(io_iic_dev_st* dev){    if((dev != 0) && (dev->deinit != 0))    {         dev->deinit();    }}

Io_iic.h

#ifndef IO_IIC_H#define IO_IIC_H
#ifdef __cplusplus    extern "C"{#endif
#include
typedef void    (*io_iic_scl_write_pf)(uint8_t val);   /**< SCL写接口     */typedef void    (*io_iic_sda_write_pf)(uint8_t val);   /**< SDA写接口     */typedef void    (*io_iic_sda_2read_pf)(void);          /**< SDA转为读接口 */typedef uint8_t (*io_iic_sda_read_pf)(void);           /**< SDA读接口     */typedef void    (*io_iic_delay_us_pf)(uint32_t delay); /**< 延时接口      */typedef void    (*io_iic_init_pf)(void);               /**< 初始化接口     */typedef void    (*io_iic_deinit_pf)(void);             /**< 解除初始化接口 */
/** * \struct io_iic_dev_st * 接口结构体*/typedef struct{    io_iic_scl_write_pf scl_write;   /**< scl写接口    */    io_iic_sda_write_pf sda_write;   /**< sda写接口    */    io_iic_sda_2read_pf sda_2read;   /**< sda转为读接口 */    io_iic_sda_read_pf  sda_read;    /**< sda读接口     */    io_iic_delay_us_pf  delay_pf;    /**< 延时接口      */    io_iic_init_pf      init;        /**< 初始化接口    */    io_iic_deinit_pf    deinit;      /**< 解除初始化接口 */    uint32_t            delayus;     /**< 延迟时间      */} io_iic_dev_st;
/** * \fn io_iic_start * 发送启动信号 * \param[in] dev \ref io_iic_dev_st*/void io_iic_start(io_iic_dev_st* dev);
/** * \fn io_iic_stop * 发送停止信号 * \param[in] dev \ref io_iic_dev_st*/void io_iic_stop(io_iic_dev_st* dev);
/** * \fn io_iic_write * 写一个字节 * \param[in] dev \ref io_iic_dev_st * \param[in] val 待写入的值 * \retval 0 写成功(收到了ACK) * \retval -2 写失败(未收到ACK) * \retval -1 参数错误*/int io_iic_write(io_iic_dev_st* dev, uint8_t val);
/** * \fn io_iic_read * 读一个字节 * \param[in] dev \ref io_iic_dev_st * \param[out] val 存储读到的值 * \param[in] ack 1发送NACK 0发送ACK * \retval 0 读成功 * \retval -1 参数错误*/int io_iic_read(io_iic_dev_st* dev, uint8_t* val, uint8_t ack);
/** * \fn io_iic_init * 初始化 * \param[in] dev \ref io_iic_dev_st*/void io_iic_init(io_iic_dev_st* dev);
/** * \fn io_iic_deinit * 解除初始化 * \param[in] dev \ref io_iic_dev_st*/void io_iic_deinit(io_iic_dev_st* dev);
#ifdef __cplusplus    }#endif
#endif


Es8388_itf.c

#include "gpio.h"#include "es8388.h"#include "es8388_itf.h"
#if USE_IO_IIC#include "io_iic.h"#else#include "i2c.h"#define ES8388_IIC_PORT I2C_PORT_1#endif
#define ES8388_IIC_SCL_PIN  GPIO_09#define ES8388_IIC_SDA_PIN  GPIO_07
#define ES8388_IIC_DEV_ADDR 0x11  /* AD0为CS引脚电平 */
static int es8388_init_flag = 0;
#if USE_IO_IIC/* IIC IO操作的移植 */static void io_iic_scl_write_port(uint8_t val){    if(val)    {        gpio_write(ES8388_IIC_SCL_PIN, 1);    }    else    {        gpio_write(ES8388_IIC_SCL_PIN, 0);    }}
static void io_iic_sda_write_port(uint8_t val){    gpio_setdirection(ES8388_IIC_SDA_PIN, GPIO_DIRECTION_OUTPUT);     if(val)    {        gpio_write(ES8388_IIC_SDA_PIN, 1);    }    else    {        gpio_write(ES8388_IIC_SDA_PIN, 0);    }}
static void io_iic_sda_2read_port(void){    gpio_setdirection(ES8388_IIC_SDA_PIN, GPIO_DIRECTION_INPUT);}
static uint8_t io_iic_sda_read_port(void){    if(0 == gpio_read(ES8388_IIC_SDA_PIN))    {        return 0;    }    else    {        return 1;    }}
static void io_iic_delay_us_port(uint32_t delay){    uint32_t volatile t=delay;    while(t--);}
static void io_iic_init_port(void){    gpio_open(ES8388_IIC_SCL_PIN, GPIO_DIRECTION_OUTPUT);    gpio_open(ES8388_IIC_SDA_PIN, GPIO_DIRECTION_OUTPUT);    gpio_set_pull_mode(ES8388_IIC_SCL_PIN,GPIO_PULL_UP);    gpio_set_pull_mode(ES8388_IIC_SDA_PIN,GPIO_PULL_UP);    gpio_write(ES8388_IIC_SCL_PIN, 0);    gpio_write(ES8388_IIC_SDA_PIN, 0);}
static void io_iic_deinit_port(void){    gpio_close(ES8388_IIC_SCL_PIN);    gpio_close(ES8388_IIC_SDA_PIN);}
static io_iic_dev_st iic_dev={    .scl_write = io_iic_scl_write_port,    .sda_write = io_iic_sda_write_port,    .sda_2read = io_iic_sda_2read_port,    .sda_read = io_iic_sda_read_port,    .delay_pf = io_iic_delay_us_port,    .init = io_iic_init_port,    .deinit = io_iic_deinit_port,    .delayus = 5,};#else
#endif
int es8388_itf_init(void){    if(es8388_init_flag != 0)    {        return 0;    }    es8388_init_flag = 0;    #if USE_IO_IIC    io_iic_init(&iic_dev);#else    i2c_gpio_cfg_t gpio_cfg;    gpio_cfg.scl = ES8388_IIC_SCL_PIN;    gpio_cfg.sda = ES8388_IIC_SDA_PIN;
    i2c_config_t iic_cfg;    iic_cfg.baudrate = 50000;    iic_cfg.i2c_busrt_mode = 0;    iic_cfg.wait_nack_max_time = 10;    gpio_set_pull_mode(ES8388_IIC_SCL_PIN,GPIO_PULL_UP);    gpio_set_pull_mode(ES8388_IIC_SDA_PIN,GPIO_PULL_UP);    i2c_init(ES8388_IIC_PORT, &iic_cfg);    i2c_open(ES8388_IIC_PORT, &gpio_cfg);#endif    es8388_dump_allregs();
    /* 读写寄存器测试 */    #if 1    //while(0)    {        uint8_t val=0;        es8388_read_reg((uint8_t)8, &val);        val |= 0x20;        es8388_write_reg((uint8_t)8, val);        val = 0;        es8388_read_reg((uint8_t)8, &val);        ES8388_LOG(("set reg 8 to %x\n",val));        val &= ~0x20;        es8388_write_reg((uint8_t)8, val);        val = 0;        es8388_read_reg((uint8_t)8, &val);        ES8388_LOG(("set reg 8 to %x\n",val));    }    #endif    es8388_dump_allregs();     return 0;}
int es8388_itf_deinit(void){#if USE_IO_IIC    io_iic_deinit(&iic_dev);
#else    i2c_close(ES8388_IIC_PORT);    i2c_deinit(ES8388_IIC_PORT);#endif    return 0;}
int es8388_write_reg(uint8_t reg, uint8_t val){#if USE_IO_IIC    /* 启动 */    io_iic_start(&iic_dev);
    /* 发送写地址 */    if(0 != io_iic_write(&iic_dev,ES8388_IIC_DEV_ADDR<<1))    {        io_iic_stop(&iic_dev);        return -1;    }
    /* 寄存器地址 */    if(0 != io_iic_write(&iic_dev,reg))    {        io_iic_stop(&iic_dev);        return -2;    }
    /* 写数据 */    if(0 != io_iic_write(&iic_dev,val))    {        io_iic_stop(&iic_dev);        return -2;    }        /* 结束 */    io_iic_stop(&iic_dev);    return 0;
#else    uint8_t tx_buf[1];    tx_buf[0] = val;    int ret = i2c_master_transmit(ES8388_IIC_PORT, ES8388_IIC_DEV_ADDR, reg, I2C_MEMORY_ADDR_8BIT,                                                tx_buf, 1, 1000);    if(ret != RET_OK)     {        ES8388_LOG(("es8388 iic write reg %d err %d\n", ES8388_IIC_PORT, reg, ret));    }     return ret; #endif}
int es8388_read_reg(uint8_t reg, uint8_t* val){#if USE_IO_IIC    /* 启动 */    io_iic_start(&iic_dev);
    /* 发送写地址 */    if(0 != io_iic_write(&iic_dev,ES8388_IIC_DEV_ADDR<<1))    {        io_iic_stop(&iic_dev);        return -1;    }
    /* 寄存器地址 */    if(0 != io_iic_write(&iic_dev,reg))    {        io_iic_stop(&iic_dev);        return -2;    }
    /* 重新启动 */    io_iic_start(&iic_dev);
    /* 发送读地址 */    if(0 != io_iic_write(&iic_dev,(ES8388_IIC_DEV_ADDR<<1) | 0x01))    {        io_iic_stop(&iic_dev);        return -1;    }        /* 读数据 */    if(0 != io_iic_read(&iic_dev,val,1))    {        io_iic_stop(&iic_dev);        return -2;      }
    /* 结束 */    io_iic_stop(&iic_dev);    return 0;#else    uint8_t rx_buffer[1];    int ret = i2c_master_receive_from_memory_poll(ES8388_IIC_PORT, ES8388_IIC_DEV_ADDR, reg, I2C_MEMORY_ADDR_8BIT,                                           rx_buffer, 1, 1000);    *val = rx_buffer[0];    if(ret != RET_OK)     {        ES8388_LOG(("es8388 iic read reg %d err %d\n", reg, ret));    }     return ret;#endif}
int es8388_dump_allregs(void){    uint8_t regval;    for(int i=0; i<53; i++)    {        if(0 != es8388_read_reg(i,®val))        {            return -1;        }        ES8388_LOG(("REG%02d:0x%x\r\n",i,regval));    }    return 0;}

Es8388_itf.h

#ifndef ES8388_ITF_H#define ES8388_ITF_H
#ifdef __cplusplus    extern "C"{#endif
#include
#define USE_IO_IIC 1 /**< 配置为1使用IO模拟IIC的方式,否则使用硬件IIC */
#define ES8388_LOG_EN 1 /**< 配置为1使能日志打印输出,否则不使能 */
#if ES8388_LOG_EN#include #define ES8388_LOG(msg) printf msg #else#define ES8388_LOG(msg) #endif

int es8388_itf_init(void);int es8388_itf_deinit(void);
int es8388_write_reg(uint8_t reg, uint8_t val);int es8388_read_reg(uint8_t reg, uint8_t* val);int es8388_dump_allregs(void)
#ifdef __cplusplus    }#endif
#endif

四. 测试

测试寄存器的读写和打印所有寄存器默认值如下,可以看到读写8寄存器正确,打印的寄存器默认值和手册对应。

REG00:0x6

REG01:0x5c

REG02:0xc3

REG03:0xfc

REG04:0xc0

REG05:0x0

REG06:0x0

REG07:0x7c

REG08:0x80

REG09:0x0

REG10:0x0

REG11:0x2

REG12:0x0

REG13:0x6

REG14:0x30

REG15:0x20

REG16:0xc0

REG17:0xc0

REG18:0x38

REG19:0xb0

REG20:0x32

REG21:0x6

REG22:0x0

REG23:0x0

REG24:0x6

REG25:0x22

REG26:0xc0

REG27:0xc0

REG28:0x8

REG29:0x0

REG30:0x1f

REG31:0xf7

REG32:0xfd

REG33:0xff

REG34:0x1f

REG35:0xf7

REG36:0xfd

REG37:0xff

REG38:0x0

REG39:0x38

REG40:0x28

REG41:0x28

REG42:0x38

REG43:0x0

REG44:0x0

REG45:0x0

REG46:0x0

REG47:0x0

REG48:0x0

REG49:0x0

REG50:0x0

REG51:0xaa

REG52:0xaa

set reg 8 to a0

set reg 8 to 80


.总结

进行IIC读写寄存器调试时,只需要ES8388上电,IIC接口即可工作即可读写寄存器,无需提供MCLK时钟。所以如果不通,只需要检查DVDDPVDDDGND,这几个电源引脚,以及CE的电平确认设备地址是0x11还是0x10。 使用示波器确认IIC接口信号,逻辑分析仪抓取IIC信号解析即可。

至此我们的IO模拟IIC的代码已经应用在了各种IIC接口设备的驱动,非常方便简单好用,现在也可以看到自己造一个好用的轮子是一件多值得的事了。


评论
  • 光耦合器,也称为光隔离器,是一种利用光在两个隔离电路之间传输电信号的组件。在医疗领域,确保患者安全和设备可靠性至关重要。在众多有助于医疗设备安全性和效率的组件中,光耦合器起着至关重要的作用。这些紧凑型设备经常被忽视,但对于隔离高压和防止敏感医疗设备中的电气危害却是必不可少的。本文深入探讨了光耦合器的功能、其在医疗应用中的重要性以及其实际使用示例。什么是光耦合器?它通常由以下部分组成:LED(发光二极管):将电信号转换为光。光电探测器(例如光电晶体管):检测光并将其转换回电信号。这种布置确保输入和
    腾恩科技-彭工 2025-01-03 16:27 162浏览
  • 根据Global Info Research项目团队最新调研,预计2030年全球封闭式电机产值达到1425百万美元,2024-2030年期间年复合增长率CAGR为3.4%。 封闭式电机是一种电动机,其外壳设计为密闭结构,通常用于要求较高的防护等级的应用场合。封闭式电机可以有效防止外部灰尘、水分和其他污染物进入内部,从而保护电机的内部组件,延长其使用寿命。 环洋市场咨询机构出版的调研分析报告【全球封闭式电机行业总体规模、主要厂商及IPO上市调研报告,2025-2031】研究全球封闭式电机总体规
    GIRtina 2025-01-06 11:10 42浏览
  • 物联网(IoT)的快速发展彻底改变了从智能家居到工业自动化等各个行业。由于物联网系统需要高效、可靠且紧凑的组件来处理众多传感器、执行器和通信设备,国产固态继电器(SSR)已成为满足中国这些需求的关键解决方案。本文探讨了国产SSR如何满足物联网应用的需求,重点介绍了它们的优势、技术能力以及在现实场景中的应用。了解物联网中的固态继电器固态继电器是一种电子开关设备,它使用半导体而不是机械触点来控制负载。与传统的机械继电器不同,固态继电器具有以下优势:快速切换:确保精确快速的响应,这对于实时物联网系统至
    克里雅半导体科技 2025-01-03 16:11 165浏览
  • 本文介绍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 41浏览
  • 自动化已成为现代制造业的基石,而驱动隔离器作为关键组件,在提升效率、精度和可靠性方面起到了不可或缺的作用。随着工业技术不断革新,驱动隔离器正助力自动化生产设备适应新兴趋势,并推动行业未来的发展。本文将探讨自动化的核心趋势及驱动隔离器在其中的重要角色。自动化领域的新兴趋势智能工厂的崛起智能工厂已成为自动化生产的新标杆。通过结合物联网(IoT)、人工智能(AI)和机器学习(ML),智能工厂实现了实时监控和动态决策。驱动隔离器在其中至关重要,它确保了传感器、执行器和控制单元之间的信号完整性,同时提供高
    腾恩科技-彭工 2025-01-03 16:28 164浏览
  • 在测试XTS时会遇到修改产品属性、SElinux权限、等一些内容,修改源码再编译很费时。今天为大家介绍一个便捷的方法,让OpenHarmony通过挂载镜像来修改镜像内容!触觉智能Purple Pi OH鸿蒙开发板演示。搭载了瑞芯微RK3566四核处理器,树莓派卡片电脑设计,支持开源鸿蒙OpenHarmony3.2-5.0系统,适合鸿蒙开发入门学习。挂载镜像首先,将要修改内容的镜像传入虚拟机当中,并创建一个要挂载镜像的文件夹,如下图:之后通过挂载命令将system.img镜像挂载到sys
    Industio_触觉智能 2025-01-03 11:39 113浏览
  • 随着市场需求不断的变化,各行各业对CPU的要求越来越高,特别是近几年流行的 AIOT,为了有更好的用户体验,CPU的算力就要求更高了。今天为大家推荐由米尔基于瑞芯微RK3576处理器推出的MYC-LR3576核心板及开发板。关于RK3576处理器国产CPU,是这些年的骄傲,华为手机全国产化,国人一片呼声,再也不用卡脖子了。RK3576处理器,就是一款由国产是厂商瑞芯微,今年第二季推出的全新通用型的高性能SOC芯片,这款CPU到底有多么的高性能,下面看看它的几个特性:8核心6 TOPS超强算力双千
    米尔电子嵌入式 2025-01-03 17:04 23浏览
  • PLC组态方式主要有三种,每种都有其独特的特点和适用场景。下面来简单说说: 1. 硬件组态   定义:硬件组态指的是选择适合的PLC型号、I/O模块、通信模块等硬件组件,并按照实际需求进行连接和配置。    灵活性:这种方式允许用户根据项目需求自由搭配硬件组件,具有较高的灵活性。    成本:可能需要额外的硬件购买成本,适用于对系统性能和扩展性有较高要求的场合。 2. 软件组态   定义:软件组态主要是通过PLC
    丙丁先生 2025-01-06 09:23 38浏览
  • 本文继续介绍Linux系统查看硬件配置及常用调试命令,方便开发者快速了解开发板硬件信息及进行相关调试。触觉智能RK3562开发板演示,搭载4核A53处理器,主频高达2.0GHz;内置独立1Tops算力NPU,可应用于物联网网关、平板电脑、智能家居、教育电子、工业显示与控制等行业。查看系统版本信息查看操作系统版本信息root@ido:/# cat /etc/*releaseDISTRIB_ID=UbuntuDISTRIB_RELEASE=20.04DISTRIB_CODENAME=focalDIS
    Industio_触觉智能 2025-01-03 11:37 138浏览
  • 车身域是指负责管理和控制汽车车身相关功能的一个功能域,在汽车域控系统中起着至关重要的作用。它涵盖了车门、车窗、车灯、雨刮器等各种与车身相关的功能模块。与汽车电子电气架构升级相一致,车身域发展亦可以划分为三个阶段,功能集成愈加丰富:第一阶段为分布式架构:对应BCM车身控制模块,包含灯光、雨刮、门窗等传统车身控制功能。第二阶段为域集中架构:对应BDC/CEM域控制器,在BCM基础上集成网关、PEPS等。第三阶段为SOA理念下的中央集中架构:VIU/ZCU区域控制器,在BDC/CEM基础上集成VCU、
    北汇信息 2025-01-03 16:01 175浏览
  • 影像质量应用于多个不同领域,无论是在娱乐、医疗或工业应用中,高质量的影像都是决策的关键基础。清晰的影像不仅能提升观看体验,还能保证关键细节的准确传达,例如:在医学影像中,它对诊断结果有着直接的影响!不仅如此,影像质量还影响了:▶ 压缩技术▶ 存储需求▶ 传输效率随着技术进步,影像质量的标准不断提高,对于研究与开发领域,理解并提升影像质量已成为不可忽视的重要课题。在图像处理的过程中,硬件与软件除了各自扮演着不可或缺的基础角色,有效地协作能够确保图像处理过程既高效又具有优异的质量。软硬件各扮演了什么
    百佳泰测试实验室 2025-01-03 10:39 143浏览
  •     为控制片内设备并且查询其工作状态,MCU内部总是有一组特殊功能寄存器(SFR,Special Function Register)。    使用Eclipse环境调试MCU程序时,可以利用 Peripheral Registers Viewer来查看SFR。这个小工具是怎样知道某个型号的MCU有怎样的寄存器定义呢?它使用一种描述性的文本文件——SVD文件。这个文件存储在下面红色字体的路径下。    例:南京沁恒  &n
    电子知识打边炉 2025-01-04 20:04 32浏览
  • 在快速发展的能源领域,发电厂是发电的支柱,效率和安全性至关重要。在这种背景下,国产数字隔离器已成为现代化和优化发电厂运营的重要组成部分。本文探讨了这些设备在提高性能方面的重要性,同时展示了中国在生产可靠且具有成本效益的数字隔离器方面的进步。什么是数字隔离器?数字隔离器充当屏障,在电气上将系统的不同部分隔离开来,同时允许无缝数据传输。在发电厂中,它们保护敏感的控制电路免受高压尖峰的影响,确保准确的信号处理,并在恶劣条件下保持系统完整性。中国国产数字隔离器经历了重大创新,在许多方面达到甚至超过了全球
    克里雅半导体科技 2025-01-03 16:10 121浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦