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接口设备的驱动,非常方便简单好用,现在也可以看到自己造一个好用的轮子是一件多值得的事了。


评论
  • 在 AI 浪潮席卷下,厨电行业正经历着深刻变革。AWE 2025期间,万得厨对外首次发布了wan AiOS 1.0组织体超智能系统——通过AI技术能够帮助全球家庭实现从健康检测、膳食推荐,到食材即时配送,再到一步烹饪、营养总结的个性化健康膳食管理。这一创新之举并非偶然的个案,而是整个厨电行业大步迈向智能化、数字化转型浪潮的一个关键注脚,折射出全行业对 AI 赋能的热切渴求。前有标兵后有追兵,万得厨面临着高昂的研发成本与技术迭代压力,稍有懈怠便可能被后来者赶
    用户1742991715177 2025-05-11 22:44 161浏览
  •   电磁数据管理系统深度解析   北京华盛恒辉电磁数据管理系统作为专业的数据处理平台,旨在提升电磁数据的处理效率、安全性与可靠性。以下从功能架构、核心特性、应用场景及技术实现展开分析:   应用案例   目前,已有多个电磁数据管理系统在实际应用中取得了显著成效。例如,北京华盛恒辉和北京五木恒润电磁数据管理系统。这些成功案例为电磁数据管理系统的推广和应用提供了有力支持。   一、核心功能模块   数据采集与接入:实时接收天线、频谱仪等设备数据,兼容多协议接口,确保数据采集的全面性与实时性
    华盛恒辉l58ll334744 2025-05-13 10:59 115浏览
  • 递交招股书近一年后,曹操出行 IPO 进程终于迎来关键节点。从 2024 年 4 月首次递表,到 2025 年 4 月顺利通过中国证监会境外发行上市备案,并迅速更新招股书。而通过上市备案也标志着其赴港IPO进程进入实质性推进阶段,曹操出行最快有望于2025年内完成港股上市,成为李书福商业版图中又一关键落子。行路至此,曹操出行面临的挑战依然不容忽视。当下的网约车赛道,早已不是当年群雄逐鹿的草莽时代,市场渐趋饱和,竞争近乎白热化。曹操出行此时冲刺上市,既是背水一战,也是谋篇布局。其招股书中披露的资金
    用户1742991715177 2025-05-10 21:18 95浏览
  • 在全球供应链紧张和国产替代需求推动下,国产存储芯片产业快速发展,形成设计到封测一体化的完整生态。北京君正、兆易创新、紫光国芯、东芯股份、普冉股份和佰维存储等六大上市公司在NOR/NAND Flash、DRAM、嵌入式存储等领域布局各具特色,推动国产替代提速。贞光科技代理的品牌紫光国芯,专注DRAM技术,覆盖嵌入式存储与模组解决方案,为多领域客户提供高可靠性产品。随着AI、5G等新兴应用兴起,国产存储厂商有望迎来新一轮增长。存储芯片分类与应用易失性与非易失性存储芯片易失性存储芯片(Volatile
    贞光科技 2025-05-12 16:05 116浏览
  •   基于 2025 年行业权威性与时效性,以下梳理国内知名软件定制开发企业,涵盖综合型、垂直领域及特色技术服务商:   华盛恒辉科技有限公司:是一家专注于高端软件定制开发服务和高端建设的服务机构,致力于为企业提供全面、系统的开发制作方案。在部队政企开发、建设到运营推广领域拥有丰富经验,在教育,工业,医疗,APP,管理,商城,人工智能,部队软件、工业软件、数字化转型、新能源软件、光伏软件、汽车软件,ERP,系统二次开发,CRM等领域有很多成功案例。   五木恒润科技有限公司:是一家专业的部队信
    华盛恒辉l58ll334744 2025-05-12 16:13 209浏览
  •   电磁数据展示系统平台解析   北京华盛恒辉电磁数据展示系统平台是实现电磁数据高效展示、分析与管理的综合性软件体系,以下从核心功能、技术特性、应用场景及发展趋势展开解读:   应用案例   目前,已有多个电磁数据展示系统在实际应用中取得了显著成效。例如,北京华盛恒辉和北京五木恒润电磁数据展示系统。这些成功案例为电磁数据展示系统的推广和应用提供了有力支持。   一、核心功能模块   数据采集与预处理   智能分析处理   集成频谱分析、时频变换等信号处理算法,自动提取时域频域特征;
    华盛恒辉l58ll334744 2025-05-13 10:20 134浏览
  •   定制软件开发公司推荐清单   在企业数字化转型加速的2025年,定制软件开发需求愈发多元复杂。不同行业、技术偏好与服务模式的企业,对开发公司的要求大相径庭。以下从技术赛道、服务模式及行业场景出发,为您提供适配的定制软件开发公司推荐及选择建议。   华盛恒辉科技有限公司:是一家专注于高端软件定制开发服务和高端建设的服务机构,致力于为企业提供全面、系统的开发制作方案。在部队政企开发、建设到运营推广领域拥有丰富经验,在教育,工业,医疗,APP,管理,商城,人工智能,部队软件、工业软件、数字化转
    华盛恒辉l58ll334744 2025-05-12 15:55 266浏览
  •         信创产业含义的“信息技术应用创新”一词,最早公开信息见于2019年3月26日,在江苏南京召开的信息技术应用创新研讨会。本次大会主办单位为江苏省工业和信息化厅和中国电子工业标准化技术协会安全可靠工作委员会。        2019年5月16日,美国将华为列入实体清单,在未获得美国商务部许可的情况下,美国企业将无法向华为供应产品。       2019年6
    天涯书生 2025-05-11 10:41 178浏览
  • 文/Leon编辑/cc孙聪颖‍2025年1月至今,AI领域最出圈的除了DeepSeek,就是号称首个“通用AI Agent”(智能体)的Manus了,其邀请码一度被炒到8万元。很快,通用Agent就成为互联网大厂、AI独角兽们的新方向,迅速地“卷”了起来。国外市场,Open AI、Claude、微软等迅速推出Agent产品或构建平台,国内企业也在4月迅速跟进。4月,字节跳动、阿里巴巴、百度纷纷入局通用Agent市场,主打复杂的多任务、工作流功能,并对个人用户免费。腾讯则迅速更新腾讯元器的API接
    华尔街科技眼 2025-05-12 22:29 10浏览
  • ‌磁光克尔效应(Magneto-Optic Kerr Effect, MOKE)‌ 是指当线偏振光入射到磁性材料表面并反射后,其偏振状态(偏振面旋转角度和椭偏率)因材料的磁化强度或方向发生改变的现象。具体表现为:1、‌偏振面旋转‌:反射光的偏振方向相对于入射光发生偏转(克尔旋转角 θK)。2、‌椭偏率变化‌:反射光由线偏振变为椭圆偏振(克尔椭偏率 εK)。这一效应直接关联材料的磁化状态,是表征磁性材料(如铁磁体、反铁磁体)磁学性质的重要非接触式光学探测手段,广泛用于
    锦正茂科技 2025-05-12 11:02 233浏览
  • 感谢面包板论坛组织的本次测评活动,本次测评的对象是STM32WL Nucleo-64板 (NUCLEO-WL55JC) ,该测试板专为LoRa™应用原型构建,基于STM32WL系列sub-GHz无线微控制器。其性能、功耗及特性组合经过精心挑选,支持通过Arduino® Uno V3连接,并利用ST morpho接头扩展STM32WL Nucleo功能,便于访问多种专用屏蔽。STM32WL Nucleo-64板集成STLINK-V3E调试器与编程器,无需额外探测器。该板配备全面的STM
    无言的朝圣 2025-05-13 09:47 14浏览
  • 【拆解】+CamFi卡菲单反无线传输器拆解 对于单反爱好者,想要通过远程控制自拍怎么办呢。一个远程连接,远程控制相机拍摄的工具再合适不过了。今天给大伙介绍的是CamFi卡菲单反无线传输器。 CamFi 是专为数码单反相机打造的无线传输控制器,自带的 WiFi 功能(无需手机流量),不但可通过手机、平板、电脑等设备远程连接操作单反相机进行拍摄,而且还可实时传输相机拍摄的照片到 iPad 和电视等大屏设备进行查看和分享。 CamFi 支持大部分佳能和尼康单反相机,内置可充电锂离子电池,无需相机供电。
    zhusx123 2025-05-11 14:14 275浏览
  • 在印度与巴基斯坦的军事对峙情境下,歼10C的出色表现如同一颗投入平静湖面的巨石,激起层层涟漪,深刻印证了“质量大于数量”这一铁律。军事领域,技术优势就是决定胜负的关键钥匙。歼10C凭借先进的航电系统、强大的武器挂载能力以及卓越的机动性能,在战场上大放异彩。它能够精准捕捉目标,迅速发动攻击,以一敌多却毫不逊色。与之形成鲜明对比的是,单纯依靠数量堆砌的军事力量,在面对先进技术装备时,往往显得力不从心。这一现象绝非局限于军事范畴,在当今社会的各个领域,“质量大于数量”都已成为不可逆转的趋势。在科技行业
    curton 2025-05-11 19:09 211浏览
  • 体积大小:14*11*2.6CM,电气参数:输入100V-240V/10A,输出16V24A。PCB 正面如下图。PCB 背面如下图。根据实际功能可以将PCB分成几部分:EMI滤波,PFC电路,LLC电路。EMI滤波区域,两级共模电感,LN各用了保险丝加压敏电阻,继电器(HF32FV-G)用来切除NTC的,为了提高效率点,如下图。PFC电路区域,如下图。LLC电路区域,如下图。详细分析一下该电源用的主要IC还有功率器件。AC侧采用了两颗整流桥进行并联,器件增加电流应力,如下图。共模电感都有放电针
    liweicheng 2025-05-10 20:03 141浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