移植micropython到MCU-新增pyb-LED模块

原创 嵌入式Lee 2024-12-19 08:03

工程源码

通过网盘分享的文件:fr30xxc_sdk__202411(1).zip

链接: https://pan.baidu.com/s/1XyNkwqjrxEVSexzCbyYooQ?pwd=tmri 提取码: tmri 

--来自百度网盘超级会员v3的分享


一. 前言

前面我们分享了micropython的移植,至此还只有一些内置的模块,我们现在开始就来移植平台相关的模块,先以最简单IO驱动LED为例。

以下是前文一些补充

修改输出不对齐问题

遇到\n输出为\r\n

这样原来只有\n换行的地方,可以回车到行首再换行就会对齐了。

uint32_t uart_send(uint8_t* buffer, uint32_t len){    g_data_transmit_flag = false;    for(uint32_t i=0;i<len;i++)    {      if(buffer[i]=='\n'){        putchar('\r');      }      putchar(buffer[i]);    }    return len;}

大数据支持

mpconfigport.h中配置

#define MICROPY_LONGINT_IMPL MICROPY_LONGINT_IMPL_MPZ

原来1<<32不支持

现在1<<32可以正常输出,甚至1<<160都可以

支持复数

mpconfigport.h中配置

#define MICROPY_PY_BUILTINS_COMPLEX (1)


查看math支持的运算

import math

math.tab按键

配置

#define MICROPY_PY_MATH (1)

#define MICROPY_PY_CMATH (1)

#define MICROPY_PY_BUILTINS_FLOAT (1)

#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_DOUBLE)

genhdr\moduledefs.h中可以看到注册了math模块。

#define MICROPY_REGISTERED_MODULES \

MODULE_DEF_BUILTINS \

MODULE_DEF_CMATH \

MODULE_DEF_GC \

MODULE_DEF_MATH \

MODULE_DEF_MICROPYTHON \

MODULE_DEF_SYS \

MODULE_DEF___MAIN__ \

extern const struct _mp_obj_module_t mp_module_math;

#undef MODULE_DEF_MATH

#define MODULE_DEF_MATH { MP_ROM_QSTR(MP_QSTR_math), MP_ROM_PTR(&mp_module_math) },

mp_module_math

py\modmath.c中实现

一. 关键词hash值计算

前文我们看到需要genhdr下自动生成的头文件,之前是通过从其他已经构建的地方复制过来的。其中genhdr/qstrdefs.generated.h定义了关键词对应的hash值,通过hash值来快速索引关键词,这个文件是通过python脚本生成的,对于支持的构建环境是自动调用脚本生成。而我们移植到MDK目前还没去添加对应的脚本(MDK也是可以配置执行脚本的,后面可以再完善),我们这一小节就来介绍下在新增关键词后如何手动更新该文件。

参考docs\develop\qstr.rst

从支持的构建环境的构建过程可以看到它是通过脚本命令生成的,参考

ports\windows\msvc\genhdr.targets可以看到其具体生成过程

其中如下位置指定文件qstrdefscollected.h

 <QstrDefsCollected>$(DestDir)qstrdefscollected.hQstrDefsCollected>

该文件由以下命令产生

 <Exec Command="$(PyPython) $(PySrcDir)makeqstrdefs.py split qstr $(DestDir)qstr.i.last $(DestDir)qstr _"/>

 <Exec Command="$(PyPython) $(PySrcDir)makeqstrdefs.py cat qstr _ $(DestDir)qstr $(QstrDefsCollected)"/>

对应

python makeqstrdefs.py split qstr genhdr/qstr.i.lastgenhdr/qstr _

makeqstrdefs.py使用格式如下usage: makeqstrdefs.py command mode input_filename output_dir output_file

即将genhdr/qstr.i.last文件生成到qstr下,使用split命令qstr模式。

qstr.i.last先使用基础版本,最后再手动添加新内容。

python makeqstrdefs.py cat qstr _ genhdr/qstr genhdr/qstrdefscollected.h

 <Exec Command="$(PyClTool) /nologo /I@(PyIncDirs, ' /I') /D@(PreProcDefs, ' /D') /E $(PyQstrDefs) $(QstrDefs) > $(DestDir)qstrdefs.preprocessed.h"/>

 

 <Exec Command="type $(QstrDefsCollected) >> $(DestDir)qstrdefs.preprocessed.h"/>

 <Exec Command="$(PyPython) $(PySrcDir)makeqstrdata.py $(DestDir)qstrdefs.preprocessed.h > $(TmpFile)"/>

