【太牛了】自制单片机开发板全过程(傻瓜式教程)-附下载!

-回复 -浏览
楼主 2020-09-15 14:30:14
举报 只看此人 收藏本贴 楼主

 

1.自制单片机之一……想法与计划

原文档"自制单片机开发板全过程(傻瓜式教程).pdf"下载方法地址请看文章底部第一条留言

学习了一段时间的51 单片机,也买了学习板,但总觉得在学习板上操作对元件引脚认识不那么深刻。学习板上的许多功能块元件密集,相互又牵扯,造成电路认识上的不清。在接扩展板时引线也不能集中成一组排线引出。商家也对他的原理图遮遮掩掩说一半留一半的。因此我打算拿起电烙铁,在通用板上先搭建起最小系统,再做出ISP 下载线,一步步的与愿和我一同上路的菜鸟们踏入C51 的世界。

昨天下午才汇了钱买洞洞板,没想到今天中午快递公司的人就把货送到我手上了。快的有点让我吃惊。等元件也到货后我便可以动手并上图与大家一同学习讨论了。

今天刚申请的空间,也试试发贴和上图。


2.自制单片机之二……AT89S51 最小系统制做

废话这里就不多说了,干活吧!

C51 最小系统电路在网上一搜一大把,大同小异。我略做改动后如图:

加一个11.0592MHZ 的晶振是为了以后做串口通信时和PC 有相同的波特率。可用短路帽切换。

说说板子的布局:网上卖的最小系统都是把板子做的非常小,如果仅仅只学习最小系统,那是可以的。我以后是要做扩展的,所以不能做的太小。因此该有的应留着,不该有的都去掉。很重要的是以后在做其它扩展功能块时的连接线就用一组排线而不能再有其它飞线。因此做一个好的布局是非常有必要的。

在板上除了最小系统外还有键盘输入、数码管、LCD、I2C 存储器。它们的数据接口和电源接口也是完全独立的。其它的功能都准备在以后通过上方的接口另外用板子扩展。

图上方的弯脚插针就是向外扩展的接口。我在弯脚下方又安排了一组直插针。它是和弯脚插针并行连接的。这样在扩展功能块时我先在AT89S51 板上将要输出的引线(包括数据线、控制线、电源线等)跳至直插针上。这样通过弯脚插针引到扩展板上的线就只有一组排线。不用再零乱地接上几组连接线了。这也是我用买的学习板常常垢病而最终弃而自制的主要原因之一。因为当时我扩展LCD12864,我既要连上数据线,又要连电源线,LCD 模块上还拖着背光电源限流电阻线。还有液晶驱动电压调节电位器。所以感觉拖的到处是线,很不方便。

实施:通过检查各元件的好坏后便进行焊接工作。焊接进行的还是比较顺利。见下图:

完成了。在检查了线路的正确性后,用万用表测了是否有短路。一切正常!

之前我的AT89S51 里已写好了个最小系统测试程序,就是让P1.0 上的红色发光管闪烁。

我把它先插在我买的学习板上运行,一切正常。但插在我做的的最小系统上却没反应。就那么点线路查来查去还是没问题呀!是晶振不起振?在学习板上用手拿着改锥分别碰18 脚(XTAL2)和19 脚(XTAL1)。发现当人体碰到19 脚时程序会乱掉,就是说可能会停振。于是又把我的系统板上晶振位置的电路重焊一遍,尽量缩短了19 脚处线的长度。C4、C5 又分别换了15PF、20PF、30PF 的电容试试。故障依然,没办法,得静一静,看书! 在看到介绍第31 脚(EA/VPP)时猛然想到31 脚没有接到电源正啊!起来立即把31 脚接到电源正,红色发光管立即闪烁起来。此时的高兴真不可名状啊!

总结:除了在焊接时要仔细外,先画好电路图也是很重要的。像上面的电路图在89S51 的31 脚上就只写了Vcc 的字样,因此焊接时就被忽视了。应该先画出一张完整的图才行。

检查分几个部分:1.晶振部分、2.复位部分、3.电源部分(最不可以忘掉EA 接V+5v),4.还有就是P1_0 发光管最基本的一个应用部分。

其实这个板子上的晶振电路是非常容易起振的。19 脚上的引线也没那么敏感。但处理19 脚时可能的话还是要尽量短些的,毕竟它比18 脚要对外界干扰敏感的多。手摸上去就停振了。

