电子积木开发手记(新篇)

文章目录
  1. 1. 2012年10月13日
    1. 1.1. PCB设计和制作
    2. 1.2. 焊接
    3. 1.3. EEPROM
    4. 1.4. 编译STM32的驱动库
    5. 1.5. 硬件设计缺陷
    6. 1.6. 小结
  2. 2. 2012年11月3日(Srduino A3勘误)
  3. 3. 2013年2月25日
    1. 3.1. 代码尺寸问题
    2. 3.2. EEPROM驱动
    3. 3.3. USB虚拟串口移植
    4. 3.4. Bootloader
  4. 4. 2013年4月12日
    1. 4.1. 固件部分
    2. 4.2. 软件部分
    3. 4.3. 硬件部分
  5. 5. 2013年4月23日
    1. 5.1. Srduino B1板子
    2. 5.2. Srduino Mini板子
    3. 5.3. Digital Audio板子
    4. 5.4. 2.4GHz RF板子
    5. 5.5. JLink ARM OB板子
    6. 5.6. JTAG转接板子

2012年10月13日

很久没有写这个手记了,翻看了一下《电子积木开发手记》,发表的时间是3月24日。至今已经有六个半月了。半年多的时间里,这个项目已经发生了翻天覆地的变化。除了“电子积木”这个目标没有变以外,我们的硬件平台被推翻重做,再次推翻、再次重做,如此重复了很多次。但是值得欣慰的事情还是有的,首先就是获得了国家十万元的经费支持,这是我们开发初期重要的资金来源,感谢国家!我们的第一版UxBoard主板是一份非常优秀的课程作业,让我们在《嵌入式系统》课程中都获得了95分以上的高分,但有点小遗憾的是这个硬件平台面临被推翻的危险,但它毕竟是我们的第一块PCB,还是值得纪念。我们受邀参加大学生创新创业展览会,这将是推广我们的产品和理念的第一步,是一个很好的机会。当然还有最重要的,那就是我们一直都在努力,在遇到困难时也没有想放弃,整个项目现在在有着良好的发展势头。

感慨了这么多,这毕竟是个技术笔记,还是来说说最近做的PCB

PCB设计和制作

这块PCB可谓屡经波折。。。组员不靠谱,鼓捣了半个月,最后啥都没做出来,人退出项目组了。。。好吧~都让你做了我还不放心呢~我自己做还不成吗?自学了Allegro,发现其实是会了不难难了不会。。。元件封装确实比较麻烦,好在有神器“LP Wizard”。不过设计PCB还是件很耗时的事情,最终送工厂打样的PCB文件的编辑时间超过了40个小时。学习软件的各种波折就不记录了,反正现在都会用了。只记得于博士的SPB教程中对钻孔文件的输出讲的不是很详细,或者我没看着,反正是我又去专门搜索的钻孔文件的输出方法。
做PCB最大的两点就是跟工厂斗智斗勇了。为了充分利用10*10的空间,我在这块空间里拼了4块板子。地球人都知道,拼板要加钱,而且还加的不少。。。我开始的如意算盘不出所料被工厂一眼识破,直接说要加钱。那能行吗!于是又改了一下边框,工厂立马表示不用加钱了。。。我只是把槽开的短了一些。。。工厂真是自欺欺人。。。
于是最终花100元做了4块拼板的10块板子~还要了很骚气的白油黑字,但做出来没有想象的好看。。。丝印有断线和黑子貌似不如白字牢固,弄上酒精一刮就掉了。。。

焊接

最难焊的估计就是那个QFN28封装的CP2102了。。。最后还是采用的烙铁烤板子的方法。第一块板子居然被烤糊了,完全低估了烙铁的温度。。。STM32的MCU焊接还算顺利,至少目前没发现大问题。FT2232就命途多舛了。。。焊的第一块仿真器板子,电脑居然不认。我就估计是芯片焊接的问题,于是又重新加热管脚,还是不认。。。最后都要抓狂了,怀疑不是焊接的问题了。。。最后把芯片拆下来,残余焊锡清理干净,用手用力按压到板子上,一上电,认了。。。看来还是焊接的问题。。。我作为一个成功焊接过LQFP100的选手,居然囧在这个LQFP48上,实在是很无奈。。。

EEPROM

