搜索
bottom↓
回复: 8

一种24064与51接口的深入研究(利用引脚第二功能)

[复制链接]

出0入0汤圆

发表于 2010-8-15 03:56:37 | 显示全部楼层 |阅读模式
为了测24060的硬件功能,在网上找了个现成程序进行测试,发现程序的接口定义很特别,分析一下,果然很有看头,程序重点部位如下:

//                    CA24064
//***************************************************************************
//*  Create by :Ssmart   2004/12/01       KeilC V7.0                           *
//***************************************************************************
//连线表:  CPU=89C52                                                        *
//C/D=P2.0           /CE=P2.7            FS=P3.5         /WR=/WR   /RD=/RD  *
//FOSC=12MHz         D0-D7=P0.0-P0.7     /RSET=/(CPU RSET)            *
//***************************************************************************
#include <reg52.h>
#include <intrins.h>
#include <stdio.h>

#define uint  unsigned int
#define uchar unsigned char
#define Graphic            1
#define TXT            0
#define LcmLengthDots            240
#define LcmWidthDots            64

char xdata LcmDataPort _at_ 0x0000;
char xdata LcmCmdPort  _at_ 0x0100;
sbit FS = P3^5;
sbit Key= P3^4;


连线表倒是说得很清楚,可是通常的接口定义这里只有见到两个

sbit FS = P3^5;
sbit Key= P3^4;

其他的哪去了?既然没有用代码指定,那就是利用CPU的某种自动功能了,没错,这里利用C51读取外部数据RAM时,P0(数据输入输出、地址总线低8位输出)和P2的地址总线输出和P3的第二功能(WD、RD)


预备知识:

1.先分析下面两行代码,看看它做了什么

char xdata LcmDataPort _at_ 0x0000;
char xdata LcmCmdPort  _at_ 0x0100;


xdata存储类型标识符指外部数据区64K字节内的任何地址,为什么要把变量指定为外部数据区?

_at_用来把变量定位一个绝对的存储地址,用法如下
type [memory_space] variable_name _at_ constant
这里
memory_space 变量的存储空间如果在声明中没有则使用缺省的存储空间缺
省的存储空间参考94页的存储模式
type 变量类型
variable_name 变量名
constant 定位变量的地址
_at_后面的绝对地址必须在可用的实际存储空间内Cx51 编译器检查无效的地址标
识符

这两行代码就是定义了两个char型的数据LcmDataPort和LcmCmdPort,它们被指定为保存在外部数据区内的变量,地址分别为0x0000和0x0100,注意它们都是16位地址。

从字面意思看LcmDataPort的意思是数据端口,LcmCmdPort是命令端口


2.P0 P2 数据、地址总线功能和P3口的替代功能

P0可进行数据输入输出和16位地址总线的低8位输出,P2为可进行16位地址总线的高8位输出,P3口的WR和RD是重点,我们详细讲它,P3比 P2在结构上多了一个与非门,与非门的另一个输入替代输出功能信号,在对外部数据RAM进行操作时,CPU会自动安排P3.6(WR )P3.7(RD)的时序,换句话说就是RD和WR信号由CPU自动产生,不需要使用软件模拟。


DPTR是数据指针,主要用来保存16位地址,当执行MOVX时,CPU会自动安排WR和RD电平的高低,具体可以看51的时序图。在读外部RAM 时,MOVX     A,@DPTR,把DPTR地址的数据(读PO口得到)放入累加器中,这时候WR为高,RD为低(低电平有效),反之,写外部RAM时MOVX     @DPTR,A,把累加器A中的值写到指定地址(写P0口),这时候WR为低,RD为高。

特别说明一下,这个过程在KEIL的DUBUG里是看不到的。


下面开始分析代码:

我写了几行C测试代码,来看看与汇编的对照

   262:          i=LcmDataPort;
C:0x07C3    900000   MOV      DPTR,#C_STARTUP(0x0000)
C:0x07C6    E0       MOVX     A,@DPTR
C:0x07C7    F508     MOV      0x08,A
   263:          LcmDataPort=0x00;
C:0x07C9    E4       CLR      A
C:0x07CA    F0       MOVX     @DPTR,A
     264:          LcmCmdPort=0x0f;
C:0x07CB    900200   MOV      DPTR,#LcmCmdPort(0x0100)
C:0x07CE    740F     MOV      A,#0x0F
C:0x07D0    F0       MOVX     @DPTR,A


我们分析前两条就够了:

262行代码:LcmDataPort前面我们分析过了,它被指定为保存在外部数据区内的变量,地址为0x0000,先用MOV把要访问的地址0x0000送入DPTR,然后用MOVX把DPRT指定地址内的数据送入累加器A。这期间RD自动变为低电平,T6963的RD也是低电平有效,且与MCU的RD连接,这样就自动实现了对LCD读\写的操作,省去单独指定IO脚用软件操作。

264行代码:先把0x0100送入DPTR,再把要写的值0x0f送入A,最后用MOVX把A中的值写到DPTR指定的地址中。这期间是WR自动变为低电平,相应的T6963C的WR也变为低电平,对应写操作。

263行和264行代码一样,为什么转成的汇编不一样呢?这就是编译器的优化啦,263行我们写的值是0x00,反正最终送到ACC的值是0,直接把它CLR不是更省事?看啊,分析代码是非常有趣而且能学到东西的事情。

注意:对外部RAM操作时,总是先向P0和P2送地址,保持一段时间,然后再通过P0读或写数据


这样特别的接口定义方式仅仅是为了省C里的几句代码?当然好处不止这些,别忘了T6963还有个C/D,命令/数据选择,LcmDataPort和 LcmCmdPort只是指定的地址不一样,怎么在操作这两个变量的同时实现对C/D的操作的呢?秘密就在它们外部地址的值上:0x0000,0x0100.

T6963C的CD接到了P2.0上,高电平对应命令,低电平对应数据。对外部RAM操作时,总是先向P0和P2送地址,保持一段时间,然后再通过P0读或写数据,那么LcmDataPort送的是0x0000,P0和P2都是0x00,P2.0是低电平,刚好对应DATA;LcmCmdPort送的是0x0000,P0都是0x00,P2是0x01,P2.0是高电平,刚好对应COMMAND。这就实现了对CD的自动设置。

这两个地址还是有意取的值,根本不存在这两个地址,更别说有个鬼的外部RAM,这里只是利用了51操作外部RAM时的特性。前面提到KEIL的手册里说_at_后面的绝对地址必须在可用的实际存储空间内Cx51 编译器检查无效的地址标识符,看来不守规据有时也能成大事。


我们再稍微深入一点,想想这两个地址还能取哪些值,在CD所接引脚确定的情况下,只要符合以下两条要求的地址都行:

1.LcmDataPort对应的“地址”不能影响CD对应引脚,相应位必须为0

2.LcmCmdPort对应的“地址”在CD所接引脚的对应的位必须为1


再往深考虑,WR RD值是自动设置的,那保持时间够不够6963用?前面还说了先送地址再读写数据,那地址保持时间够不够用?查51的DATASHEET,WR和RD脉宽最小值TRLRH TWLWH均为1675ns,再查T6963C的DATASHEET,WR和RD的要求脉宽的最小值是60ns,完全完全足够。P0和P2的地址保持时间也满足T6963C的要求。

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2010-8-15 10:15:33 | 显示全部楼层
浪费了七个脚

出0入0汤圆

发表于 2010-8-15 11:15:39 | 显示全部楼层
在扩展外部存储器时经常用,把C/D放在锁存器的输出还可以省一个IO口

出0入0汤圆

 楼主| 发表于 2010-8-15 11:25:27 | 显示全部楼层
回复【2楼】hujh3116
在扩展外部存储器时经常用,把c/d放在锁存器的输出还可以省一个io口
-----------------------------------------------------------------------

是的,但我的ALE没引出来。估计很多业余的新手都是像我这样直接学C,对单片机的硬件结构不是太了解,所以我把分析得到的东西写出来。

出0入0汤圆

 楼主| 发表于 2010-8-17 02:51:20 | 显示全部楼层
回复【3楼】skystalker  
回复【2楼】hujh3116
在扩展外部存储器时经常用,把c/d放在锁存器的输出还可以省一个io口
-----------------------------------------------------------------------
是的,但我的ale没引出来。估计很多业余的新手都是像我这样直接学c,对单片机的硬件结构不是太了解,所以我把分析得到的东西写出来。
-----------------------------------------------------------------------

应该是不能把CD接到ALE上

出0入0汤圆

发表于 2010-8-17 21:39:22 | 显示全部楼层
标记

出0入0汤圆

发表于 2013-8-26 21:02:17 | 显示全部楼层
学习学习.............

出0入0汤圆

发表于 2013-8-26 21:47:43 来自手机 | 显示全部楼层
学习一下.........

出0入0汤圆

发表于 2013-8-30 15:08:55 | 显示全部楼层
学习一下,增长了见识。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 05:21

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表