对应

type genhdr/qstrdefscollected.h >> genhdr/qstrdefs.preprocessed.h

python makeqstrdata.py genhdr/qstrdefs.preprocessed.h > genhdr/qstrdefs.generated.h

前面原始输入文件是genhdr\qstr.i.last该文件由编译器产生,格式类似于

(# n "file") GCC产生的

(#line n "file") MSVC产生的

那么如何产生这个文件呢,qstr.i.last由编译器的预处理器产生,

if等条件编译删除,宏展开,添加行信息

需要添加-DNO_QSTR编译选项

py\mkrules.mkqstr.i.last

如下命令生成

$(HEADER_BUILD)/qstr.i.last:$(SRC_QSTR) $(QSTR_GLOBAL_DEPENDENCIES) |$(QSTR_GLOBAL_REQUIREMENTS)

 $(ECHO) "GEN$@"

 $(Q)$(PYTHON) $(PY_SRC)/makeqstrdefs.py pp$(CPP) output$(HEADER_BUILD)/qstr.i.last cflags$(QSTR_GEN_CFLAGS) cxxflags$(QSTR_GEN_CXXFLAGS) sources$^ dependencies$(QSTR_GLOBAL_DEPENDENCIES) changed_sources$?

我们无需从头开始,只需要修改原来的

genhdr\qstrdefs.preprocessed.h添加

新的字符串


然后执行python makeqstrdata.py genhdr/qstrdefs.preprocessed.h > genhdr/qstrdefs.generated.h生成即可。

整个过程如下,我们手动修改qstrdefs.preprocessed.h执行最后一步生成genhdr/qstrdefs.generated.h

.添加LED模块

我们参考参考已有的示例去做,参考

ports\stm32\modpyb.c

ports\stm32\led.h

ports\stm32\led.c

Io控制驱动

这一部分和具体的硬件平台相关,我们这里由两个LED


先实现LED控制IO的初始化

app_micropython.c

#include "fr30xx.h"#include "FreeRTOS.h"#include "task.h"#include "app_micropython.h"TaskHandle_t micropython_task_handle;extern int py_main(int argc, char **argv);static void micropython_task(void *arg);static void led_init(void){  GPIO_InitTypeDef gpio_config;  __SYSTEM_GPIOD_CLK_ENABLE();  gpio_config.Pin = GPIO_PIN_14 | GPIO_PIN_15;  gpio_config.Mode = GPIO_MODE_OUTPUT_PP;  gpio_config.Pull = GPIO_PULLUP;  gpio_config.Alternate = GPIO_FUNCTION_0;  gpio_init(GPIOD, &gpio_config);}void app_micropython_init(void){    xTaskCreate(micropython_task, "micropython"2048*2NULL3, µpython_task_handle);}static void micropython_task(void *arg){   led_init();   py_main(0,0);}

然后实现LED的控制接口

py_port\mphalport.c

#include "py/runtime.h"#include "py/mphal.h"#include "mphalport.h"#include "fr30xx.h"void mp_hal_pin_low(mp_uint_t id){  if(id==1)  {    gpio_write_pin(GPIOD,GPIO_PIN_14,GPIO_PIN_CLEAR);  }  else if(id == 2)  {    gpio_write_pin(GPIOD,GPIO_PIN_15,GPIO_PIN_CLEAR);  }  else  {    }}void mp_hal_pin_high(mp_uint_t id){  if(id==1)  {    gpio_write_pin(GPIOD,GPIO_PIN_14,GPIO_PIN_SET);  }  else if(id == 2)  {    gpio_write_pin(GPIOD,GPIO_PIN_15,GPIO_PIN_SET);  }  else  {    }}void mp_hal_pin_toogle(mp_uint_t id){  if(id==1)  {    if(gpio_read_pin(GPIOD,GPIO_PIN_14))    {       gpio_write_pin(GPIOD,GPIO_PIN_14,GPIO_PIN_SET);    }    else    {       gpio_write_pin(GPIOD,GPIO_PIN_14,GPIO_PIN_CLEAR);    }  }  else if(id == 2)  {    if(gpio_read_pin(GPIOD,GPIO_PIN_15))    {       gpio_write_pin(GPIOD,GPIO_PIN_14,GPIO_PIN_SET);    }    else    {       gpio_write_pin(GPIOD,GPIO_PIN_15,GPIO_PIN_CLEAR);    }  }  else  {    }}

py_port\mphalport.h

#ifndef MICROPY_MPHALPORT_H#define MICROPY_MPHALPORT_Hstatic inline mp_uint_t mp_hal_ticks_ms(void) {    return 0;}static inline void mp_hal_set_interrupt_char(char c) {}void mp_hal_pin_low(mp_uint_t id);void mp_hal_pin_high(mp_uint_t id);void mp_hal_pin_toogle(mp_uint_t id);#endif 

Led实例

构建实例

static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_on_obj, led_obj_on);static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_off_obj, led_obj_off);static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_toggle_obj, led_obj_toggle);static const mp_rom_map_elem_t led_locals_dict_table[] = {    { MP_ROM_QSTR(MP_QSTR_on), MP_ROM_PTR(&led_obj_on_obj) },    { MP_ROM_QSTR(MP_QSTR_off), MP_ROM_PTR(&led_obj_off_obj) },    { MP_ROM_QSTR(MP_QSTR_toggle), MP_ROM_PTR(&led_obj_toggle_obj) },};static MP_DEFINE_CONST_DICT(led_locals_dict, led_locals_dict_table);MP_DEFINE_CONST_OBJ_TYPE(    pyb_led_type,    MP_QSTR_LED,    MP_TYPE_FLAG_NONE,    make_new, led_obj_make_new,    print, led_obj_print,    locals_dict, &led_locals_dict);