FT2232D要求的EEPROM貌似比较严格,有些型号虽然也符合16bit结构,但是就是不能用。我提前知道这种情况,在淘宝上买芯片时也注意了区分。但是不怕就怕啊!SB的买家居然发错了货!我要的AT93C46D,给我发了个AT93C46A。。。其实理论上说,AT93C46A应该也是可以用的(AT93C46A固定为16bit组织,而AT93C46D可以选择8bit还是16bit,ORG脚悬空即为16bit,跟A一样,但是A就是不能用。。。),但实际不行,FT2232根本就没法跟它通信,一个字节都读不出来,一直是Blank Device。后来死马当活马医,把打算放到主板上的M93C86按上去试了试,发现居然读出了东西。虽然工作还是异常,但至少有东西了。。。于是紧急奔到中发,买了10片ST的M93C46. 回来一试,果然好了!

编译STM32的驱动库

编译居然出错了。。。真是太神奇了。。。看了一下错误,大概是因为工程目录下CMSIS库extern了系统库里定义的东西,但是extern的类型跟系统库里定义的类型不太一样。。。ST官方给出的解决方法是,删掉驱动库自带的CMSIS(据网友说是1.3版本),通过修改工程设置来使用IAR自带的CMSIS(据说是2.1版本)。但网友指出,如果换了IDE还会出问题。所以建议直接用ARM官方的CMSIS最新版替换掉工程目录下的旧版本。这个看起来很有道理的样子,有空尝试一下~

硬件设计缺陷

仿真器好了就开始跟主板联调,结果仿真器没法仿真STM32. 很无奈。最后实在没办法了,为了确定是仿真器的问题还是目标板的问题,就找出了当时做的UxBoard主板,那上面是TI的Cortex-M4的MCU,试了一下居然可以仿真!看电路图,发现我很SB的把STM的nTRST引脚放到了JTAG的5脚上,而这个脚对应在仿真器那边是GND。。。于是结果就是JTAG的寄存器一直处于复位状态,但是由于nSRST的位置的对的,所以目标板的复位目测是正常的。。。其实10pin的JTAG接口不应该包含nTRST引脚,但是STM32有这么个引脚,总不能不引出吧~下次打算放到7号,7号在仿真器那边是不连接的。

还有件很囧的事情,就是L那个指示灯一直是亮着的!!!去网上找来Arduino Uno第一版的电路图,发现这个LED是直接连接,没有运放隔离。而Uno第三版就加上了运放隔离。但是MCU复位后引脚默认应该是高阻输入的,那个灯确实应该一直亮着,而且还会因手指的触摸而改变亮度。。。实在是太囧了,目测Uno第三版也会有这个问题,有机会找个板子试试。这样的设计实在有点不靠谱,不如把LED设计成低电平点亮的。。

当然目前为止真正称得上是错误的应该就算自动复位的设计了,我的设计貌似没有像想象中的那样工作,可能需要通过修改原理图来更正,不知道PCB上能否小改一下。。。
2012年10月13日,更新啦!今天早上起来就在分析自动复位这个问题。研究后决定把复位脚上接地的104电容拆掉(标号C4),拆掉后自动复位果然工作正常了!

小结

拼的4块板子,其中有个万能转接板,那个不算,剩下的3块都是有电路的。

  1. Srduino主板做成功的测试有:
    • CP2102串口回显
    • 修改CP2102的字符串
    • STM32通过CP2102串口ISP
    • STM32通过J-Link和Stellaris ICDI下载程序(闪烁LED)
    • 通过拆除电容C4,自动复位已经正常工作了
      失败的测试:
    • 通过CP2102自动为STM32复位。。。但CP2102的DTR和RTS电平能正常拉低。
  2. Stellaris ICDI成功的测试:
    • 通过OpenOCD的GDB Server驱动仿真STM32、LM4F232(仅支持JTAG)
    • 通过IAR内置的Stellaris ICDI驱动仿真LM4F232(JTAG和SWD均可)
      失败的测试:
    • 用IAR内置的Stellaris ICDI驱动仿真STM32。
    • 还有一个问题就是红色的DEBUG灯不会熄灭。。。
  3. STM8S最小系统:只测试了用SWID下载了一个闪烁LED的程序,成功了。

2012年11月3日(Srduino A3勘误)

