发动态
综合 最新发布 最新回复
图文
列表
今天终于安安静静的坐下来分享一些东西,根据今年的一些规划和目标,应该是非常忙的一年,再加上疫情的反复、各大厂的裁员、还有目前国际大环境等等都多多少少影响着我们的生活,跟一些同事和朋友的交流当中我也隐隐约约感受到大家的一丝焦虑和担忧。其实大可不必这样,一味担心一些未知东西或许仅仅只是一种自耗吧,还是要调整好心态。好了,今天谈论的话题是C语言中为何没法规避全局变量?为什么突然谈论这个话题,主要是最近有几个粉丝朋友问到了类似的问题。"bug菌,我代码中全局变量太多了,有没有一种方法不使用全局变量来编写C语言程序?"等等当时并没有感觉特别惊讶,因为曾经的我也是在这条道路上探索着,只是在C语言编程这条路上走得多一点,相对想得更加明白一点罢了。我的回答是:"没有办法规避全局变量的~"1、耦合其实自认为"没有办法规避全局变量的",这个答案相对而言并不是特别专业,却能够让更多的人听懂。在最开始使用C语言进行项目开发的过程中,都会提示要你用模块化思想来编程,怀着"低耦合,高内聚"的编程理念。但是你应该没有听说过模块之间无耦合吧,所以耦合和内聚都是相对而言,当采用了一种不是最优的设计思想和方法,便编写出了一套耦合度较高的代码罢了。而所谓的耦合便是你所划分的各功能模块代码之间的数据共享了。bug菌一直相信代码中的所有设计都可以在这世间找到类比原型,同样这世间规律也完全可以用程序来进行表达,只是目前的科技水平还并没有达到那么水平,或许人工智能就是一个萌芽吧。而在C语言中全局变量的使用,便是一种数据共享的方式,同样也是模块化沟通的桥梁。有朋友该说了,我不进行数据共享便不会使用全局变量了。比如点了个灯,同时又写了串口通信程序,两者并没有什么联系,各自安好,那确实没有数据共享,也可以不使用全局变量,最多认为你在静态存储区定义了几个变量吧。但这样的程序又能复杂到什么程度,或实现什么功能呢?基本没有特别大的意义。2、联系这世间原本就是千丝万缕羁绊着而存在,或许从蝴蝶效应看来就会颇有感触,那么编程中也是一样的,相互之间的存在着某种联系才愈发精彩,而这种联系的表达则少不了数据的共享。程序员们要用C语言来描述这世间种种规律,使用全局变量还逃得掉吗?即便有一种语言可以达到不使用类似于全局变量的语法形式,但数据的共享终究逃不了。虽话说回来,无法规避,但并非没有章法;不加约束,必将带来不少麻烦。3、面向对象面向对象的程序设计思想就是目前约束全局变量使用的一味良药,面向对象与面向过程都是一种思维方式的存在,并非孰优孰劣。但就目前软件设计的发展来看,面向对象的程序设计思想在大型程序的设计和把控上有更多的优势。它能够把各个抽象的个体描绘得更加的直观,这样个体之间的相互联系也就顺理成章的表达和约束。
C语言如何规避全局变量?不可能~
嘉立创PCB
在学校或者各种编程类书本上,基本上都会看到一句话:"函数是程序的基本组成单位",可以说理解函数对编程是非常重要的,与函数调用紧密结合的机制就是函数调用栈了,而栈有一个特别的属性就是栈的增长方向问题了,也发现一些多年编程经验的朋友对这一块都有点迷迷糊糊的。在阅读RTOS源码的时候也会经常看到栈的增长方向配置项目,那么今天bug菌就带大家了解一下栈的增长方向到底是咋回事。1、栈的增长方向首先我们要明确的是栈同样也是分布在我们的内存之中,而内存是通过地址来进行编排访问的,如下是堆栈的示意图:对于堆栈而言原本并没有方向一说,只有入栈和出栈一说,程序中执行push指令则栈顶向上移动,执行pop指令则栈顶向下移动,其仅仅只是一种先进后出的数据结构,增长方向都是从栈底向栈顶方向移动,即分配数据的过程。而我们平时所说的栈的增长方向又是怎么回事呢?为了在内存中分配一段内存给堆栈,我们必须要区分堆栈相对于内存的地址而言的方向性,通常栈顶增长的方向是从内存的低地址向高地址变化,我们则称为向上增长;反之则向下增长。所谓"水往高处流,即向上增长",这样应该就很好记忆了。2、有什么用?当了解处理器中栈指针的增长方向以后,我们在debug程序的时候才能真正的把控程序的运行过程。在移植RTOS的过程中我们都需要对每个任务的堆栈分配一个合适的连续内存区域来使用,此时初始状态堆栈指针指向什么位置就跟堆栈的增长方向密切相关,有过RTOS移植经验的朋友应该都有在RTOS配置项中关注过这块的选择。RTOS在任务初始化的时候,其堆栈指针应该指向其栈底位置,那么对于堆栈向上增长,任务初始化的时候我们需要把堆栈指针设置在所分配内存的低地址内存处,反之则设置到高地址处。设置好以后,其在堆栈分配的过程中才会朝着所分配的内存区域中,否则就会堆栈反向自爆,导致程序异常;如果你的堆栈分配不合理,同样了解堆栈变化方向后也变得有迹可循。同样在裸机程序中也需要了解一下处理器的堆栈变化方向,从而用来排查一些堆栈溢出所导致的程序异常问题。3、用C语言如何判断?要了解一个CPU的堆栈的变换方向,一方面就是查询相应的芯片参考手册,另外一方面就是实际测试了。毕竟堆栈也就是内存,自然就可以通过堆栈的分配过程取出所分配的内存地址来比较判断,而C语言可以方便的访问内存,也就比较容易判断当前处理器中堆栈指针的增长方向了。那还不简单,直接在函数内部先后定义两个局部变量,直接比较两个变量的地址大小不就搞定了吗?其实这种方式是依赖于编译器实现的,毕竟哪个变量先进行内存申请,并没有太大的影响。那么是否有一种方法不依赖于编译器实现呢?必须有的,那就是函数调用栈了,因为先调用的函数必然首先入栈。基于这样的思想,这里bug菌写一个判断堆栈增长方向的demo供大家参考: 1#include <stdio.h>2#include <stdlib.h> 3 4#define STACK_UP (0)5#define STACK_DN (1) 6 7/*************************************** 8@ Function: find_stack_direction 9@ Author  : bug man  10@ Note    : (公众号:最后一个bug) 11****************************************/ 12int find_stack_direction(int* ptr) 13{ 14    int  Val = 0; 15 16    printf("Last stack Addr : %p\n",ptr); 17    printf("Now  stack Addr : %p\n",&Val); 18 19    if(ptr > &Val) 20    { 21        return STACK_DN; 22    } 23 24    return STACK_UP; 25}  26/*************************************** 27@ Function: main 28@ Author  : bug man  29@ Note    : (公众号:最后一个bug) 30****************************************/ 31int main(int argc, char *argv[]) { 32    int  Val = 0; 33 34    printf("stack direction : %d\n",find_stack_direction(&Val)); 35    return 0; 36} 可以拿去试一试,看看你的芯片堆栈咋变化的~
栈的增长方向怎么理解?用C语言如何判断?
嘉立创PCB
pcb下单选项
家人们,今天准备用掉pcb彩色丝印卷,结果发现彩色丝印不能选择免费的客编或者二维码,只能啥也不加,这是为啥呀,工艺不支持嘛[疑问][疑问]
嘉立创PCB
老工程师总结的10条经验,太受益了~
1、你永远不可能什么都知道 2、好的团队可以让你的能力呈指数增长,而非线性增长 3、编写的代码应该便于阅读 4、耐心是你最好的朋友 5、持续性是关键 6、总是有比你优秀的人你可以向他学习 7、社交网络很重要 8、经常休息可以让你更高效 9、如果你希望在自己的职业生涯中更进一步,就需要有很好的人缘 10、大多数公司都不是你希望的样子
嘉立创PCB
【自制】超神奇的无线USB HUB!从此USB进入无线时代!
本项目的起因是要调试的嵌入式设备经常不在电脑旁边,搬来搬去的很不方便。所以萌生了想要实现把USB信号无线化的想法。项目主控使用全志H618,搭载linux操作系统,再运行一个VirtualHere软件,便可以实现USB信号完全无线化,再结合一些实用的USB HUB功能,从此USB设备将彻底摆脱束缚。
嘉立创PCB
嘉立创真是中国电子工程师的再生父母
嘉立创免费打板,EDA免费使用,3D打印免费打样,立创商城超级会员日每月一次下单立减,真是牛 #嘉立创PCB# #立创超级会员日#
嘉立创PCB
有没有什么办法增强焊盘的机械强度?
嘉立创PCB
趁着等快递的时间有完善了几个基础实用功能 1. (软件上的优化)16路实时逻辑分析仪 2. (软件上的优化)13路自定义函数发生器 3. (硬件上的优化)准备新开一块LVDS缓冲模块的板子 OwO...用原理图页写笔记这功能简直绝了
嘉立创PCB
相信大家对该通信的大部分基础理论知识已经了然如胸了,在开发过程中使用SPI通信问题应该不会太大,但SPI作为一种嵌入式工程师们如此青睐的通信方式,在开发中总会有人挖一些坑让你来填,当然这个人可能是自己。在定位这些问题的时候动不动就几天过去了,项目工程师又要来催了~那么今天bug菌根据以往的经验,将重点从通信的速度、容错性和结构这三个方面进一步谈谈SPI通信,也算是完结篇了。1、通信速度对于SPI通信并没有规范最高的通信速率,在我的开发经验中有见过达到50Mbit/s的应用场景,但通常比较常见的还是10Mbit/s左右。具体选用多快的通信速度,还得在实际项目中根据情况具体设计,比如:1、当前主从机的主频和项目的具体应用都与SPI数据的处理能力有着直接关系,一般SPI通信的时钟频率都是来源于主频分频,这就在一定程度上限制了其通信速率上限。即使能够达到较高速的速率,而处理器还需要处理更多的业务逻辑,再去处理SPI数据也是不够及时的,此时高速率并没有太大的意义了。2、SPI硬件PCB布线长度等等影响着线路阻抗,这也同样限制了通信速率,一般通信距离越长,通信速度越低,否则容易造成通信不稳定。特别是通信线路经过一些干扰源更是影响其稳定性,所以SPI作为一种相对高速的通信方式,一般都不会用于长距离通信中,而是大量用于微处理器与外部SPI接口的设备之间的通信,比如高速采样芯片ADC、处理器之间等等。3、前面说了即使SPI主机能够达到较高的通信速率,但从机主频或者数据处理能力不够,这样也是没有太大意义的,当你可以通过配置从机为接收队列或者DMA等方式进行优化,当然高速率在多机中能够减少同步延时。值得注意的是一些芯片标称的最高通信速率,是在比较好的外界条件下的测试值,超过了该标称值可能也能用,但并不会很稳定,容易导致通信异常。所以具体选用多快的通信速度,还需根据实际情况分析确认。2、容错性SPI不像IIC那样存在应答机制,也没有流控制机制,当从机配置较低,如果一个报文还没处理完,后一个报文又到来,导致传输错乱,其通信过程几乎都是靠硬件来保证数据的传输稳定性,是一种不可靠传输。当然如果是用于多机通信倒是可以通过制定可靠性校验协议来保证传输数据的稳定,但这也在一定程度上会降低通信的有效数据传输速度。像stm32的SPI外设发送和接收都存在独立的CRC校验功能,大致的原理就是使用CRC在每个位上进行串行计算,然后在最后一次数据传输结束时来传输CRC校验值,接受方接收到CRC以后自动拿着数据和CRC值进行比对,看是与否有数据故障,如果存在传输问题就会置位相应的CRC故障标志位告知。当然如果所选用的芯片SPI外设没有独立CRC模块可以模拟类似的操作进行处理,只是相对比较耗时,毕竟这个CRC得软件自己处理。stm32的SPI外设的灵活度远不止这些,比如配置成双线单向模式等,可以把MISO和MOSI都向一个方向传输,从而提高一倍的传输速度,感兴趣可以参考一下手册玩一下。3、通信模式SPI通信拓扑结构上的一大特色就是菊花链拓扑。上篇文章跟大家介绍的SPI一主多从的通信方式属于并行方式,要控制多个从机需要使用大量的GPIO信号来控制片选信号。似乎非常简约的SPI通信一下子变得不那么简单了,特别是布线方面是非常低效的,此时菊花链的通信方式便有了一席之地。菊花链模式下的SPI所有的片选和串联时钟信号都可以共用一条线,其数据以时钟节拍逐个bit的循环移动,从而完成数据传递,这样就大大减少了控制线路。当凡事总有其两面性,采用链式结构相对并联方式没有那么灵活,主机无法一次任意选中一个从机进行直接通信,而是得通过数据的循环传递。另外对于链式结构主从关系没有那么直接,相连接的从机之间存在着更多的依赖关系,一旦链路或者从机出现了问题,其影响是联锁的。菊花链的通信方式应用是非常多的,比如当我们在一块板上有多块控制芯片,但此时由于PCB大小的限制,可以选用菊花链的拓扑方式实现一个JTAG仿真器对多个JTAG芯片进行烧录和控制。
大话SPI通信--进阶避坑篇
嘉立创PCB
最近跟一个同事聊了聊天,他说一直用的位置式PID,从来没在具体项目中用过增量式PID,感觉两者没啥区别呀?于是跟他讨论了一番,不由得让人深思~1、“万能”的PIDPID是一种非常经典的控制类算法,凭着它的简单易用在工程上得到了广泛的应用,并且影响力也是极高,那为什么说其简单易用呢?可以说只要你对PID的主要的参数对系统的影响理解得足够好,完全可以通过手动试凑的方式来获得一套合适的PID参考,所以对一些非控制类的工程师应用起来也是非常友好的。当然还有一个非常重要的原因,PID算法对大部分系统稳定性、鲁棒性以及可靠性都非常的高,有调试PID控制算法经验的朋友应该都有类似的感觉,即便根据经验随便给系统一套参数都可以到达一个不错的控制效果。所以在很多人眼里这算法就是"万能的",适应的场景也非常的广泛,然而自古有一种规律"熊掌和鱼不可以兼得",PID算法虽然适应性非常广泛,对于处理一些特定的应用场景,或许其并不会最优的解决办法。基于大家在实际应用中各种各样的需求,曾经一个发展涌现了非常的PID的变种,也就是对PID算法在特定的应用场景进行优化、或者与其他一些控制方法进行结合,以便达到相应控制场景下的不错控制效果,比如微分先行PID、PID与智能控制的算法的结合等等。当然如果PID算法实在无法满足需求了,那也不能勉强,就只能考虑寻找另外更为匹配的控制策略,比如现在非常流行的自抗扰控制技术等等。2、PID的理解PID算法主要就是三项,比例(P)-积分(I)-微分(D),在连续的时间域内的表达式如下:从上面的公式可以看出PID算法是一个非常纯粹的数学表达式,既然是数学表达式那必然可以通过数学的方式进行分析,拉式变换一下,获得传递函数,然后采用控制理论分析方法,结合被控对象分析其对动态系统的稳定性、准确性以及快速性进行分析,从而达到性能上的最优解,这个控制系统的设计过程不是本文重点,暂时就不进行展开了。还记得最开始了解这个算法的时候,有一句话非常相信的彰显其魅力所在:P-I-D分别代表着当前、过去和未来。P对当前误差的抑制作用;I对历史误差的累积控制,以便消除静态误差;D根据误差的变化率进行补偿,从表达式也非常容易从根本上理解这几句话。3、数字PID在前面跟大家简单描述了连续域内的PID算法表达式,而连续域中该算法需要通过相应的模拟电路来进行实现,特别是一些没有数字芯片的嵌入式系统是经常可见的。但随着数字系统的应用,特别是单片机系统,数字PID更加得到广泛的应用,被大部分人所熟知的两种数字PID,分别是位置式PID和增量式PID。大部分的教材都会描述着两种形式的数字PID,然而这些教材一上来就介绍位置式PID与历史状态相关,过去会对现在的控制输出产生影响,而增量式PID仅仅只与最近的几次误差数据相关。如下是位置式PID表达式:这样看来增量式PID只与最近的两次误差有关系,不会存在累积误差的问题,说来增量式PID必然是更好的,那为何还要介绍位置式PID呢?也有伙计在自己的程序中使用增量式PID的表达式,毕竟增量式PID其输出仅仅只是控制量的增量,最后还是需要把输出量进行累积,这与位置式根本没啥区别。于是很多初学者,甚至一些用PID多年的工程师对此都抱有一丝疑问。其实这两种数字PID的应用场景是有区别的,增量式PID控制输出的仅仅只是控制量的增量,其主要是应用在执行机构带有积分部件的被控对象,而位置式PID其输出的是实际的控制量,则用于不带积分环节的执行机构。当然如果在一些不带积分环节的执行结构系统中你执意要使用增量PID的形式也无伤大雅,只是最后用数字积分进行处理后输出,其与位置式PID式没有差异,增量式PID的优势并没有展现,因为真正单独使用增量式PID的执行机构的积分环节是连续的,这是数字离散的方式无法比拟的。
不要只成为PID调参工程师
嘉立创PCB
如何在工程中添加说明文档
#嘉立创PCB# 请问在工程中添加说明文档,记录一些接口的说明,及工程中的注意事项,及修改的错误记录等,往高手指教
嘉立创PCB
1、#define与#undef今天分享一个C语言宏定义小技巧,从语法上来看比较简单,不过一旦真正领悟到其精妙之处不仅可以简化代码、还能提高代码的可扩展性。X-MACRO宏技术的核心在于灵活的应用#define与#undef,对于玩C语言的伙计#define是再熟悉不过了,但#undef却鲜有人在实际的开发过程中熟练使用,基本上都是#define走天下。那#define的作用域是怎样的呢?其作用范围都是从宏定义处到文件结束,不管函数内外均可以随意使用。那一不小心使用#define重复定义相同的宏又会怎样呢?对于大部分编译器会报重复定义警告,但也有小部分编译器采用最近的宏定义直接通过,所以稍不留神就把bug引入到了代码中。其实对于C语言编程素养良好的工程师们多会使用#undef来限制宏定义的作用范围,即取消宏定义,以免造成宏泛滥。 1#include <stdio.h>2#include <stdlib.h> 3 4#define HELLO_BUG   100 5 6int main(int argc, char *argv[]) { 7 8 printf("hello bug %d\r\n",HELLO_BUG); 9 10#undef HELLO_BUG 11 12 printf("hello bug %d\r\n",HELLO_BUG); 13 return 0; 14} 如上代码所示,便会编译报错,提示第二条打印语句HELLO_BUG宏未定义。2、X-MACROX-MACRO平时我们也叫"X宏",其实在bug菌之前的文章<三种管理C程序中标志位的方法,最后一种比较秀~>有一个简单的提及,今天单独拧出来简化讲讲。1#define X_MACRO(a, b)   a 2//do something 3#undef X_MACRO45#define X_MACRO(a, b)   b 6//do something 7#undef X_MACRO 如上是X-MACRO的比较精华的几句,通过#define与#undef的配合,可以使用相同的宏名称选择性的替换出我们想要的结构,从而达到简化代码的目的。同时我们也非常清楚,由于宏主要是靠编译器来处理,所以X-MACRO技巧也主要是在编译阶段来维护代码。下面来一波操作看看效果吧: 1/*************消息定义**********/ 2#define MSG_TABLE                  \ 3    X_MACROS(USER_MSG1, MsgProc1)  \ 4    X_MACROS(USER_MSG2, MsgProc2)  \ 5    X_MACROS(USER_MSG3, MsgProc3)  \ 6 7/*************消息枚举定义**********/ 8typedef enum { 9    #define X_MACROS(a, b) a, 10    MSG_TABLE 11    #undef X_MACROS 12    MSG_MAX  13} MSG_TYPE; 14 15/*************消息处理定义**********/ 16const Proc Proc_table[] = { 17    #define X_MACROS(a, b) b, 18    MSG_TABLE 19    #undef X_MACROS  20}; 21 22/*************实际使用**********/ 23void sMessageProc(MSG_TYPE msgtype) 24{ 25    (Proc_table[msgtype])(); 26} 当然X-MACRO还可以扩展多个参数来供序列化替换,同时X-MACRO宏定义也可以更加的复杂。比如使用#defineX_MACROS(a,b) #a宏来处理为字符串等。
C语言X-MACRO宏使用技巧
嘉立创PCB
C代码中花括号写成这种风格竟被吐槽~
最近来了位新同事,闲暇时分聊了几句,其中有一点让我记忆特别深刻,说:"怎么我们这边代码中的花括号风格都独立另起一行,看代码的时候挺不适应的~",我笑着说:"习惯就好了~"。 其实对于C代码中花括号的书写风格,bug菌也不是第一次听到不一样的声音了,包括之前文章中所编写的一些代码示例,也是有朋友跟我提及此事。 其实对于C代码中的花括号的风格也绝非偶然,他们是有具体的命名和使用考虑的,目前使用比较广泛的是如下两种风格: 风格一:Kernighan & Ritchie风格,也就K&R Style void function() { if(bTrue){ //do someting...... } else{ //do someting...... } } 这种风格的花括号与使用它的语句同一行,其实这也是Linux内核中常采用的一种风格,相比风格二没有单独起一行,在一定程度上降低了代码长度,整体更加紧凑,但使用者经常会衍生出各种变体风格。 风格二:Allman风格,也叫BSD Style。 void function() { if(bTrue) { //do someting...... } else { //do someting...... } } 这种风格也是bug菌目前习惯的一种编码风格,该编码风格有一种对称美,可能也是早已习惯的原因吧,但缺点也很明显,比较浪费行,一些朋友常说:"我都没写几句代码,却占了一个显示器~"。 至于花括号使用哪种风格也是一直存在一些争议,也没有说哪种风格会更胜一筹,所以不管选择哪种风格,最重要的是保持统一,不用过分纠结。
嘉立创PCB
可以用Keep-out层画板框吗? 用M1画板框,每次铺铜后,还要单独删一遍Keep-out层,比较浪费时间!
嘉立创PCB
最近一些朋友问道如何快速提升自己的技术能力,以前觉得提这样问题的人有点急功近利,所以一般也不太愿意去解答,或许我也不知道有什么方法能够快速提升吧。但闲暇时分也会常常偷偷的问自己,假如一切从头开始,我会以怎样的方式去提升技能呢?思来想去最后总结了4点内容,在这里分享一下:1、多交流、多分享。技术更新是很快的,可能嵌入式技术革新相对计算机要慢点,不过目前受龙"卷"风的影响,很多技术的更新周期缩短了很多。不断的学习是一方面,但也不能蒙头搞研究,还需要多跟同行交流优秀的技术和方案,这样在学习和开发中才会更加的高效,拥有更多的思路和灵感,也会少走很多弯路。2、多利用零碎的时间。时间是我们生命中非常重要的东西,年龄、头发的颜色和疏密层度就是时间的痕迹。相同的年纪,你知道了解的东西越多、掌握的技能越透彻,便可以更容易超越很多的人。前段时间听到一个空降26岁技术总监的故事,其实并没有感觉很意外,要么是皇亲国戚,要么就是有两把刷子,其他情况下都不会是长久之计。而对于大部分打工人而言,一个人的成长很大程度上取决于工作之外的时间利用。3、注重基础。万丈高楼平地起,自从bug菌工作以来深感基础的重要性,很多时候深入、透彻的研究一些复杂的技术,我总会先大致学习或复习与之相关的基础知识,把知识脉络理清楚,然后一层一层往上学,知识盲区自然会被各个击破。同样像我们平时进行软件编程,各种底层驱动、框架搭建好了,那么上层应用开发会省心不少,其实是一样的道理。4、多总结、多实践。人是会健忘的,同样很多技术知识,如果你长时间的不去温习,自然就会生疏,很少有人能够做到长时间不用的技术能够信手拈来,所以很多时候一些朋友面对自己的生疏会变得非常焦躁。以前明明这些技术我可是“玩得溜溜的”,可现在走两步就有种掉坑的感觉,甚至开始怀疑自己是不是老了,记忆力衰退了等等。这些都是正常现象,我们不可能保证自己所学习的东西能够一直想硬盘一样存储中你的脑海。一方面我们需要定期总结重点技术要点,梳理自己的技术知识体系,只有这样,当我们需要把尘封的知识重新解封的那一刻,那么这些技术知识总结能够帮助我们在最短的时间恢复到当初的最佳状态。另外一方面就是多实践,为的就是让自己印象更加深刻,减慢遗忘速度,同时在技术知识的实践过程中也能够有自己新的领悟和理解,就如同恋爱一样,为什么会那么的刻骨铭心?因为你亲身经历过,真真切切的感受过,而不仅仅只是在电视上或者书本中在看着别人在谈情说爱。
唠叨一些嵌入式技术学习习惯~
嘉立创PCB
1-32层pcb打样,真A级板材,最快12小时出货,自营制造,品质可靠!
推荐话题 换一批
#嘉立创PCB#
#DIY设计#
#嘉立创3D打印#
#畅聊专区#
#嘉立创免费3D打印#
#创享2025#
#618金豆嗨购节#
#高校动态#
查看更多热门话题
打赏记录
粤公网安备44030002004666号 · 粤ICP备2023121300号 · 用户协议 · 隐私政策 · 侵权举报 · ISO/IEC · Copyright © 2024 嘉立创社区版权所有
服务时间:周一至周六 9::00-18:00 · 联系地址:中国·深圳(福田区商报路奥林匹克大厦27楼) · 媒体沟通:pr@jlc.com · 集团介绍
移动社区