关于51单片机P2口做地址总线和一般IO口的问题(P2):路过的大神们,进来看下!main 函数(0,1,2,3)在3楼,1602函
关于51单片机P2口做地址总线和一般IO口的问题(P2):
路过的大神们,进来看下!
main 函数(0,1,2,3)在3楼,1602函数在1楼,2楼是一个工程头文件
问题描述:
C/C++ code#include <reg52.h>#define uchar unsigned charuchar xdata volatile TEST _at_ 0xff00void main(void){ P2 = 0x20; TEST = 0x00; //TEST _at_ 0xff00 //上面一句执行完后P2口的输出是多少? 0xff or 0x20 ? //如果是 0x20,是怎么实现的?执行 TEST = 0x00的时候 MOV DPH,#0ffh ;MOV DPL,#00h, // CLR A,然后,MOVX @DPTR,A,执行 MOVX @DPTR,A的时候 P2输出为0xff //但是执行完后怎么又成了 0x20了? 0x20是我用proteus 仿真的结果,不解? //要使这样的话,P2口可以即作地址总线,同时做IO口,比如控制1602的引脚RS,WR, //只是中间 会有数据晃一下 ,只要保证1602的 E (用非P2口控制)引脚在执行MOVX @DPTR,A前后一直 //都为低电平 就行 ?可以这样吗? while(1);}
基于上面的问题,我想寻求一个好的方法:
我的单片机想接较多 的外设,需要地址扩展, 我想用P2的低3位通过38译码器来选择不同的片,(有8255,ADC0809,LCD1602等等,还有其他的片),P0经373锁存器 选择各个片内部的通道(如,8255的的几个口,ADC的 0~7 8个通道)但是 有一个问题:1602 有E RS RW 三个引脚, 1602读写时要求先 设置好RS RW 引脚,再将E引脚置为高电平
所以我 用 51的WR,RD引脚和P2低三位经38译码器输出的CS_LCD引脚 逻辑组合产生E引脚信号,E为高电平时(即CS_LCD为低,读写信号为低),RS RW 引脚已由 P0口经373锁存器的低两位(A0,A1)输出, 这样连接行吗?
还有什么好的统一编址 的方法吗?
想 清爽一点,写程序 可以直接定义 uchar xdata volatile LCDcmdWR _at_ 0xf800(高字节低三位 译码后 与WR,RD 选择LCD_E引脚,低字节低两位00(RS,RW) 即指令寄存器写操作),这样 往1602写命令的时候就可以直接 LCDcmdWR = 0xXX; 了,但是 程序写出来 1602却没有显示, 是1602初始化 有问题吗?程序在下面!是不是E引脚时间不够啊?波形图如下:
程序在下面:
[解决办法]虽然不想看lz的问题。
但是lz的态度值得表扬,程序、图片排版很好,赞下!
[解决办法]1)扩充片选,通常使用P2口的高3位地址线,外接74138。这样,将64K空间分成8个8K,138的每一条输出对应8K空间,且每一个8K的地址是连续的(用P2的低3位,8K空间就不连续了)。
2)P2要么作为地址线用,要么作为I/O口用,混用的话,很容易相互干扰。
3)上述(1)的做法是译码法做片选。还有一种做法是线选,还是用P2的最高几位,例如用高6位做片选。当P2.2~P2.7某一线输出高,通过反相器,可以选中某一片外设。一共可选6片外设,每条片选的地址区域是2^10=1K。
[解决办法]通常P2口的高地址线只在ALE有效时才输出,过了ALE就恢复到IO口的值。