Srduino A3 PCB调试过程中发现以下设计缺陷,将会在未来版本中更正

  1. 自动复位电容C4原设计为100nF,实际应用中无法自动复位。此电容的正确容值应为10nF

  2. IO板10pin JTAG排针5号脚,原设计为nTRST,而仿真板5脚为GND。直接使用排线连接两个排针会导致IO板一直处于复位状态。应将IO板的nTRST不引出,或者引出到未使用的7号脚位置。

  3. IO板USB DEVICE接口的D+信号线未上拉,直接连接了MCU,会导致USB设备无法枚举。此处应将D+信号线使用1.5k电阻上拉至3.3V。视实际应用,可能还需要添加三极管控制是否上拉,以便在合适的时候通知上位机重新枚举USB设备。

    编程过程需要对设备进行重枚举(USB Composite Device理论上可以实现CDC+DFU,但据Maple主页上的描述来看,这么做在Windows下会有问题。若无法实现CDC+DFU的Composite Device,则必须进行重枚举。此说法待验证。)官方Evaluation Board的做法是使用单片机的一个IO口和两个三极管控制1.5K电阻是否连接D+,但我们认为有更简单的方法。目前我们的做法是将1.5K电阻一段接D+,另一端接一空闲IO口。IO口推挽输出高电平即为USB接通,IO口开漏输出高电平(实为悬空)即为USB断开。从而完成USB重枚举。此方法目前工作正常。

  4. 仿真板丝印错误,FT2232右上方丝印中,两列四行的表格中,第一列第三行原为RX,应为TX;第一列第四行原为TX,应为RX。

  5. 指示灯L,原设计为高电平点亮,但在芯片高阻态时,此指示灯会常亮,且可能因手指触碰运放引脚而改变其亮度。当相应引脚作为输出状态时,则工作正常。拟在下一个版本中将其改为低电平点亮。或许可以通过修改连接运放的极性来更正?

  6. 丝印层PLATFORM写成了PLANTFORM,PERFORMANCE写成了PROFORMANCE…….丢人都不知道丢到哪里去了。。。

  7. 下一版本考虑将IOREF旁边未连接的针脚用于连接Vbat,用于给RTC提供后备电源。

  8. 再次发现一处丝印层错误!!!Srduino板JTAG口TDO和TCK两个的位置标反了。。。

  9. EEPROM型号确定为ST的M93C86

  10. 供电电路和电磁兼容性优化

    • 3.3V稳压器换小封装(SOT89或者SOT23-5)
    • 增加电解电容滤波
    • 根据实验结果将LM324更换为LM358或者LMV358,串口指示灯不用隔离,恢复直连
    • 根据实验结果确定是否要对VDDA和VSSA设置独立的LDO稳压器
    • 根据实验结果确定是否将模拟地VSSA直接连到GND
    • 根据实验结果确定是否更换MOSFET的型号
    • 修改USB口保护方案
    • 修改运放电压比较器分压为1:1
  11. 将BOOT0和RTS两个测试孔拉近


2013年2月25日

我要先吐个槽!!!我真的觉得我够到了我的智商上限。。。我已经很努力的思考一些问题了,但是一定要经过足够长的时间,我才能找到正确的思路

代码尺寸问题

这个问题不再详谈了,已经写了一篇两三千字的文章了。那段时间实在是郁闷。。。动不动代码尺寸就爆了。。。Hello world就要90KB。。。完全不知道如何下手。。。一天晚上跟MM聊天,突然迸发出一个灵感,逆向思维。删代码,直到删到代码尺寸降下来为止。这个思路很有效,后来发现那次代码尺寸暴增是由纯虚函数导致的。导致代码膨胀的原因还有很多,我基本都碰上了,详情去看《如何在嵌入式C++开发中缩减代码尺寸》这篇文章吧~完全是一部血泪史。。。

EEPROM驱动

一个调了一天的问题。。。结果是因为时钟线的频率太高了,超过了EEPROM芯片的最高速度。。。随手加了个循环浪费时间,频率降下来了,驱动就通了。很庆幸我能按照Datasheet一次性的时序逻辑写对,否则调试起来就真蛋疼了。。。

USB虚拟串口移植

又是一部血泪史。没得说,就是看官方的example代码。开始想偷懒,打算把程序拿过来随便改改整合进去,完全行不通,官方的文档又很学术,没啥具体的东西。只能看代码。。。有几个细节记录一下,首先就是拙计的英语。。。有个词组叫correct transfer,我以为这是一种特殊的传输,就像Control transfer、Bulk transfer等等这些词组,都是USB标准里规定的一种传输方式,有特定的工作模式。可是我翻遍了USB标注也没找到到底什么叫correct transfer。。。我那个郁闷啊。。。由于对correct transfer的理解错误,还导致了很多bug。。。终于,有一天,我意识到我SB了。。。correct transfer就是字面意思,就是正确传输。。。就说这次传输数据没发生错误,对方也收到了,这就叫正确传输了,correct transfer。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