还有就是学习单片机怎么着也得先买块最最简单的板子。否则你焊好你的板子后有故障到底是程序问题还是线路问题就无从查起,查错查得还不疯掉呀! 程序也没法写进片子里去。你可能会说再做一个ISP 下载线呀。做下载线更加不稳定,下一篇我会专门讲做ISP 下载线的问题。再来个特写鼓励一下自己。

3.自制单片机之三……AT89S51ISP 下载线的制做

最小系统板做好了,接下来就是做根ISP 下载线了。否则程序怎么写到AT89S51芯片里呢?

先来认识一下AT89S51 上ISP(在线编程)功能脚的定义

看上图的左边AT89S51 引脚图的P1.5、P1.6、P1.7 的第二功能分别为MOSI(主机发送从机接收)、MISO(主机接收从机发送)、SCK(时钟脉冲信号由主机发送)。那什么时候才能启用第二功能呢?就是当复位脚RST 接高电平一直处于复位状态时就可用第二功能了,所以在ISP 下载板上有一条线接至AT89S51 的第9脚(RST)上,就是在写程序前先发一个高电平将S51 的RST 脚设为复位态,然后就可通过MOSI、MISO 向S51 内写程序了。

有网友问我的板子上ISP 线是如何定义的,我上图的右边就是我这个板子上的接法。ISP 十针接口的定义如下图


看见上图的实物接口边缘上的三角标记了吗?这就是第1 脚的标记,它的定义如上图的右边示意图。

在网上查了一下,ISP 下载线的种类主要取决于PC 端下载程序的种类。有并口的,有串口的,也有USB 的。串口和USB 的介绍较少而并口的介绍的很多,也比较简单。易于自己制做。并口的在网上也分为几类,原理都一样。主要是根据下载程序的不同。

1.这是Easy Isp-2 的配合软件为Easy 51Pro v2.0 宇宙版

这是他的简化版:

在网上的制做思路几乎都是把74HC373 放在并口头的小盒子内见下图:

但由于我的台式机放在桌子的下面,把74HC373 放在接头盒内插在电脑机箱后面怎么调试呢。因此我没将它放在接头盒内而是另用个洞洞板做的,前面是一米的并行线,后面是约50cm 的连接线。线路的焊接没什么问题,比较顺利。见下图:(因旧的已拆了,现在只是示意一下)Easy 51Pro


Easy 51Pro 2.0 的工作界面:

连上我的最小系统后,发现不能稳定工作。但可以读出89S51 的特征字,说明线路是好的

反复试验,不断在电源间加去偶电容,没什么效果,后来发现把连接排线握成一团握在手心里,就能有80%的机率正确写入程序,跟并口线那边关系却不大。莫非我要在排线上挂块肉,就像以前黑白电视的天线?

结论:读写不可靠。放弃!

因为这个下载程序不支持win98,我的笔记本是98 的不能用。因此这次我用了官方的下载线方案。配合软件为ISP-30a.

线路的原理还是差不多,焊接也没什么问题,这次可以支持笔记本,我省掉了并口线,将并口头直接焊在板子上。完工后的样子见下图。

现在它的并口端没有线了,直接插在了我的笔记本的并口上,启动程序,ISP-30A 界面见下图

状况同上一个下载线如出一辙,能读出特征字。读写也是几乎不成功,还是将排线揉成团握在手心里时,便能有八九十的读写正确率了。看来用哪个方案都是一样的,关键在布线上不同罢了。

我一不做二不休,狠狠剪短了排线,就剩下这么一点点引线,见下图:

再接上笔记本一试,你猜怎么着,正确读写率100%,成功了!

结论:各种方案都差不多,但在布线上,原来总是把元件装在并口盒内,而留一段连线到AT89S51 板上的想法是错误的。应尽量把从HC373 到AT89S51 板上的连线做短,最好HC373 就做在板子上,因为HC373 是三态输出,停用时OE 端是高电平,输出是高阻抗的,对系统板的独立性是没有影响的。而留的线应该是从PC 机到HC373 的并口线,这样的下载线作为自制来说才能有点实用价值。

第二天我把那段并口线又再连上后,接上笔记本再试,读写正确率仍为100%。下载线见图

