电子积木开发手记

文章目录
  1. 1. 2012年3月24日
    1. 1.1. CMOS芯片不用的输入端不能悬空
    2. 1.2. 0805表面贴装的电阻可以焊到洞洞板上
    3. 1.3. 串口通信,神棍一般的波特率计算!
  2. 2. 2012年4月3日
    1. 2.1. 第一件要吐槽的事情一定是:波特率!
    2. 2.2. 1602液晶及其在Proteus里的仿真
    3. 2.3. C51模拟PMW输出
    4. 2.4. STC的自定义下载~~
  3. 3. 2012年4月9日
    1. 3.1. 去买了晶振,串口通信稳定了
    2. 3.2. 做了块STC11的扩展板
    3. 3.3. 自动检测波特率,检测串口设备
    4. 3.4. received标志位没置零,调了很久
  4. 4. 2012年4月22日

2012年3月24日

最近准备做个串口通信的LED数码管显示板,搞了一堆芯片做实验,遇到的问题挺多的,这里记录一下吧。

CMOS芯片不用的输入端不能悬空

浪费一个小时的时间,惨痛的教训证明,数电老师上课强调的事情并非子虚乌有。。。用了一个74HC595串入并出移位寄存器,有个神棍的清零端,我也用不着,就悬空了。结果数码管都是半亮半不亮的状态,很诡异。检查电路,无果。。。后来忽然意识到,这个HC貌似就代表这是个CMOS的芯片,于是把那个清零端接到高电位,和谐了。。。

0805表面贴装的电阻可以焊到洞洞板上

感觉一般的电阻体积太大,想搞点小的,就顺便买了100个表贴的电阻,回来发现真的可以焊到洞洞板上,刚好是两个洞洞的长度~还有,SMD的电阻貌似很精确,标明的误差是5%,可是我实测的误差都在0.5%以内,出乎意料

串口通信,神棍一般的波特率计算!

调串口通信的程序,收到的一直是乱码,无限吐血中。。。很奇怪,为什么网上的代码都是在11.0592的晶振上做的,我的晶振是12.000的,就是找不到代码。我自己算了一个RELOAD值,也不行。后来看到数据手册上提到了波特率的误差,又在STC官方下到了波特率计算工具,直接生成C代码,挺给力的。更重要的是,这个软件会给出一个波特率的误差。在12.000MHz,12T,9600bps的情况下,误差超过了8%,而数据手册要求误差不能高于3%,看来是达不到要求的。只好把波特率改成了2400bps,成功了。。。

另外在STC11的单片机上,可以使用内部RC时钟,还有独立波特率发生器,由于STC11是1T的单片机,所以波特率的误差会小一些,可以达到9600的波特率了。要注意的是晶振频率要选5.5296,我手动改到了更准确(吗?)的5.8,貌似没多大区别。但是6.0的话就不行了。。。


2012年4月3日

连续在一件事情上做几天,收获还是非常大的

第一件要吐槽的事情一定是:波特率!

记住这句话:通信出了什么诡异的问题,先换个芯片试试~

对于计算机系的童鞋来说,出问题了先考虑外部的因素不是个好习惯。。。但是,,,写底层的程序是要跟硬件打交道的,如果程序貌似都对了,没改啥东西,就突然又不对了,,,那极有可能是硬件的问题了。。。

波特率。。。只要串口调试一出乱码,一定又是波特率的问题,就是这货没跑了!!!

曾经出过诡异的通信乱码的问题,当时没有完全搞清楚波特率的机制,不知道怎么就改好了,也没有记录下来,导致今天又浪费了几小时的时间。。。

导致今天串口通信乱码的原因是芯片的内部时钟不准确,之前都按照5.5296计算的波特率,STC11的内部时钟一般都在5.6或者5.7,误差小于3%的话就问题不大。但是今天遇到了2片神芯片,出厂时钟频率达到了5.82,误差超过了5%,直接就没法通信~另外一片是5.72,经常出错。我应该庆幸今天先遇到了那个5.82的,是这个根本没法通信的片子让我彻底研究明白了这个问题。如果我今天先用了那个5.72的,可以想象我现在还在查找程序的错误,冥思苦想为啥通信老是出现诡异的错误,而且还不一定啥时候出错。。。

想用5.82的那个芯片的话,就必须把波特率从115200降到19200甚至9600,否则误差太大。我知道9600的话数码管会闪的厉害,于是试了19200,发现数码管依然有轻微的闪烁,我又比较强迫,于是就放弃了降低波特率的方案。其实5.72的误差是3%多一点,大概是0.07个百分点吧,反正刚好骑在线上,就是多的这一点让通信时断时续。。。不知道3%的限制是怎么提出来的,实在是太牛了。。。

