移植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新增模块支持比较简单,只需要按照模板注册模块,绑定对应的驱动即可。后续就可以不断添加新的模块支持使更具备实用性。








评论
  • 80,000人到访的国际大展上,艾迈斯欧司朗有哪些亮点?感未来,光无限。近日,在慕尼黑electronica 2024现场,ams OSRAM通过多款创新DEMO展示,以及数场前瞻洞察分享,全面展示自身融合传感器、发射器及集成电路技术,精准捕捉并呈现环境信息的卓越能力。同时,ams OSRAM通过展会期间与客户、用户等行业人士,以及媒体朋友的深度交流,向业界传达其以光电技术为笔、以创新为墨,书写智能未来的深度思考。electronica 2024electronica 2024构建了一个高度国际
    艾迈斯欧司朗 2025-01-16 20:45 146浏览
  • 实用性高值得收藏!! (时源芯微)时源专注于EMC整改与服务,配备完整器件 TVS全称Transient Voltage Suppre,亦称TVS管、瞬态抑制二极管等,有单向和双向之分。单向TVS 一般应用于直流供电电路,双向TVS 应用于电压交变的电路。在直流电路的应用中,TVS被并联接入电路中。在电路处于正常运行状态时,TVS会保持截止状态,从而不对电路的正常工作产生任何影响。然而,一旦电路中出现异常的过电压,并且这个电压达到TVS的击穿阈值时,TVS的状态就会
    时源芯微 2025-01-16 14:23 152浏览
  • 随着消费者对汽车驾乘体验的要求不断攀升,汽车照明系统作为确保道路安全、提升驾驶体验以及实现车辆与环境交互的重要组成,日益受到业界的高度重视。近日,2024 DVN(上海)国际汽车照明研讨会圆满落幕。作为照明与传感创新的全球领导者,艾迈斯欧司朗受邀参与主题演讲,并现场展示了其多项前沿技术。本届研讨会汇聚来自全球各地400余名汽车、照明、光源及Tier 2供应商的专业人士及专家共聚一堂。在研讨会第一环节中,艾迈斯欧司朗系统解决方案工程副总裁 Joachim Reill以深厚的专业素养,主持该环节多位
    艾迈斯欧司朗 2025-01-16 20:51 109浏览
  • 晶台光耦KL817和KL3053在小家电产品(如微波炉等)辅助电源中的广泛应用。具备小功率、高性能、高度集成以及低待机功耗的特点,同时支持宽输入电压范围。▲光耦在实物应用中的产品图其一次侧集成了交流电压过零检测与信号输出功能,该功能产生的过零信号可用于精确控制继电器、可控硅等器件的过零开关动作,从而有效减小开关应力,显著提升器件的使用寿命。通过高度的集成化和先进的控制技术,该电源大幅减少了所需的外围器件数量,不仅降低了系统成本和体积,还进一步增强了整体的可靠性。▲电路示意图该电路的过零检测信号由
    晶台光耦 2025-01-16 10:12 97浏览
  • 一个易用且轻量化的UI可以大大提高用户的使用效率和满意度——通过快速启动、直观操作和及时反馈,帮助用户快速上手并高效完成任务;轻量化设计则可以减少资源占用,提升启动和运行速度,增强产品竞争力。LVGL(Light and Versatile Graphics Library)是一个免费开源的图形库,专为嵌入式系统设计。它以轻量级、高效和易于使用而著称,支持多种屏幕分辨率和硬件配置,并提供了丰富的GUI组件,能够帮助开发者轻松构建出美观且功能强大的用户界面。近期,飞凌嵌入式为基于NXP i.MX9
    飞凌嵌入式 2025-01-16 13:15 199浏览
  • 近期,智能家居领域Matter标准的制定者,全球最具影响力的科技联盟之一,连接标准联盟(Connectivity Standards Alliance,简称CSA)“利好”频出,不仅为智能家居领域的设备制造商们提供了更为快速便捷的Matter认证流程,而且苹果、三星与谷歌等智能家居平台厂商都表示会接纳CSA的Matter认证体系,并计划将其整合至各自的“Works with”项目中。那么,在本轮“利好”背景下,智能家居的设备制造商们该如何捉住机会,“掘金”万亿市场呢?重认证快通道计划,为家居设备
    华普微HOPERF 2025-01-16 10:22 176浏览
  • 随着智慧科技的快速发展,智能显示器的生态圈应用变得越来越丰富多元,智能显示器不仅仅是传统的显示设备,透过结合人工智能(AI)和语音助理,它还可以成为家庭、办公室和商业环境中的核心互动接口。提供多元且个性化的服务,如智能家居控制、影音串流拨放、实时信息显示等,极大提升了使用体验。此外,智能家居系统的整合能力也不容小觑,透过智能装置之间的无缝连接,形成了强大的多元应用生态圈。企业也利用智能显示器进行会议展示和多方远程合作,大大提高效率和互动性。Smart Display Ecosystem示意图,作
    百佳泰测试实验室 2025-01-16 15:37 172浏览
  • 百佳泰特为您整理2025年1月各大Logo的最新规格信息,本月有更新信息的logo有HDMI、Wi-Fi、Bluetooth、DisplayHDR、ClearMR、Intel EVO。HDMI®▶ 2025年1月6日,HDMI Forum, Inc. 宣布即将发布HDMI规范2.2版本。新规范将支持更高的分辨率和刷新率,并提供更多高质量选项。更快的96Gbps 带宽可满足数据密集型沉浸式和虚拟应用对传输的要求,如 AR/VR/MR、空间现实和光场显示,以及各种商业应用,如大型数字标牌、医疗成像和
    百佳泰测试实验室 2025-01-16 15:41 157浏览
  • 全球领先的光学解决方案供应商艾迈斯欧司朗(SIX:AMS)近日宣布,与汽车技术领先者法雷奥合作,采用创新的开放系统协议(OSP)技术,旨在改变汽车内饰照明方式,革新汽车行业座舱照明理念。结合艾迈斯欧司朗开创性的OSIRE® E3731i智能LED和法雷奥的动态环境照明系统,两家公司将为车辆内饰设计和功能设立一套全新标准。汽车内饰照明的作用日益凸显,座舱设计的主流趋势应满足终端用户的需求:即易于使用、个性化,并能提供符合用户生活方式的清晰信息。因此,动态环境照明带来了众多新机遇。智能LED的应用已
    艾迈斯欧司朗 2025-01-15 19:00 78浏览
  • 数字隔离芯片是现代电气工程师在进行电路设计时所必须考虑的一种电子元件,主要用于保护低压控制电路中敏感电子设备的稳定运行与操作人员的人身安全。其不仅能隔离两个或多个高低压回路之间的电气联系,还能防止漏电流、共模噪声与浪涌等干扰信号的传播,有效增强电路间信号传输的抗干扰能力,同时提升电子系统的电磁兼容性与通信稳定性。容耦隔离芯片的典型应用原理图值得一提的是,在电子电路中引入隔离措施会带来传输延迟、功耗增加、成本增加与尺寸增加等问题,而数字隔离芯片的目标就是尽可能消除这些不利影响,同时满足安全法规的要
    华普微HOPERF 2025-01-15 09:48 184浏览
  • 电竞鼠标应用环境与客户需求电竞行业近年来发展迅速,「鼠标延迟」已成为决定游戏体验与比赛结果的关键因素。从技术角度来看,传统鼠标的延迟大约为20毫秒,入门级电竞鼠标通常为5毫秒,而高阶电竞鼠标的延迟可降低至仅2毫秒。这些差异看似微小,但在竞技激烈的游戏中,尤其在对反应和速度要求极高的场景中,每一毫秒的优化都可能带来致胜的优势。电竞比赛的普及促使玩家更加渴望降低鼠标延迟以提升竞技表现。他们希望通过精确的测试,了解不同操作系统与设定对延迟的具体影响,并寻求最佳配置方案来获得竞技优势。这样的需求推动市场
    百佳泰测试实验室 2025-01-16 15:45 238浏览
  • 日前,商务部等部门办公厅印发《手机、平板、智能手表(手环)购新补贴实施方案》明确,个人消费者购买手机、平板、智能手表(手环)3类数码产品(单件销售价格不超过6000元),可享受购新补贴。每人每类可补贴1件,每件补贴比例为减去生产、流通环节及移动运营商所有优惠后最终销售价格的15%,每件最高不超过500元。目前,京东已经做好了承接手机、平板等数码产品国补优惠的落地准备工作,未来随着各省市关于手机、平板等品类的国补开启,京东将第一时间率先上线,满足消费者的换新升级需求。为保障国补的真实有效发放,基于
    华尔街科技眼 2025-01-17 10:44 129浏览
  • 故障现象 一辆2007款法拉利599 GTB车,搭载6.0 L V12自然吸气发动机(图1),累计行驶里程约为6万km。该车因发动机故障灯异常点亮进厂检修。 图1 发动机的布置 故障诊断接车后试车,发动机怠速轻微抖动,发动机故障灯长亮。用故障检测仪检测,发现发动机控制单元(NCM)中存储有故障代码“P0300 多缸失火”“P0309 气缸9失火”“P0307 气缸7失火”,初步判断发动机存在失火故障。考虑到该车使用年数较长,决定先使用虹科Pico汽车示波器进行相对压缩测试,以
    虹科Pico汽车示波器 2025-01-15 17:30 95浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