样子虽不好看,但它是个皮实且易于自制的方案,在论坛里有人跟我说,把下载板上元件做好布线和抗干扰也能把下载板至AT89S51 板的引线做到1.5 米。我非常相信。但我没有示波器及其它测量设备,只有一块万用表。有简单易行的方案为什么不用呢!

4.自制单片机之四----数码管电路的制做与驱动

数码管的使用方法与发光二极管没什么区别,只是把七或八只发光二极管组合在一个模件上组成了个8 字和小数点,用以显示数字。为了减少管脚,把各个发光管的其中同一个极接在一起作为共用点,因此就产生了共阳极和共阴极数码之说。共阳管就是把各个发光管的正极接在一起,而共阴管就刚好相反。见下图:一般来说大部分的逻辑IC 的吸收电流要强于输出电流。因此,大家都爱

使用共阴极的数码管,因为可选的IC 多些。很可惜,我的这组数码管是共阳的,因此公共端我打算用三级管来驱动。

我的最小系统板:

我用最常用的S9012,首先我得计划好电路方式,就采用最常用的动态扫描显示。

先搭建最简电路,调试出需采用元件的参数。

先不接上图的R2 和74HC244,将数码管一个段直接接地。调节R1,测得S9012基极电流为0.21mA 时集电极也就是数码管上已有40mA,说明放大倍数足够了。这时接上R2 和74HC244,调节R2 使数码管电流控制在15mA,这样当8 个段一起点亮时三极管上得通过120mA 的电流。而基极上需要0.63mA,为了减小三极管的负荷应使三极管过饱和,,调节R1 使基极电流为2mA,此时测得集电极和漏极之间的电压约0.1V。好!此时R1 为2K。R2 为240 欧姆。确定。

接下来就是确定电路。电路的接口与AT89S51 间有三组接口:段码、位码和电源。为了让AT89S51 独立出来这三级接口都采用插针做接口,用排线自由连接到AT89S51 的P1-P3 口,电源用短路帽连接,完成后的板子见下图:

然后就是写程序。先写个查询方式的吧!

//六位管码管在以0.3 秒的间隔在闪烁,这是采用查询方式的,比较占CUP 资源

当我插把程序写入片子,插上电运行时,是乱码。你猜怎么回事?

原来那个P2 口方向是反的,您注意过没有,在AT89S51 管脚排列上,P0--P1 和P3 都是上方为PX_0。而唯独P2 口管脚排列是下方为P2_0。方向则好是反的。既然反了,我就把段码表重写一下。再试,一切正常。

在这里我说一下段码的排列,好多人问数码管段码是如何排列的,我也在网上查了,好像没有什么标准的排法,随自己的接法而定,这也是导致为什么在网上下载的一些数码管程序在自己的板子上不能正常显示的原因。就普遍而言我最上面的那张图示的标法最多,在上面程序里原打算也是P2_0 对应段码a(也就是上面的横)。一直到P2_7 对应段为h(就是小数点)。结果哪知道P2 口刚好是反的。这样一来也就是倒过来了,P2_0 对应段h(小数点了)。例如我原先定义的数码管显示“2”段码为10100100B 的,一接反了就不再是“2”了。而要想再显示“2”那就把段码的高低位倒过来。改为00100101B 就OK 了。

下面再写个用中断来显示的:

5.自制单片机之五……LCD1602的驱动

(1)……LCD1602的驱动

LCD1602 已很普遍了,具体介绍我就不多说了,市面上字符液晶绝大多数是基于HD44780 液晶芯片的,控制原理是完全相同的,因此HD44780 写的控制程序可以很方便地应用于市面上大部分的字符型液晶。字符型LCD 通常有14 条引脚线或16 条引脚线的LCD,多出来的2 条线是背光电源线VCC(15 脚)和地线GND(16脚),其控制原理与14 脚的LCD 完全一样,定义如下表所示:

HD44780 内置了DDRAM、CGROM 和CGRAM。

DDRAM 就是显示数据RAM,用来寄存待显示的字符代码。共80 个字节,其地址和屏幕的对应关系如下表:

也就是说想要在LCD1602 屏幕的第一行第一列显示一个"A"字,就要向DDRAM的00H 地址写入“A”字的代码就行了。但具体的写入是要按LCD 模块的指令格式来进行的,后面我会说到的。那么一行可有40 个地址呀?是的,在1602 中我们就用前16 个就行了。第二行也一样用前16 个地址。对应如下:

我们知道文本文件中每一个字符都是用一个字节的代码记录的。一个汉字是用两个字节的代码记录。在PC 上我们只要打开文本文件就能在屏幕上看到对应的字符是因为在操作系统里和BIOS 里都固化有字符字模。什么是字模?就代表了是在点阵屏幕上点亮和熄灭的信息数据。例如“A”字的字模:

上图左边的数据就是字模数据,右边就是将左边数据用“○”代表0,用“■”代表1。看出是个“A”字了吗?在文本文件中“A”字的代码是41H,PC收到41H 的代码后就去字模文件中将代表A 字的这一组数据送到显卡去点亮屏幕上相应的点,你就看到“A”这个字了。

刚才我说了想要在LCD1602 屏幕的第一行第一列显示一个"A"字,就要向DDRAM 的00H 地址写入“A”字的代码41H 就行了,可41H 这一个字节的代码如何才能让LCD 模块在屏幕的阵点上显示“A”字呢?同样,在LCD 模块上也固化了字模存储器,这就是CGROM 和CGRAM。HD44780 内置了192 个常用字符的字模,存于字符产生器CGROM(Character Generator ROM)中,另外还有8 个允许用户自定义的字符产生RAM,称为CGRAM(Character Generator RAM)。下图说明了CGROM 和CGRAM 与字符的对应关系。

从上图可以看出,“A”字的对应上面高位代码为0100,对应左边低位代码为0001,合起来就是01000001,也就是41H。可见它的代码与我们PC 中的字符代码是基本一致的。因此我们在向DDRAM 写C51 字符代码程序时甚至可以直接用P1='A'这样的方法。PC 在编译时就把“A”先转为41H 代码了。

字符代码0x00~0x0F 为用户自定义的字符图形RAM(对于5X8 点阵的字符,可以存放8 组,5X10 点阵的字符,存放4 组),就是CGRAM 了。后面我会详细说的。

0x20~0x7F 为标准的ASCII 码,0xA0~0xFF 为日文字符和希腊文字符,其余字符码(0x10~0x1F 及0x80~0x9F)没有定义。

那么如何对DDRAM 的内容和地址进行具体操作呢,下面先说说HD44780 的指令集及其设置说明,请浏览该指令集,并找出对DDRAM 的内容和地址进行操作的指令。

共11 条指令:

1.清屏指令

功能:

<1> 清除液晶显示器,即将DDRAM 的内容全部填入"空白"的ASCII 码20H;

<2> 光标归位,即将光标撤回液晶显示屏的左上方;

<3> 将地址计数器(AC)的值设为0。

2.光标归位指令

功能:

<1> 把光标撤回到显示器的左上方;

<2> 把地址计数器(AC)的值设置为0;

<3> 保持DDRAM 的内容不变。

3.进入模式设置指令

功能:设定每次定入1 位数据后光标的移位方向,并且设定每次写入的一个字符是否移动。参数设定的情况如下所示:

位名设置

I/D 0=写入新数据后光标左移          1=写入新数据后光标右移

S 0=写入新数据后显示屏不移动    1=写入新数据后显示屏整体右移一个字符

4.显示开关控制指令

5.设定显示屏或光标移动方向指令

6.功能设定指令

7.设定CGRAM 地址指令


功能:设定下一个要存入数据的CGRAM 的地址。

8.设定DDRAM 地址指令

功能:设定下一个要存入数据的CGRAM 的地址。

9.读取忙信号或AC 地址指令

功能:

<1> 读取忙碌信号BF 的内容,BF=1 表示液晶显示器忙,暂时无法接收单片机送来的数据或指令;当BF=0 时,液晶显示器可以接收单片机送来的数据或指令;

<2> 读取地址计数器(AC)的内容。

10.数据写入DDRAM 或CGRAM 指令一览

功能:

<1> 将字符码写入DDRAM,以使液晶显示屏显示出相对应的字符;

<2> 将使用者自己设计的图形存入CGRAM。

11.从CGRAM 或DDRAM 读出数据的指令一览

(2)……LCD1602的驱动