led.c

#include #include "py/runtime.h"#include "py/mphal.h"#include "led.h"/// \moduleref pyb/// \class LED - LED object////// The LED object controls an individual LED (Light Emitting Diode).// the default is that LEDs are not inverted, and pin driven high turns them on#ifndef MICROPY_HW_LED_INVERTED#define MICROPY_HW_LED_INVERTED (0)#endiftypedef struct _pyb_led_obj_t {    mp_obj_base_t base;    mp_uint_t led_id;} pyb_led_obj_t;static const pyb_led_obj_t pyb_led_obj[] = {    {{&pyb_led_type}, 1},    {{&pyb_led_type}, 2},    {{&pyb_led_type}, 3},    {{&pyb_led_type}, 4},};#define NUM_LEDS MP_ARRAY_SIZE(pyb_led_obj)void led_init(void) {    /* Turn off LEDs and initialize */    for (int led = 0; led < NUM_LEDS; led++) {    }}void led_state(pyb_led_t led, int state) {    if (led < 1 || led > NUM_LEDS) {        return;    }    mp_uint_t led_id = pyb_led_obj[led].led_id-1;    if (state == 0) {        // turn LED off        mp_hal_pin_low(led_id);    } else {        // turn LED on        mp_hal_pin_high(led_id);    }}void led_toggle(pyb_led_t led) {    if (led < 1 || led > NUM_LEDS) {        return;    }    mp_uint_t led_id = pyb_led_obj[led].led_id-1;    // toggle the output data register to toggle the LED state    mp_hal_pin_toogle(led_id);}void led_set_intensity(pyb_led_t led, mp_int_t intensity) {    // intensity not supported for this LED; just turn it on/off    led_state(led, intensity > 0);}void led_debug(int n, int delay) {    led_state(1, n & 1);    led_state(2, n & 2);    led_state(3, n & 4);    led_state(4, n & 8);    //mp_hal_delay_ms(delay);}/******************************************************************************//* MicroPython bindings                                                       */void led_obj_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {    pyb_led_obj_t *self = MP_OBJ_TO_PTR(self_in);    mp_printf(print, "LED(%u)", self->led_id);}/// \classmethod \constructor(id)/// Create an LED object associated with the given LED://////   - `id` is the LED number, 1-4.static mp_obj_t led_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {    // check arguments    mp_arg_check_num(n_args, n_kw, 1, 1, false);    // get led number    mp_int_t led_id = mp_obj_get_int(args[0]);    // check led number    if (!(1 <= led_id && led_id <= NUM_LEDS)) {        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("LED(%d) doesn't exist"), led_id);    }    // return static led object    return MP_OBJ_FROM_PTR(&pyb_led_obj[led_id - 1]);}/// \method on()/// Turn the LED on.mp_obj_t led_obj_on(mp_obj_t self_in) {    pyb_led_obj_t *self = MP_OBJ_TO_PTR(self_in);    led_state(self->led_id, 1);    return mp_const_none;}/// \method off()/// Turn the LED off.mp_obj_t led_obj_off(mp_obj_t self_in) {    pyb_led_obj_t *self = MP_OBJ_TO_PTR(self_in);    led_state(self->led_id, 0);    return mp_const_none;}/// \method toggle()/// Toggle the LED between on and off.mp_obj_t led_obj_toggle(mp_obj_t self_in) {    pyb_led_obj_t *self = MP_OBJ_TO_PTR(self_in);    led_toggle(self->led_id);    return mp_const_none;}static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_on_obj, led_obj_on);static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_off_obj, led_obj_off);static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_toggle_obj, led_obj_toggle);static const mp_rom_map_elem_t led_locals_dict_table[] = {    { MP_ROM_QSTR(MP_QSTR_on), MP_ROM_PTR(&led_obj_on_obj) },    { MP_ROM_QSTR(MP_QSTR_off), MP_ROM_PTR(&led_obj_off_obj) },    { MP_ROM_QSTR(MP_QSTR_toggle), MP_ROM_PTR(&led_obj_toggle_obj) },};static MP_DEFINE_CONST_DICT(led_locals_dict, led_locals_dict_table);MP_DEFINE_CONST_OBJ_TYPE(    pyb_led_type,    MP_QSTR_LED,    MP_TYPE_FLAG_NONE,    make_new, led_obj_make_new,    print, led_obj_print,    locals_dict, &led_locals_dict    );