再有就是一个芯片或者USB库的一个bug了(不知道算不算bug。。。),就是EPx_OUT_Callback会收到长度为0的包。。。如果这时你闭着眼把Endpoint置为NAK状态,你就别想回来了。。。因为处理数据的函数无事可做,就不会重新将Endpoint置为ACK,当然又不会有新的数据发来,于是就歇菜了。。。解决方法,只能自己判断一下,长度是0的话就不要置为NAK。。。哦,好像系统会自动给你置为NAK,你必须手动置为VALID才行!!!我真的很幸运,第一个思路就是怀疑是数据包的长度出了问题,否则按照程序员“一定是我哪里搞错了”的思路,我无论如何也不会想到把断点加到Endpoint的callback里。。。

Bootloader

血泪史啊!!!!我觉得核心库做的差不多了,通过虚拟串口复位也加上了,打算加上bootloader,走一下流程了。结果,傻逼了!!!

首先是Maple的bootloader太2B了,编译居然不能开优化!!!一个-O1的优化就会导致其不能运行。。。估计是哪儿该加volatile的地方没加,被优化坏了。。。决定先不管bootloader,先用着O0,改天有空再研究优化的问题。

接着就是最2B的事件了。。。加上bootloader之后,程序居然不能运行了!!!没有bootloader的时候好好的啊~连接脚本已经把起始地址改成相应的bootloader跳转的地址了,后来发现是中断向量表的位置没有在代码中设置。。。但设置了之后,程序还是不对劲。程序就是最简单的闪烁LED,但是LED闪烁64次后程序就会挂掉。。。我至今都非常不明白我是怎么发现是64次的。。。总之我神奇的发现了这个神气的现象,但我不能解释。。。

64是个比较特殊的数字,很多常量都设置成了64. 后来随手把串口rx队列长度改成了32,发现闪烁32次后停机。我就觉得闹鬼了,闪烁led是死循环,跟串口队列长度有毛线关系啊!终于,,,经过几个小时的思考和艰苦查找,我发现!!!闪烁的LED居然就是串口RX的指示灯!!!于是闪一下,串口就收到一个数据,数据就被放到队列里。。。然后64下之后,队列满了,程序就挂了。。。。。实在是太!二!了!!!!


2013年4月12日

固件部分

巧妙的分配单片机的定时器是非常有挑战性的。我们有望比Arduino做得更好!

软件部分

首次走通了全部的流程。已经可以在VIM中实现一键编译、复位并刷写了。
第一次手动编写了自己的Makefile,是不是很弱爆。。。

之前敲各种make敲到手软,但也只是知道Makefile这个东西而已。自己编写Makefile之前还试图用各种工具自动生成,结果越弄越乱。想到松哥之前说的一句话,不到10万行的项目根部不需要这种工具,遂放弃自动生成,改为手动编写。
Makefile大概有60行左右,包含了编译、连接、objdump和size以及reset和dfu-util调用等操作,用起来还是很方便的。

唯一要吐槽的地方是,我花了一天的时间写这个Makefile。。。我本以为中午就能搞定,结果在晚上9点终于调通了的时候,发现好像没吃晚饭。。。“马上就能做完”果然是程序员三大错觉之一!

硬件部分

这个是最近的重头戏了吧。新版PCB的设计和打样,是我们开发进程中的重要一步。新版的PCB全面更换了阻容元件封装,优化了供电电路、还改动了USB接口、AD转换接口等位置,修复了在A3版中发现的所有bug。由于引脚映射发生了些许的变化,固件库也需要跟着升级一下。

另外为了最大限度利用PCB空间,我们还在这块板子中拼入了一个Srduino Mini,这是一个简化的Srduino,尺寸与51单片机类似。还拼入了一个数字音频扩展板,由飞利浦的经典I2S接口的DA芯片TDA1543进行音频解码,板上还包含了一个microSD卡槽。另外拼入了一个基于nRF24L01+的2.4G射频模块,参考了官方的设计,将0402封装的元件更换为了0603. 最后一个拼版是J-Link OB仿真器,之前仿制的开源仿真器实在是不能令人满意,在IDE兼容性、跨平台特性等诸多方面都存在问题。这次索性使用了山寨J-link。之前已经在一块废板上进行了测试,J-Link OB工作非常稳定。