具体电路的制作是很简单的,就接了两个电阻,一个是10 欧姆的背光限流电阻,另一个是2K 的LCD 极板电压调节电阻。这两个电阻的阻值怎么定呢?背光比较简单,它就相当于在后面接了几个发光二极管,任何时候你只要在15、16 脚串上个100 欧的电位器接上电源,调节电位器,觉得亮度合适。此时的阻值便可。LCD 液晶极板驱动电压调节电阻的确定就稍微麻烦一点。在各数据线,控制线接好关通上电源的前提下在第3 脚(VEE)和地之间接一个10K 的电位器。调节电位器。当3 脚电压高时为全亮,电压为0 时为全暗(液晶全显示为黑块)。你用电位器把屏幕从全暗刚好调到变亮。这时便可调试程序。待屏幕能正确显示后再细调电位器,使对比度合适。这时的阻值便可确定,然后换成等值的固定电阻焊上便可。

我们接着上次的系统板制做:

新买的1602LCD,20 元,贵不?

反面:

组装后:

具体电路图:

接口说明:

运行:

用户自定义字符的应用:

我们从CGROM 表上可以看到,在表的最左边是一列可以允许用户自定义的CGRAM,从上往下看着是16 个,实际只有8 个字节可用。它的字符码是00000000-00000111 这8 个地址,表的下面还有8 个字节,但因为这个CGRAM 的字符码规定0-2 位为地址,3 位无效,4-7 全为零。因此CGRAM 的字符码只有最后三位能用也就是8 个字节了。等效为0000X111,X 为无效位,最后三位为000-111共8 个。

如果我们要想显示这8 个用户自定义的字符,操作方法和显示CGROM 的一样,先设置DDRAM 位置,再向DDRAM 写入字符码,例如“A”就是41H。现在我们要显示CGRAM 的第一个自定义字符,就向DDRAM 写入00000000B(00H),如果要显示第8 个就写入00000111(08H),简单吧!

好!现在我们来看怎么向这八个自定义字符写入字模。有个设置CGRAM 地址的指

令大家还记得吗?赶快再找出来看看。

从这个指令可以看出指令数据的高2 位已固定是01,只有后面的6 位是地址数据,而这6 位中的高3 位就表示这八个自定义字符,最后的3 位就是字模数据的八个地址了。例如第一个自定义字符的字模地址为01000000-01000111 八个地址。我们向这8 个字节写入字模数据,让它能显示出“℃”

下面我们写一段程序让这8 个自定义字符显示出一个心的图案:

实际效果如图:

6.自制单片机之六……LCD12864的驱动

LCD12864 的驱动

LCD12864 在市面上主要分为两种,一种是采用st7920 控制器的,它一般带有中文字库字模,价格略高一点。另一种是采用KS0108 控制器,它只是点阵模式,不带字库。很可惜,我的这块就是KS0108 控制器不带汉字库的,不过不打算用它专门显示文本,也就无所谓了。

具体电路图如下:

制做如下:

接口说明:

装上12864

具体的电路还是两个电阻。一个背光限流电阻。一个液晶驱动电压调节电阻。背光电阻还是任何时候在19、20 脚与电源之间串上个100 欧电位器接上电源。调节电位器到合适亮度。具体值最好是到调试完程序能够正常显示后再将阻值确定换成固定电阻。液晶驱动电压的调整在数据线、电源线接好的前提下是在Vee(-15v)和地之间接一个电位器。中间接V0,通过调节电位器来调节V0 上的电压。当V0 上为-15V 时为全暗(液晶显示为全黑)。当V0 为0V 时为全亮。调节电位器使屏幕从全暗刚好变到亮时,便可进行程序的调试。待屏幕显示正常后,进行对比度的细调,然后测量这两边的阻值在地和V0 之间、V0 和Vee 之间换成两个固定电阻焊上就好了。注意在V0 的电压是在一个很小的范围有效。我的就是在-2.2——-2.5 这个范围。仔细调节V0 和地之间的电阻使V0 上的电压在2.3V。

更换为固定电阻后的装配图:

下面说说具体的驱动:

先来了解一下LCD12864 的内部控制结构:见图

可以看出12864 屏是分为左、右两块控制的。所有对屏幕的操作要受片选CS1、CS2 来控制。

我们再来看一看对屏幕操作数据与屏幕点阵的排布关系:见下图。

