摘要:近期龙芯俱乐部完成了龙芯开源创客智龙主板的首发,这个基于龙芯1C处理器的创客主板,不仅有了国内的创客用户,还被带到了国外,通过社区协作实现了很有趣的创客作品。现在就请第155号首发用户王千来分享下智龙主板的英国之旅,可以说他既是第一个把龙芯智龙主板带到国外,同时也是最年轻的龙芯创客。

我其实很早就知道我国有龙芯这么一款国产处理器,但对其的印象一直停留在“安全应用”、“试验品”等字眼上,认为一个普通人并不会接触到龙芯系列的处理器;尤其是在得知龙芯所使用的MIPS架构无法兼容Windows之后,便更加认为龙芯不会在桌面系统上有所成就——直到今年三月份在某新闻客户端上看到了一则新闻,内容大约是“中国的树莓派 开源龙芯主板开始接受团购”,发现其价格为199元并不贵,同时由于对国产CPU的好奇,便拍下了这款产品。在经过了漫长的等待——五月份发货,以及我八月份才回国过暑假——之后,终于拿到了这块板子。当然由于这块板子,我也通过社区了解到了龙芯产品的最新动向,比如自主指令集,以及3A2000和3B2000 CPU。这些新产品受到了媒体的广泛关注,龙芯中科也因此被人民日报头版所报道,在此便不再累述。

事实上,我此前并没有任何嵌入式开发的经验。在最开始拿到板子的时候,甚至不知道要通过串口线连接主板。但是通过开源社区中提供的教程,我很快便掌握了对主板的简单操作。在这里要感谢教程的作者xieyug2012以及shigeng。

小作品——摩斯电码播放器

摩斯码使用不同长短的连续波(嘀和嗒)和间隙来表示26个英文字母,10个数字以及一些标点符号,由于其编码简单、可靠性高,被广泛应用于无线电通讯领域。其简便性使我萌生了利用龙芯主板来将英文文本翻译为摩斯码,并通过扬声器以正弦波播放出来的想法。由于我并没有无线电执照及相应的设备,所以此作品仅限以声音形式播放而不能通过无线电发报,但进行改动,龙芯主板是完全有能力成为全自动发报机的。

硬件部分

此作品电路板的基本系统结构为:使用运算放大器芯片构造一个正弦波发生器,其频率可由一个双联电阻器在约500Hz至无限大(实际极限数值由芯片决定,但肯定超出人耳听力范围)之间调整,此正弦波将作为扬声器的声源。扬声器与正弦波之间有一个由开源龙芯主板GPIO接口所控制的继电器,用来控制线路的断连,从而达到播放摩斯码的目的。

确定了系统结构之后,下一步就要制作电路原理图并确定元件参数。毫无电路设计基础的我在网络上找到了这张原理图作为参考。

然而此电路在模拟器中的模拟并不成功。在QQ群中electron群友的帮助下,将运算放大器改为LF356N,并对电路做出了大幅度简化及调整,确定了电路构造以及元件参数,并在软件中进行了电路模拟,成功输出了预定频率的正弦波。

我住在天津,作为一个大城市购买电子元件并不困难,我很快便购齐了所需的元件及面包板,开始真正的制作。

最初的三个元件

杂乱的环境

在实际制作中,我碰到了许多在模拟中没有预料到的问题。首先碰到的问题是GPIO无法直接触发继电器。通过查阅所使用的HRS1H-S型继电器的数据表,发现其线圈需要约300mW的功率来触发,然而龙芯GPIO的最大输出功率仅为约50mW。在QQ群中群友的建议下,我使用了一颗8050三极管来提升功率,成功触发了继电器。

第二个问题则是吃了不认真和不懂电路原理的亏。当我把一切元件及线路按照电脑自动生成的鼠线连接之后,扬声器没有任何反应。这个问题困扰了我好几天,我一点一点地将面包板上的接线与电脑给出的鼠线比对,希望能发现什么接线错误,然而并没有。而这时我也该回到英国了,于是只能把所有的东西装到盒子里,到了英国再处理。

到了英国,我就有万用表能用了。通过测试发现,输出端是有直流电压输出的,而且与预期的结果一样,这说明电路并没有断路;但当测试交流电压时,万用表毫无反应,这说明输出的波形是一条直线,而不是正弦波。既然电路板上没问题,那会不会是电路本身的设计问题?但如果电路设计有问题的话,仿真软件又是如何输出预期的波形的呢?我开始仔细检查起仿真软件中的电路,最终发现了问题:

问题就出在这个-6.0V身上。此前我一直是把4号针脚接地的,并没有意识到这个负电压的问题。当我在仿真软件中也把4号针脚接地后,其输出的波形也变成了一条直线。

