注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

The Bloom of Youth

本博客已搬家至http://kuangqi.me

 
 
 

日志

 
 

电子积木开发手记2  

2012-04-03 23:04:56|  分类: 软硬兼施 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
连续在一件事情上做几天,收获还是非常大的

1. 第一件要吐槽的事情一定是:波!!特!!率!!!
记住这句话:通信出了什么诡异的问题,先换个芯片试试~
对于计算机系的童鞋来说,出问题了先考虑外部的因素不是个好习惯。。。但是,,,写底层的程序是要跟硬件打交道的,如果程序貌似都对了,没改啥东西,就突然又不对了,,,那极有可能是硬件的问题了。。。
波特率。。。只要串口调试一出乱码,一定又是波特率的问题,就是这货没跑了!!!
曾经出过诡异的通信乱码的问题,当时没有完全搞清楚波特率的机制,不知道怎么就改好了,也没有记录下来,导致今天又浪费了几小时的时间。。。
导致今天串口通信乱码的原因是芯片的内部时钟不准确,之前都按照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这个数字是怎么来的,后来发现有一种晶振的频率就是这个。看来做高波特率的通信最好还是用外部晶振,内部时钟太不靠谱了。。。买晶振去。。。

2. 1602液晶及其在Proteus里的仿真
首先,,,Proteus里的器件型号叫LM016L。。。
1602的程序网上有很多,但对的不多,写得好的就更少了。单就上电复位的时序,有十分之一的能写对就不错了。。。绝大部分程序都没有检测busy flag的代码,直接用delay延时一会儿,确保数据处理完。。。写的比较好的一个程序是汇编语言的,虽说汇编不会编,但是一林老师教过一些,看还是大概能看懂,很有帮助。。。
不过实际应用中的1602倒是很泼辣,就算程序写的比较烂,它也能识别出来。我的第一个错的离谱的程序,根本就没有上电复位,它还是能显示出字来(读了英文版的手册,其中说到复位是自动进行的,如果外围元件和电源的电气特性不好,上电复位可能会失败,这时候就需要手动用指令来复位,这也可能是很多程序没有复位的代码仍是正确的原因吧),而之后我的程序愈加趋向于正确时,它反而不理我了。。。
比较诡异的是,1602的模块没有像样的数据手册,后来下到了主控芯片的英文datasheet,里面讲解上电时序非常清晰,这才把模块初始化写的像模像样。
值得一提的是,它到底是上升沿执行命令还是下降沿执行命令。。。答案是毋庸置疑的:下降沿。但是你看网上的程序,有先E = 1再E = 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 = 0,RW = 1)
(2)E给下降沿
(3)测D7
(4)D7为零跳出,为一转到步骤(2)  这里要特别注意,如果是忙状态,需要重新给下降沿
这个过程,在我看过的所有C代码中,还没有人写对。要么就是delay混过去,要么压根就是错误的. 唯一正确的是那个汇编的代码,估计大家都不会去看,于是真想就离我们越来越远。。。注意,只有这样写才既符合协议又能通过Proteus仿真

3. C51模拟PMW输出
想用单片机调液晶屏背光的亮度,于是就研究了一下怎么做脉宽调制。。。
在STC89C52RC上试了一下,参数是:
计时器0,8位自动重装,溢出时间52微秒
计数器,最大值64
频率:1/(52 * 10^-6 * 64) 约等于300Hz
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不加肯定不会错的。。。又是坑爹的网友吧。。。

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

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

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

我在执行复位到ISP那句话之前,还在LCD上显示出Downloading...字样,由于1602是锁存的,所以这句话会一直显示在屏幕上,直到下载完成~非常酷~
  评论这张
 
阅读(1079)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017