从上图可以看出数据按字节在屏幕上是竖向排列的。上方为低位,下方为高位。因此在横向上(也就是Y)就一共是128 列数据。分为CS1 和CS2 两个64 列来写入。在竖方向上(也就是X)一字节数据显示8 个点,竖向64 个点分为8 个字节,称做8 页(X=0-7)。了解这些后我们就知道要满屏显示一张图就要从y=0…127、X=0…7 一共写128×8=1024 个字节的数据。同样在AT89S51 中存一张图就要1024个字节的空间。

好!下面我们来了解对LCD12864 进行操作的一些指令。

下面对上图的指作解释:

1.显示开关控制(DISPLAY ON/OFF)

D=1:开显示(DISPLAY ON) 意即显示器可以进行各种显示操作

D=0:关显示(DISPLAY OFF) 意即不能对显示器进行各种显示操作

2.设置显示起始行(DISPLAY START LINE)

1.写操作时序

2.读操作时序

时序参数表:

又帖了这么多指令呀时序图什么的,看了就头晕。我也和你一样不爱看这些枯燥的东西。

下面实际写些程序让屏幕亮起来。

运行:

7.自制单片机之七……LCD12864的驱动之源代码

今天将LCD12864 的源代码发上来。

本程序的实际效果图如下。

8.串行 I2C总线 E2PROM AT24CXXX的应用1

这一篇介绍I2C 存储器的使用。主要是介绍AT24CXX 系列器件,它分为两类,主要是通过被存储容量地址来分的,一类是AT24C02-AT24C16,它的存储容量从256 字节到2048 字节。另一类是AT24C32-AT24C1024,容量从4K-128K。(理论上好像可以达到最高512K 字节容量,但现在网上最高也就能看到AT24C1024也就是128K 字节容量)

原理:

I2C 总线是一种用于IC 器件之间连接的二线制总线。它通过SDA(串行数据线)及SCL(串行时钟线)两根线在连到总线上的器件之间传送信息,并根据地址识别每个器件:不管是单片机、存储器、LCD 驱动器还是键盘接口。

I2C 总线接口电路结构如图所示。

SDA 和SCL 均为双向I/O 线,通过上拉电阻接正电源。当总线空闲时,两根线都是高电平。连接总线的器件的输出级必须是集电极或漏极开路,以具有线“与”功能。I2C 总线的数据传送速率在标准工作方式下为100kbit/s,在快速方式下,最高传送速率可达400kbit/s。

在I2C 总线技术规范中,开始和结束信号(也称启动和停止信号)的定义如图所示。当时钟线SCL 为高电平时,数据线SDA 由高电平跳变为低电平定义为“开始”信号;当SCL 线为高电平时,SDA 线发生低电平到高电平的跳变为“结束”信号。开始和结束信号都是由主器件产生。在开始信号以后,总线即被认为处于忙状态;在结束信号以后的一段时间内,总线被认为是空闲的。

I2C 总线的数据传送格式是:在I2C 总线开始信号后,送出的第一个字节数据是用来选择从器件地址的,其中4-7 位为器件码,如1010 就是代表串行E2PROM器件。1-3 位为存储器的片选地址或存储器内的块地址码,如何区分?后面再做详细说明,第8 位为方向位(R/W)。方向位为“0”表示发送,即主器件把信息写到所选择的从器件;方向位为“1”表示主器件将从从器件读信息。开始信号后,系统中的各个器件将自己的地址和主器件送到总线上的地址进行比较,如果与主器件发送到总线上的地址一致,则该器件即为被主器件寻址的器件,其接收信息还是发送信息则由第8 位(R/W)确定。

一个字节的写操作的过程:首先器件发出起始信号后,发送器件识别控制字节,即1010A2A1A00(最低位置0,即R/W 读写控制位为低电平0),然后等待应答信号指示从器件被寻址。再发送一个AT24CXX 存储器将要写入的位置地址。再次等待AT24CXX 应答信号以后,将发送数据字节,AT24CXX 接收到后写入到刚刚指定的存储器地址。然后主器件再次等待AT24CXX 的应答信号。主器件最后发出停止信号。

在I2C 总线上每次传送的数据字节数不限,但每一个字节必须为8 位,而且每个传送的字节后面必须跟一个认可位(第9 位),也叫应答位(ACK)。数据的传送过程如图所示。每次都是先传最高位,通常从器件在接收到每个字节后都会作出响应,即释放SCL 线返回高电平,准备接收下一个数据字节,主器件可继续传送。如果从器件正在处理一个实时事件而不能接收数据时,(例如正在处理一个内部中断,在这个中断处理完之前就不能接收I2C 总线上的数据字节)可以使时钟SCL 线保持低电平,从器件必须使SDA 保持高电平,此时主器件产生1个结束信号,使传送异常结束,迫使主器件处于等待状态。当从器件处理完毕时将释放SCL 线,主器件继续传送。