这次PCB设计总结了之前版本的经验,吸取了教训。在丝印层方面,放弃了教学视频中提及的Autosilk,因为这个层经常因元件调整带来各种问题,使得刚刚修改好非常美观的布局变得面目全非。看名字也知道,这个层是由系统自动管理的。这次我们配合使用了Board Geometry中的Silkscreen、Package Geometry中的Silkscreen和Components中的RefDes的Silkscreen。分别用于管理板级的图案(例如Logo和说明文字)、元件本身的丝印图案(例如正负极标志)和元件的索引编号。实验证明,即使在调整好丝印之后再次改动布局和布线,也只有在改动中旋转了方向的器件的丝印需要手动转一下,其它内容几乎不需要再重新调整。这才应该是调整丝印的正常状态!之前版本之所以丝印出现那么多bug,就跟管理丝印的方法有关!

本版还常识使用Illustrator制作矢量图,直接导入Allegro作为Logo,但是最终没有成功。不过由矢量图直接输出指定尺寸的BMP图像还是很方便的。另外我们还发现了上一版的Logo存在一些较细的笔画印不出来的问题,这次也同时对图像的内容和BMP to IPF的参数进行了调整,有望彻底解决这个问题。

新版PCB已经箭在弦上,希望在接下来的封装验证、PCB打样和焊接调试中进展顺利!


2013年4月23日

这次PCB打样太给力了!下单后48小时就发货了,快递也给力,隔天就从深圳寄到北京了!

史无前例的6块板子拼板!省钱省到家了!不过事实也证明了,投入多少精力就会有多少回报。在Srduino B1版上,可是说我精雕细琢。因为之前有积累,这次也一举修复了之前在A3版上发现的所有硬件bug。目前为止Srduino B1没有发现啥明显的bug,希望不要再有bug了!

其他的拼板,因为画的时候就抱着试一试,允许失败的态度,所以自然就出现了一些比较无语的错误。。。下面将发现的所有的错误总结如下

Srduino B1板子

  1. microUSB钻孔直径过大,应为0.65mm,实际上有41mil,超过1.00mm
  2. 光学识别点中心没有铜
  3. Top层丝印的Logo仍与想象的有一定出入,不过至少所有笔画都能看清了!不知道是否跟厂家印刷的精度有关。
  4. 下一版要把注册商标的标志(TM)和官方网站的链接加上去!还可以考虑弄个二维码~

Srduino Mini板子

  1. 丝印Logo完全看不清楚

Digital Audio板子

  1. 3.5mm耳机插孔封装的封装错误:
    • 5个非电气孔没有打出来!
    • 摆放边界没有预留合理的空间,隔着旁边的运放芯片太近!差点就插不上了
    • 圆形的电气孔直径太小,费好大劲才能把插座插进去
  2. microSD卡槽封装的问题
    • 非电气孔直径过大!
    • 若非电气孔直径合适,那电气焊盘预留的长度是否足够?
  3. 低级错误:2*8pin的SPI&I2S插口摆放的位置不对,无法与基板重合,相差了100mil,基本导致该PCB报废,只能用杜邦线连接

2.4GHz RF板子

  1. 通信不稳定,不确定是由于元件导致、程序导致还是PCB导致的。
  2. 16MHz直插晶振封装的摆放边界没有预留出合理的空间,几乎导致其金属外壳与旁边的焊盘短路,只好给它垫上一层胶带
  1. JTAG接口的方向错误,无法直接插到Srduino B1上,只能用一条排线连过去。不过貌似无伤大雅。下一版可以考虑去掉按键,而使用全尺寸的2*5牛角座
  2. 同样是晶振的问题,金属外壳几乎要与旁边的电容短路。

JTAG转接板子

这个应该不会有bug吧。。。


版权声明

The Bloom of Youth by KUANG Qi is licensed under a Creative Commons BY-NC-ND 4.0 International License.
况琪创作并维护的锦瑟华年博客采用创作共用保留署名-非商业-禁止演绎4.0国际许可证

本文首发于The Bloom of Youth | 锦瑟华年博客( http://kuangqi.me ),版权所有,侵权必究。

本文永久链接:http://kuangqi.me/embedded/note-on-srduino/