Led.h

#ifndef MICROPY_INCLUDED_XX_LED_H#define MICROPY_INCLUDED_XX_LED_Htypedef enum {    PYB_LED_RED = 1,    PYB_LED_GREEN = 2,    PYB_LED_YELLOW = 3,    PYB_LED_BLUE = 4,} pyb_led_t;void led_init(void);void led_state(pyb_led_t led, int state);void led_toggle(pyb_led_t led);void led_debug(int value, int delay);extern const mp_obj_type_t pyb_led_type;#endif 

注册pyb模块,绑定LED实例

py_port\modpyb.c中,绑定led实例pyb_led_typepyb模块

#include #include #include "py/runtime.h"#include "py/mphal.h"#include "shared/runtime/pyexec.h"#include "led.h"//#include "portmodules.h"//#include "modmachine.h"//#include "extmod/modmachine.h"//#include "extmod/modnetwork.h"//#include "extmod/vfs.h"//#include "extmod/modtime.h"MP_DECLARE_CONST_FUN_OBJ_KW(pyb_main_obj); // defined in main.c// Provide a no-op version of pyb.country for backwards compatibility on// boards that don't support networking.static mp_obj_t pyb_country(size_t n_args, const mp_obj_t *args) {    (void)n_args;    (void)args;    return mp_const_none;}static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_network_country_obj, 0, 1, pyb_country);static const mp_rom_map_elem_t pyb_module_globals_table[] = {    { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_pyb) },    { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pyb_led_type) },};static MP_DEFINE_CONST_DICT(pyb_module_globals, pyb_module_globals_table);const mp_obj_module_t pyb_module = {    .base = { &mp_type_module },    .globals = (mp_obj_dict_t *)&pyb_module_globals,};MP_REGISTER_MODULE(MP_QSTR_pyb, pyb_module);

py\genhdr\moduledefs.h中注册pyb模块

extern const struct _mp_obj_module_t pyb_module;#undef PYB_BUILTIN_MODULE_CONSTANTS#define PYB_BUILTIN_MODULE_CONSTANTS \    { MP_ROM_QSTR(MP_QSTR_pyb), MP_ROM_PTR(&pyb_module) },#define MICROPY_REGISTERED_MODULES \    MODULE_DEF_BUILTINS \    MODULE_DEF_CMATH \    MODULE_DEF_GC \    MODULE_DEF_MATH \    MODULE_DEF_MICROPYTHON \    MODULE_DEF_SYS \    MODULE_DEF___MAIN__ \    PYB_BUILTIN_MODULE_CONSTANTS// MICROPY_REGISTERED_MODULES

.测试

见视频

https://mp.weixin.qq.com/s/JdFb3x7KOag114Fb72URGA?token=1312261758&lang=zh_CN

import pyb

led1 = pyb.LED(1)

led2 = pyb.LED(2)

led1.on()

led2.on()

led1.off()

led2.off()

led1.toggle()

led2.toggle()

五. 总结

可以看到micropython新增模块支持比较简单,只需要按照模板注册模块,绑定对应的驱动即可。后续就可以不断添加新的模块支持使更具备实用性。