当主器件发送完一个字节的数据后,接着发出对应于SCL 线上的一个时钟(ACK)认可位,在此时钟内主器件释放SDA 线,一个字节传送结束,而从器件的响应信号将SDA 线拉成低电平,使SDA 在该时钟的高电平期间为稳定的低电平。从器件的响应信号结束后,SDA 线返回高电平,进入下一个传送周期。I2C 总线还具有广播呼叫地址用于寻址总线上所有器件的功能。若一个器件不需要广播呼叫寻址中所提供的任何数据,则可以忽略该地址不作响应。如果该器件需要广播呼叫寻址中提供的数据,则应对地址作出响应,其表现为一个接收器。

5.总线竞争的仲裁总线上可能挂接有多个器件,有时会发生两个或多个主器件同时想占用总线的情况。例如,多单片机系统中,可能在某一时刻有两个单片机要同时向总线发送数据,这种情况叫做总线竞争。I2C 总线具有多主控能力,可以对发生在SDA 线上的总线竞争进行仲裁,其仲裁原则是这样的:当多个主器件同时想占用总线时,如果某个主器件发送高电平,而另一个主器件发送低电平,则发送电平与此时SDA 总线电平不符的那个器件将自动关闭其输出级。总线竞争的仲裁是在两个层次上进行的。首先是地址位的比较,如果主器件寻址同一个从器件,则进入数据位的比较,从而确保了竞争仲裁的可靠性。由于是利用I2C 总线上的信息进行仲裁,因此不会造成信息的丢失。

器件说明:

AT24CXXX 系列引脚图如下

现在我先来说说AT24CXX 的具体使用

假设用AT89S51 的P0.0 做SDA 总线,P0.1 做SCL 总线。有若干个I2C 器件挂接在SDA 和SCL 总线上。

现在要对E2PROM_01 存储器进行写字节操作看看它是如何找到的。

上面说过在发送完一个开始信号后接着发送一个字节的器件识别信号。这一个字节的4-7 位就是器件识别码。1010 就是对应E2PROM 器件,其它器件就不再理会了。1-3 位是器件的物理地址,也就是说如果是E2PROM,它可以在I2C 总线上挂接(000-111)8 个E2PROM。在这里就得详细说说AT24CXX 上的A0,A1,A2 和这个器件识别字节之间的关系了。上面说过存储器的寻址范围是一个字节,也就256 个,AT24C02 的存储容量为256 字字,刚刚好将一个字节的地址用完。器件电路上A0,A1,A2 三个管脚通过接高电平或低电平来和AT89S51 发送过来的器件识别控制字节相匹配,从而得以识别出AT89S51 将要操作的那个存储器。现在AT24C04 的容量是512 个字节,那不是一个字节的地址不够用了吗?其实它是将512 个字节为成两个页,每页256 字节,而页地址就是器件识别控制字节的1 位。前面说了这个1-3 位不是和器件上的A0,A1,A2 匹配来识别器件的吗?是的,但存储器容量超过256 字节情况就有变了。AT24C04 上的A0 这时就废弃不用了,只用A1 和A2,这样就只能接(00-11)四个AT24C04 了,同样AT24C08容量为1K 字节分为4 页了,于是页地址就是器件识别控制字节的1-2 位,器件上的A0,A1 废弃不用,只用A2,就只能接两个AT24C08 了。AT24C16 容量为2K字节,分为8 页。页地址是器件识别控制字节的1-3 位,全用了。器件上的A0,A1,A2,就无效了,只能接一只AT24C16。

我这么说能明白吗?

对于大容量AT24C32-1024 的存储器。器件的存储寻址地址为两个字节,所以它的一页为65536(64K)。AT24C32-64 的容量为4K 字节-8K 字节,在一页范围,可以接8 只器件。从AT24C128-1024 的器件代号也由1010 改为10100,多了一位,识别控制字节的器件物理地址就少了一位,变为1-2 位,相应的在器件管脚上A2 也废弃空着了,因此最多只能接四只器件。AT24C128-512 只有两位器件地址所以最多只能接四只器件。而AT24C1024 的容量为128K,分为两页,识别控制字节的的1 位为页地址,器件的A0 脚废弃不用,只用了A1。因此只能接2 只器件。

