5669|17

63

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

请51高手进入赐教。 [复制链接]

大家都知道51核心的引脚寄存器定义“reg51.h”内容:
/*  BYTE Register  */
sfr P0   = 0x80;
sfr P1   = 0x90;
sfr P2   = 0xA0;
sfr P3   = 0xB0;
其,P0~3的数值都为0x00~0xFF范围,
可是我现在的困难是,我想将P0.1~P0.0定义为一个寄存器为P00,数值范围为0~3H,P0.3
~P0.2为P01,范围也为0~3H,同理,P0.7~P0.6的数值范围为0~3H,
请问这样怎么定义P00~P03的寄存器呢?

最新回复

" c=d=0;"楼主这样有错吧,应该改为c=0; d=0;  详情 回复 发表于 2010-1-18 22:48
点赞 关注

回复
举报

85

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
51指令系统有字节操作与位操作指令,但没有你需要的二位操作指令,所以你这个目的无法实现。

sfr这个关键字不是定义而是重命名了一个寄存器。
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
使用typedef定义类型:


  1. typedef struct
  2. {
  3.         unsigned char ucSyncHead;    //同步头:0xfa
  4.         unsigned ucMachineNo:3; //目标地址。000~011-从机地址;100-主机地址;101-广播。
  5.         unsigned ucSourceNo:3;  //源地址。000~011-从机地址;100-主机地址;101-广播。
  6.         unsigned ucTokenID:2;   //令牌ID(2Bit)

  7.         unsigned ucPrimaryId:3;  //拥有优先权的从机ID(3Bit)
  8.         unsigned ucCmdCode:5;    //帧序号

  9.         unsigned char ucSndData[DATA_LENGTH]; //数据区, 长度为4个字节。
  10.         unsigned char ucChkSum; //校验和。
  11. }CommFrame;
复制代码

上例中,ucTokenID就是你需要的定义了,超出范围的赋值是没有意义的了
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

4
 
你这个头文件应该是KEIL中
自带的头文件

KEIL中常用的定义
有特殊寄存器定义sfr
和位定义sbit

具体用法就是
sfr P0  = 0x80;
sbit P0_0 = P0^0;

其中sfr,sbit应该是KEIL
内部封装好的命令
KEIL中没有现成的
可以完成楼主那种操作的命令

楼主可是使用sbit
一位一位的操作
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

5
 
这样的办法很多。
当然一个一个的用位操作也可以。

另外也可以实现一个子函数,
这样比较方便。
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

6
 
写个位操作函数就可以解决问题了,没有必要搞那么麻烦
 
 
 

回复

84

帖子

0

TA的资源

一粒金砂(初级)

7
 
"我想将P0.1~P0.0定义为一个寄存器为P00,数值范围为0~3H,P0.3
~P0.2为P01,范围也为0~3H,同理,P0.7~P0.6的数值范围为0~3H,"如果是单独的位地址定义或是字节地址定义是可以的,但是楼主你“P0.1~P0.0”两个位合成一个再定义是不可能实现的,
比如你可以用sbit P0.1 00h ,sbit P0.0 01h,这样编译器就会为你在ram的位寻址去开辟对应的两个位地址区
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

8
 
sfr P0  = 0x80;
sfr P1  = 0x90;
sfr P2  = 0xA0;
sfr P3  = 0xB0;
这个0X80------0XB0是P0----P3的地址 是51单片机决定的

P0~3的数值都为0x00~0xFF范围, 因为每个IO口有8位 所以数据是一个字节 0x00----0xFF

将P0.1~P0.0定义为一个寄存器为P00,数值范围为0~3H
P00=P0&0x03  现在P00就是低两位P0.1 P0.0   数据范围0x0---0x03

P0.3~P0.2为P01,范围也为0~3H
P01=(P0&0x0C)>>2 现在P01就表示P0.3 P0.2    数据范围0x0---0x03

P0.5~P0.4为P02,范围也为0~3H
P02=(P0&0x30)>>4 现在P02就表示P0.5 P0.4    数据范围0x0---0x03

P0.7~P0.6为P03,范围也为0~3H
P03=(P0&0xC0)>>6 现在P03就表示P0.7 P0.6    数据范围0x0---0x03

定义P00~P03  就是普通的变量就可以了 unsigned char P00,P01,P02,P03;
 
 
 

回复

67

帖子

0

TA的资源

一粒金砂(初级)

9
 
无法按楼主的要求定义寄存器,但可以通过结构体赋值的方式实现
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(高级)

10
 
写两函数实现
void SetP00(unsigned char nVal)
{
P0=nVal&0x03;
}
unsigned char GetP00()
{
return P0&0x03;
}
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

11
 
51没有办法半字节寻址

直接用函数封装是可以的

同样在,也可以用结构里的位域来解决字节中的区域问题

具体问题你可以先找一下位域的知识
 
 
 

回复

62

帖子

0

TA的资源

一粒金砂(初级)

12
 
没法弄
 
 
 

回复

83

帖子

0

TA的资源

一粒金砂(初级)

13
 
虽然那不是寄存器,但是这样的还是可以实现的啊,汇编的话 开辟存储单元 C的话 就 用一个变量 是可以表示的啊
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

14
 
感谢各位的指教,我突然想到这个简单的方法来实现,但请大家帮忙看看,是不是还有很多问题?
sbit a=P0^0;
sbit b=P0^1;
sbit c=P0^2;
sbit d=P0^3;
sbit e=P0^4;
sbit f=P0^5;
sbit g=P0^6;
sbit h=P0^7;


void P00(unsigned char dat)
{
  switch(dat)
  {
        case 0x00:
          a=b=0;
        break;
        case 0x01:
          a=1;b=0;
        break;
        case 0x02:
          a=0;b=1;
        break;
        case 0x03:
          a=1;b=1;
        break;
  }

}
void P01(unsigned char dat)
{
  switch(dat)
  {
        case 0x00:
          c=d=0;
        break;
        case 0x01:
          c=1;d=0;
        break;
        case 0x02:
          c=0;d=1;
        break;
        case 0x03:
          c=1;d=1;
        break;
  }

}
void P02(unsigned char dat)
{
  switch(dat)
  {
        case 0x00:
          e=f=0;
        break;
        case 0x01:
          e=1;f=0;
        break;
        case 0x02:
          e=0;f=1;
        break;
        case 0x03:
          e=1;f=1;
        break;
  }

}
void P03(unsigned char dat)
{
  switch(dat)
  {
        case 0x00:
          g=h=0;
        break;
        case 0x01:
          g=1;h=0;
        break;
        case 0x02:
          g=0;h=1;
        break;
        case 0x03:
          g=1;h=1;
        break;
  }

}

 
 
 

回复

88

帖子

0

TA的资源

一粒金砂(初级)

15
 
可以的 但是这样只能作为出口的时候用的
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

16
 
实现是可以实现,这样很有意义吗?这样做了可以减轻你的工作量吗?揉来揉去的,还不如直接位操作。
 
 
 

回复

84

帖子

0

TA的资源

一粒金砂(初级)

17
 
哦,直接位操作不容易被别人看懂啊。
谢谢各位的提议。
 
 
 

回复

58

帖子

0

TA的资源

一粒金砂(初级)

18
 
" c=d=0;"楼主这样有错吧,应该改为c=0; d=0;
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表