哦,STC宣传说,内部时钟很精确,温飘1%,常温下0.5%,从今天的结果来看,这个宣传貌似虚假宣传,仔细想想暗藏玄机。。。的确,对于同一个芯片,它的温飘是比较小的,应该在他说的范围内,但是不同芯片间的频率可能差别超过5%,这件事情不管是宣传页还是数据手册里都没提到。。。是啊,准确性是一回事,一致性是另外一回事了,对吧~可是我要多机通信啊!!!

开始还在想默认的5.5296这个数字是怎么来的,后来发现有一种晶振的频率就是这个。看来做高波特率的通信最好还是用外部晶振,内部时钟太不靠谱了。。。买晶振去。。。

1602液晶及其在Proteus里的仿真

首先,,,Proteus里的器件型号叫LM016L。。。

1602的程序网上有很多,但对的不多,写得好的就更少了。单就上电复位的时序,有十分之一的能写对就不错了。。。绝大部分程序都没有检测busy flag的代码,直接用delay延时一会儿,确保数据处理完。。。写的比较好的一个程序是汇编语言的,虽说汇编不会编,但是一林老师教过一些,看还是大概能看懂,很有帮助。。。

不过实际应用中的1602倒是很泼辣,就算程序写的比较烂,它也能识别出来。我的第一个错的离谱的程序,根本就没有上电复位,它还是能显示出字来(读了英文版的手册,其中说到复位是自动进行的,如果外围元件和电源的电气特性不好,上电复位可能会失败,这时候就需要手动用指令来复位,这也可能是很多程序没有复位的代码仍是正确的原因吧),而之后我的程序愈加趋向于正确时,它反而不理我了。。。

比较诡异的是,1602的模块没有像样的数据手册,后来下到了主控芯片的英文datasheet,里面讲解上电时序非常清晰,这才把模块初始化写的像模像样。

值得一提的是,它到底是上升沿执行命令还是下降沿执行命令。。。答案是毋庸置疑的:下降沿。但是你看网上的程序,有先E = 1E = 0的,也有反过来的,我猜想他敢把程序发上来,应该是可以用的,但为啥有两种相反的写法呢?这个要看使能信号E是长期保持高电位还是长期保持低电位。我比较喜欢的方式是长期高电位,数据准备好后,E = 0,给个下降沿,然后就测busy flag,搞定后重新E = 1。但正是这种代码,先置零再置一,给人一种上升沿触发的错觉,我开始也弄错了,后来又受到中文版山寨数据手册上时序图的误导,以至于错的一塌糊涂。。。

如何测busy flag,没写这个代码的人估计是出于两个原因,一是模块速度很快,可能一条指令是40微秒吧,delay一下就过去了。。。二是不会写,因为这一步数据手册上讲解的也很少。直到我开始写这篇日志之前,我对测busy flag的理解仍是错误的。我刚才写到一半,觉得说服不了自己,于是去读英文版的datasheet,,,对于测busy flag没有文字性的描述,只有一张时序图,耐着性子仔细看了一下,终于明白了。。。之前还要单独写个proteus版的代码,还以为是proteus的bug。。。现在终于统一了。。。