下面我们进行具体的制做先准备好器件如下图,我用的是AT24C16


原先的板子如下图

焊好后。


好!下面我们进行调试:插上主电源。但AT24C16 的电源短路帽不接,在短路帽两个针之间接上万用表的电流档检查是否有短路和静态电流的大小。实测静态电流几乎为零,改变两个数据线的电平时,电流会有所上升,说明电路基本正常。

现在我们接上电源短路帽把AT24C16 电源接好。将两个数据线用跳线接到P1.6和P1.7 口上(接到哪个口上可以自己选的)。注意分清哪个是SDA 哪个是SCL。别弄错了。


把LCD12864 装上,后面我们就要进行软件的调试了。

接下来,我们进行软件件部分的调试。

对代码进行编译成HEX 文件写入S51 后运行:


重新编译后写入S51 芯片运行:

第一幅:

第二幅:

OK,成功!这次"iic test"这行字符是从AT24C16 内读取的。你可以试着拔掉那两根SDA,SCL 的数据线,再按下复位键重新运行,你会发现那行“iic test”没有显示了。说明没有读取到数据。再装上数据线,重按复位键运行,又正常了。后面就可以将存储在S51 代码段的字模,图形数据等,都写到AT24C16 里了。

在网上找到一个写的不错的读写AT24CXXX 的通用程序函数,也很好用,程序见下面:

但实际使用中发现它有个严重的错误。就是没有考虑到不同的I2C 器件在写页操作时,是有一页数据限制的,AT24C01 是8 个字节,AT24C02-16 是16 个字节,AT24C33-64 是32 个字节。AT24C128-256 是64 个字节。AT24C512 是128 个字节。AT24C1024 是256 个字节。

这是器件说明书上的资料,我手上只有AT24C02、AT24C16 和AT24C256,实际使用了一下,AT24C02 的页限制是8 个字节。另两个是和说明书上一致的。当我写的数据量超出页限制时,地址指针就会回到起始点覆盖原来的数据。例如我以页方式写10 个字节的数据到AT24C02 时。前8 个字节的数据正常写入,第9、第10 个数据就回头覆盖掉了第一、第二个数据。

你如果把265 个字节的数据往AT24C02 进行写页操作,它也不报错,就一个劲地反复覆盖你8 个字节的空间,再比如你往AT24C256 里输入一个字节的地址,或往AT24C02 里输入两个字节的地址,它也不报错,就这么胡乱地把地址当数据或把数据当成地址往里一阵乱写。当你读取数据时才发现里面混乱不堪。这使得上面那个读写AT24CXXX 器件的程序怎么运行都不会出错。我觉得这是AT24CXX器件设计上比较弱智的地方。

所以上面的程序得修改

12.板子上的最后一个部件--RS232串口

在我的板子上其它的部分都已完成了,现在就剩下RS232 串口了。串口对于单片机很重要,有了它就可以和PC 通信了,可以用PC 来控制你的单片机,也可以将你单片机上采集的数据传到PC 上。

留的位置好像有点挤。得把上面的复位钮挪一挪

先得搭建个临时电路试一试,MAX232 结构图和电路图如下:

电路图:

搭建的实际元件图如下:

检查无短路现象后接上电源。

注意,我已将板子上的晶振用短路帽跳接至11.0592MHz,这样才能将波特率设置为19200。这是在12MHz 的状态:

下图是跳至11.0592MHz 的状态。

在电脑上将程序写好,编译后用ISP 写入S51。程序很简单,就是不停地向PC传送“hello World!”。程序如下:

在PC 上启动串口调试器,将波特率调为19200,打开串口。然后按一下单片机上的复位钮。如下图:

电路运行正常。后面就是要把电路焊到板子上了。

焊好后的板子。

8.本文原文档PDF版下载方法

原文档"自制单片机开发板全过程(傻瓜式教程).pdf"下载方法地址请看文章底部第一条留言!


电源界第一大公众平台50000+电源工程师关注电子研发精英圈

点击左下角“阅读原文”加入张工子弟社

我要推荐
转发到