前两天第一次学习51单片机的串行口,学习到串口控制LED灯这个程序,当时看着视频教程,觉得程序看懂了,然后按照它提示的步骤写好程序并烧录到单片机,发现单片机发送和接收的数据不一致。
当发送aa和ff的确可以全亮或者全灭。并且低四位的LED灯能准确控制,就是当发送01到0f都能正确显示。
但当发生的数据的高四位不为0时,LED灯就不能准确显示了。比如当我发送是1f时,理论来说,LED灯应正确显示00011111,就是第六、第七位、第八的灯会亮。而实际上它显示是:3f,也就是00111111。 再比如我发送是3f,而实际上LED灯显示的是01111111.就是只有最高位亮,其他都是灭的。
我重复检查依然没有发现程序有错,也想不到哪里的地方会出错,很纠结。
接着我联系卖家,卖家说也不清楚,叫我重启计算机,也没解决,又说光盘附带的程序是错的,你自己修改,还鼓励我自己解决问题。当时就囧了、、、问同学,同学说不知道;去论坛问,可发了帖子后很久还没回复;去了Q群问,群友问我的晶振是多少,我说12M,他们就说可能是晶振的问题,因为做串口实验最好用11.0592M的晶振,用12M的会产生误差。我立马再去询问卖家,他又说我们的板子是没问题的,应该不会是晶振问题,不过还是叫我试试。我立马换了11.592M的晶振,问题立马解决了!!兴奋了一番,再打开论坛,发现有了回复,觉得回复者回复得很详细,再次感谢一番!!
回复如下:
你的晶振是多大了啊?如果是12MHz的话波特率在9600的时候的误差可达8.5%,也就是波特率误差太大了,所以单片机接收到的数可能会错其中的一位或两位。你举的例子里错的也都是一位或两位,而0xFF因为都是1,所以没错,0x80就一位是1,其他都为0,出错的机会也就少了。我觉得这样的解释算是比较合理的。
用12MHz晶振的时候就1200和600的波特率误差还小一些,只有0.16%。你可以把波特率换成1200试一下。这个时候TH1的值应该为0xE6。你可以试一下,如果使用9600的波特率的话必须使用11.0592MHz的晶振,一般用51做串口通讯的都是用这个频率的晶振的,因为这个频率的晶振就是为了做51通讯而专门算出来生产的。
其实我看书的时候也知道用11.592M的晶振会更好的,不过课本以及视频教程都没有强调,而且课本的例题也是用12M的晶振的,所以出现问题后我也没有意识到是晶振的误差问题。不过还好,在不停的询问后问题解决了。
不过我这次也意识到自己没有养成遇到问题应该首先百度的习惯,如果我首先百度了,可能会更快地解决问题,因为刚刚我再将我的问题百度了一下,发现同样的问题其实已经有人解答过的了,如果我看了,也许就有所启发而解决问题。