测busy flag的方法是:

  1. 将RS和RW位置为读指令(RS = 0RW = 1
  2. E给下降沿
  3. 测D7
  4. D7为零跳出,为一转到步骤2. 这里要特别注意,如果是忙状态,需要重新给下降沿

这个过程,在我看过的所有C代码中,还没有人写对。要么就是delay混过去,要么压根就是错误的. 唯一正确的是那个汇编的代码,估计大家都不会去看,于是真想就离我们越来越远。。。注意,只有这样写才既符合协议又能通过Proteus仿真

C51模拟PMW输出

想用单片机调液晶屏背光的亮度,于是就研究了一下怎么做脉宽调制。。。

在STC89C52RC上试了一下,参数是:
计时器0,8位自动重装,溢出时间52微秒
计数器,最大值64
频率:$ \frac{1}{(52 \times 10^{-6} \times 64)} $ 约等于300Hz

1
2
3
4
5
6
7
void tmr0_isr() interrupt 1 using 1
{
if(counter > pmw_val) P1 = 0xff;
else P1 = 0;
if(counter == RANGE) counter = 0;
counter++;
}

这个ISR比较短,就全文贴上来吧。。。

其实我还写了计时器1的ISR,用于自动的调整pmw_val,从而产生呼吸灯的效果。但是遇到了问题,张万祥大牛提示我要加上using。。。我加了,就好了。。。当时是谁告诉我using不加肯定不会错的。。。又是坑爹的网友吧。。。

还有,PWM真的很耗资源。。。因为52微秒,溢出的真的很快。。。我写了“呼吸流水灯”。。。加了呼吸,流水的速度估计要慢5倍左右吧。。。现在,我才理解了为啥那些芯片要宣传说带有PMW口,我当时还想呢,51用定时器也能做,干嘛要PMW口。。。

弱弱的说一下,,,STC官方的定时器计算器挺好用的,不用自己算溢出时间。。。还有,如果没用自动重装的计时器,别忘了要在ISR里重装。。。我当时忘了重装还说是不是STC计算的溢出率有错误。。。我弱爆了。。。

STC的自定义下载~~

很有爱的功能。因为STC总要掉电下载,很多人不堪其扰,制作出各种神棍的“自动掉电下载器”。。。有基于STC15做的,被黑心商贩卖出了三四十元的高价,有用继电器做的,听起来就凶残。。。其实STC提供了自定义下载,MCU接收到指定的信号,就软件复位到ISP程序区,开始下载。很多人嫌麻烦不愿意再加一坨串口的通信,由于我要做的东西正好都要用串口,所以就顺手加了几行代码~我用的是5c21作为下载置指令,翻译成字符就是\!,貌似下载指令不应该这么短的。。。但我貌似没发现问题。。。我的程序里用反斜杠作为转义字符,直接加了一个if,就搞定了~对了,复位到ISP的语句是IAP_CONTR = 0x60;(连这句话网上也有人写错。。。无语)如果不能编译,请自行检查头文件。。。需要用STC的头文件,reg51.h是不行的。。。

我在执行复位到ISP那句话之前,还在LCD上显示出Downloading…字样,由于1602是锁存的,所以这句话会一直显示在屏幕上,直到下载完成~非常酷~


2012年4月9日

舍友提醒我说,我已经“沉迷”一周了。。。
不过让人欣慰的是,基本的设计目标已经达成了,尽管经历了一些所谓的“坎坷”。。。

去买了晶振,串口通信稳定了

5.5296MHz的晶振貌似很不常用,中发很多专门卖晶振的摊位都没有这个频率。找到一家,我要十个,他说8毛,我扔给他5元钱,还等着找钱呢,结果人家说是1个8毛,我勒个去。。。后来找到了5毛的,其实应该2-3毛吧。。。

做了块STC11的扩展板

自认为最满意的一块板子,电路和焊接都很满意~上面还加了个按钮,用于在下载的时候给单片机掉电重启。从一条USB转232的线里拆出了一块USB的模块。。。那条线一米长加两边插头才5元钱,果然便宜没好货,还要加个MAX232做电平转换。。。

自动检测波特率,检测串口设备

这个程序写的挺满意的,我的温度传感板波特率是57600,而显示板是115200,我的目标是让扩展板插在任意一个端口,都能自动检测并工作。写了个uxUartProbe,实现了这个功能

received标志位没置零,调了很久

这种弱智的bug也能浪费很多时间,无奈了。。。

最后上一张图吧。。组合之后的数字温度计~数码管还可以换成1602液晶屏,协议是一样的,所以不需要改程序。


2012年4月22日

最近开发停滞了一下,事情也比较多,团队里的同学也大概熟悉了整个系统的架构,也都找到了各自的开发方向。现在矩阵键盘扩展板已经完成,步进电机和红外通信两块板子也都在进行中,估计也差不多了。

最近值得称道的事情就是TI的免费样片和超便宜的开发板了。去TI官网申请了MSP4302231和MSP4302302的免费样片,每个都给了2片。还申请了价值4.9美金的LM4F232,给了一片。联邦快递寄过来的,用防静电袋包装的,很给力的样子~~

单片机有了,还需要个开发板,淘宝上的板子价格也各种奇葩,于是自己到美国官网上订购了Launchpad G2开发板,只要4.3美金,还包国际邮费!开发板上是集成仿真器的,还随套件送2个单片机、2张贴纸还有晶振、USB线、排针啥的。实在是太超值了!让我百思不得其解是,仿真器那部分里面用到了一个价值8.55美金的芯片MSP430F1612IPMR,但整个套件才卖4.3美金啊!哪位高人知道的话告诉我一下。。。

吐槽一下我的中国银行借记卡,PayPal是支持银联卡充值的,但是只支持62开头的银联卡,我中行的不是62开头的。。。难道银联卡和银联卡还不一样嘛。。。神棍。。。只好到淘宝上找人,花了30元充了4.33美金,去TI eStore上支付了~

现在开发板已经发货了,静待到货喽~~


版权声明

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-electronic-bricks/