评论 (0)
  • 北京贞光科技有限公司作为紫光同芯授权代理商,专注于为客户提供车规级安全芯片的硬件供应与软件SDK一站式解决方案,同时配备专业技术团队,为选型及定制需求提供现场指导与支持。随着新能源汽车渗透率突破40%(中汽协2024数据),智能驾驶向L3+快速演进,车规级MCU正迎来技术范式变革。作为汽车电子系统的"神经中枢",通过AEC-Q100 Grade 1认证的MCU芯片需在-40℃~150℃极端温度下保持μs级响应精度,同时满足ISO 26262 ASIL-D功能安全要求。在集中式
    贞光科技 2025-04-02 14:50 218浏览
  • 探针本身不需要对焦。探针的工作原理是通过接触被测物体表面来传递电信号,其精度和使用效果取决于探针的材质、形状以及与检测设备的匹配度,而非对焦操作。一、探针的工作原理探针是检测设备中的重要部件,常用于电子显微镜、坐标测量机等精密仪器中。其工作原理主要是通过接触被测物体的表面,将接触点的位置信息或电信号传递给检测设备,从而实现对物体表面形貌、尺寸或电性能等参数的测量。在这个过程中,探针的精度和稳定性对测量结果具有至关重要的影响。二、探针的操作要求在使用探针进行测量时,需要确保探针与被测物体表面的良好
    锦正茂科技 2025-04-02 10:41 112浏览
  • 文/郭楚妤编辑/cc孙聪颖‍不久前,中国发展高层论坛 2025 年年会(CDF)刚刚落下帷幕。本次年会围绕 “全面释放发展动能,共促全球经济稳定增长” 这一主题,吸引了全球各界目光,众多重磅嘉宾的出席与发言成为舆论焦点。其中,韩国三星集团会长李在镕时隔两年的访华之行,更是引发广泛热议。一直以来,李在镕给外界的印象是不苟言笑。然而,在论坛开幕前一天,李在镕却意外打破固有形象。3 月 22 日,李在镕与高通公司总裁安蒙一同现身北京小米汽车工厂。小米方面极为重视此次会面,CEO 雷军亲自接待,小米副董
    华尔街科技眼 2025-04-01 19:39 245浏览
  • 引言随着物联网和智能设备的快速发展,语音交互技术逐渐成为提升用户体验的核心功能之一。在此背景下,WT588E02B-8S语音芯片,凭借其创新的远程更新(OTA)功能、灵活定制能力及高集成度设计,成为智能设备语音方案的优选。本文将从技术特性、远程更新机制及典型应用场景三方面,解析该芯片的技术优势与实际应用价值。一、WT588E02B-8S语音芯片的核心技术特性高性能硬件架构WT588E02B-8S采用16位DSP内核,内部振荡频率达32MHz,支持16位PWM/DAC输出,可直接驱动8Ω/0.5W
    广州唯创电子 2025-04-01 08:38 179浏览
  • 据先科电子官方信息,其产品包装标签将于2024年5月1日进行全面升级。作为电子元器件行业资讯平台,大鱼芯城为您梳理本次变更的核心内容及影响:一、标签变更核心要点标签整合与环保优化变更前:卷盘、内盒及外箱需分别粘贴2张标签(含独立环保标识)。变更后:环保标识(RoHS/HAF/PbF)整合至单张标签,减少重复贴标流程。标签尺寸调整卷盘/内盒标签:尺寸由5030mm升级至**8040mm**,信息展示更清晰。外箱标签:尺寸统一为8040mm(原7040mm),提升一致性。关键信息新增新增LOT批次编
    大鱼芯城 2025-04-01 15:02 225浏览
  • 退火炉,作为热处理设备的一种,广泛应用于各种金属材料的退火处理。那么,退火炉究竟是干嘛用的呢?一、退火炉的主要用途退火炉主要用于金属材料(如钢、铁、铜等)的热处理,通过退火工艺改善材料的机械性能,消除内应力和组织缺陷,提高材料的塑性和韧性。退火过程中,材料被加热到一定温度后保持一段时间,然后以适当的速度冷却,以达到改善材料性能的目的。二、退火炉的工作原理退火炉通过电热元件(如电阻丝、硅碳棒等)或燃气燃烧器加热炉膛,使炉内温度达到所需的退火温度。在退火过程中,炉内的温度、加热速度和冷却速度都可以根
    锦正茂科技 2025-04-02 10:13 104浏览
  • 随着汽车向智能化、场景化加速演进,智能座舱已成为人车交互的核心承载。从驾驶员注意力监测到儿童遗留检测,从乘员识别到安全带状态判断,座舱内的每一次行为都蕴含着巨大的安全与体验价值。然而,这些感知系统要在多样驾驶行为、复杂座舱布局和极端光照条件下持续稳定运行,传统的真实数据采集方式已难以支撑其开发迭代需求。智能座舱的技术演进,正由“采集驱动”转向“仿真驱动”。一、智能座舱仿真的挑战与突破图1:座舱实例图智能座舱中的AI系统,不仅需要理解驾驶员的行为和状态,还要同时感知乘员、儿童、宠物乃至环境中的潜在
    康谋 2025-04-02 10:23 181浏览
  • 职场之路并非一帆风顺,从初入职场的新人成长为团队中不可或缺的骨干,背后需要经历一系列内在的蜕变。许多人误以为只需努力工作便能顺利晋升,其实核心在于思维方式的更新。走出舒适区、打破旧有框架,正是让自己与众不同的重要法宝。在这条道路上,你不只需要扎实的技能,更需要敏锐的观察力、不断自省的精神和前瞻的格局。今天,就来聊聊那改变命运的三大思维转变,让你在职场上稳步前行。工作初期,总会遇到各式各样的难题。最初,我们习惯于围绕手头任务来制定计划,专注于眼前的目标。然而,职场的竞争从来不是单打独斗,而是团队协
    优思学院 2025-04-01 17:29 241浏览
  • 引言在语音芯片设计中,输出电路的设计直接影响音频质量与系统稳定性。WT588系列语音芯片(如WT588F02B、WT588F02A/04A/08A等),因其高集成度与灵活性被广泛应用于智能设备。然而,不同型号在硬件设计上存在关键差异,尤其是DAC加功放输出电路的配置要求。本文将从硬件架构、电路设计要点及选型建议三方面,解析WT588F02B与F02A/04A/08A的核心区别,帮助开发者高效完成产品设计。一、核心硬件差异对比WT588F02B与F02A/04A/08A系列芯片均支持PWM直推喇叭
    广州唯创电子 2025-04-01 08:53 224浏览
  • 文/Leon编辑/cc孙聪颖‍步入 2025 年,国家进一步加大促消费、扩内需的政策力度,家电国补政策将持续贯穿全年。这一利好举措,为行业发展注入强劲的增长动力。(详情见:2025:消费提振要靠国补还是“看不见的手”?)但与此同时,也对家电企业在战略规划、产品打造以及市场营销等多个维度,提出了更为严苛的要求。在刚刚落幕的中国家电及消费电子博览会(AWE)上,家电行业的竞争呈现出胶着的态势,各大品牌为在激烈的市场竞争中脱颖而出,纷纷加大产品研发投入,积极推出新产品,试图提升产品附加值与市场竞争力。
    华尔街科技眼 2025-04-01 19:49 239浏览
  • 提到“质量”这两个字,我们不会忘记那些奠定基础的大师们:休哈特、戴明、朱兰、克劳士比、费根堡姆、石川馨、田口玄一……正是他们的思想和实践,构筑了现代质量管理的核心体系,也深远影响了无数企业和管理者。今天,就让我们一同致敬这些质量管理的先驱!(最近流行『吉卜力风格』AI插图,我们也来玩玩用『吉卜力风格』重绘质量大师画象)1. 休哈特:统计质量控制的奠基者沃尔特·A·休哈特,美国工程师、统计学家,被誉为“统计质量控制之父”。1924年,他提出世界上第一张控制图,并于1931年出版《产品制造质量的经济
    优思学院 2025-04-01 14:02 159浏览
  • 在智能交互设备快速发展的今天,语音芯片作为人机交互的核心组件,其性能直接影响用户体验与产品竞争力。WT588F02B-8S语音芯片,凭借其静态功耗<5μA的卓越低功耗特性,成为物联网、智能家居、工业自动化等领域的理想选择,为设备赋予“听得懂、说得清”的智能化能力。一、核心优势:低功耗与高性能的完美结合超低待机功耗WT588F02B-8S在休眠模式下待机电流仅为5μA以下,显著延长了电池供电设备的续航能力。例如,在电子锁、气体检测仪等需长期待机的场景中,用户无需频繁更换电池,降低了维护成本。灵活的
    广州唯创电子 2025-04-02 08:34 175浏览
我要评论
0
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