依然是在群友的帮助下,我对线路做了一点小改动,将4*1.5V AA电池盒的负极接到4号针脚而不是地,并把第二节电池的负极当成了地。由此便创造出了一个 3V的直流电源,但这也导致了输出电压成了原来的一半,因此不再需要起初串联在扬声器上的限流电阻。

以上即为最终的电路图。可见由2颗3.3nF电容和一个最大电阻为100k 的双联电位器所组成的反馈回路。运放输出端直接连接扬声器正极,扬声器的回路则由继电器所控制。继电器的线圈一边接地,一边与一颗三极管的发射级连接,此三极管的集电极由电池驱动,基极则连接GPIO输出口和一个限流电阻。5.1k 电阻+2个1N4004二极管并联的设计来自群友electron,用来限制峰值电压。

最终,扬声器里成功输出了干净的正弦声波,通过调整双联电位器可将其频率调高至人耳听力以外。至于波形实际的噪音水平为多少,最高可达到的频率为多少,由于我并没有示波器,因此无从得知。

软件部分

以上内容仅是成功的一半而已。有电路只能让喇叭发出正弦波,要想发送摩斯码,还要进行编程。我按照论坛上的教程在Ubuntu上搭建了交叉编译环境,所使用的语言是C。我的C语言水平也是半斤八两,许多地方都靠现学现卖。

程序结构如下:主函数将输入的文本存入字符数组并传递给morslize函数,此函数将输入的字符数组遍历,并将每个字符翻译为一个代表此字符摩斯码的整形数组。比如字母A的摩斯码是嘀 嗒,那么它的数组就是{0,1},字母C的摩斯码是嗒 嘀 嗒 嘀,那么它的数组就是{1,0,1,0}。总之,用1表示嗒,0表示嘀。此数组再传递给play函数,用来控制GPIO口的电平高低及电平持续时间。控制GPIO口的函数及其头文件来自论坛网友shigeng。他/她并未写明此头文件的版权协议,在此我将其默认为与龙芯开源主板使用相同的版权协议。如有侵权请联系我。

摩斯码很重要的一点就是嘀、嗒的持续时间以及嘀嗒之间、字母之间以及单词之间间隔的时间。依照标准,一个嘀的长度为一个单位时间,一个嗒的长度为三个单位时间,嘀嗒之间的间隔为一个单位,两个字母之间为三个单位,两个单词之间为七个单位。一个单位时间是由码速所决定的,码速则由WPM为单位,意为单词每分钟。这里的单词以”PARIS”一词为标准;因此,码速的完整意思是“在一分钟之内可以使用摩斯码发送多少个 PARIS ”。由此我们可以得到公式:单位时间(秒)=1.2/WPM。但由于C语言中usleep函数是以微秒计的,因此在源码中应该用1200000/WPM来计算单位时间。

程序中涉及到了两次遍历数组,第一次是morslize函数遍历所输入的字符。此数组长度未知,因为输入的内容未知。然而通过循环遍历数组是需要知道数组长度的。由于在C中数组参数的本质是指针,我们不能在morslize函数中简单地使用sizeof(数组)来获得长度,因为这里的数组本质是指针。对此我调用了string.h头函数中的strlen函数来获得长度。

第一个遍历尚好解决,第二个就比较棘手:对于play最终的函数来讲,其参数(也就是上文提到的0 1数组)长度未知,因为每个字母摩斯码嘀 嗒的数量都不一样。而其数据类型为int,并非可以使用strlen函数的字符数组。对此问题我的解决方法是把嘀嗒数量当成数组的第一个元素传递出去,而在play函数遍历的时候跳过第一个元素。

在play函数的具体机理是:如果遍历到的元素是1,则把GPIO口设置为高电平,等待3个单位时间(即一个嘀的时间),然后把GPIO设置为低电平;如果元素是0,则同理,不过等待的时间只有一个单位时间。

程序码好之后,修改一下shigeng所提供的makefile文件,将源码以及GPIO头文件及函数利用mipsel-linux-gcc编译为一个独立的、不需要外部依赖的mipsel可执行文件,然后通过ncat发送到龙芯主板上。

将GPIO47口及GND与电路连接,执行morse程序,输入WPM值及要播放的文本,即可听到继电器开闭以及扬声器播放摩斯码的声音。

致此,这个在中国开始,在英国完成的项目正式完工了。从构想到完成总共花了约一周多时间。其实这个小项目很简单,对于有电路设计经验的人来说或许三四天就能完成。下一步我可以把这些元件焊到实验板上,甚至设计出PCB让厂家来生产——不过设计PCB也不是件简单事,如果我有时间的话可能会研究下。

此外,我也应该是第一个将开源龙芯主板带出国门的人。可惜我所在的小镇离著名的地标性建筑很远,因此就让龙芯主板与我小镇上的一些标志合影吧。