搜索
bottom↓
回复: 34

各位大神!!懂指针的进

[复制链接]

出0入0汤圆

发表于 2012-4-13 13:01:51 | 显示全部楼层 |阅读模式
    首先在51中P1的物理地址是90H,如果我不通过用《reg51.h》或者sfr之类的直接用指针,应该
也是可以对P1口进行操作的。
代码如下
void main()
{   
   unsigned char*p;
   p=( volatile unsigned char *)(0x90);
   *p=0xf0;
   while(1);
}
如果上面的代码正确的话,那么8个led是一半亮一半不亮啊,纳闷的是这个程序运行的时候没一点反应,望各位大侠多多指教!!十分感谢

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

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2012-4-13 13:09:38 | 显示全部楼层
不是很懂指针 但是我觉得*P是数据指针吧 不是程序指针 用汇编去理解

出0入0汤圆

发表于 2012-4-13 13:10:04 | 显示全部楼层
典型的没事找事
0x90只是SFR地址 SFR定义到SRAM中地址不一定是0x90

出0入0汤圆

发表于 2012-4-13 13:12:19 | 显示全部楼层
本帖最后由 bangbangji 于 2012-4-13 13:13 编辑

先确定硬件没问题,再确定你的程序确实下进去了
另外51是哈佛结构的,程序和数据是分开编址的,这里是不是有问题

出0入0汤圆

发表于 2012-4-13 13:16:04 | 显示全部楼层
bangbangji 发表于 2012-4-13 13:12
先确定硬件没问题,再确定你的程序确实下进去了
另外51是哈佛结构的,程序和数据是分开编址的,这里是不是 ...

51是冯诺依曼结构的 AVR才是哈佛结构

出0入0汤圆

发表于 2012-4-13 13:17:40 | 显示全部楼层
  1. ; .\test.SRC generated from: test.c
  2. ; COMPILER INVOKED BY:
  3. ;        C:\Keil\C51\BIN\C51.EXE test.c BROWSE DEBUG OBJECTEXTEND SRC(.\test.SRC)


  4. NAME        TEST

  5. ?PR?main?TEST        SEGMENT CODE
  6.         EXTRN        CODE (?C_STARTUP)
  7.         EXTRN        CODE (?C?CSTPTR)
  8.         PUBLIC        main
  9. ; void main()

  10.         RSEG  ?PR?main?TEST
  11. main:
  12.         USING        0
  13.                         ; SOURCE LINE # 1
  14. ; {   
  15.                         ; SOURCE LINE # 2
  16. ;    unsigned char *p;
  17. ;    p=( volatile unsigned char *)(0x90);
  18.                         ; SOURCE LINE # 4
  19.         MOV          R3,#00H
  20.         MOV          R2,#00H
  21.         MOV          R1,#090H
  22. ;---- Variable 'p?040' assigned to Register 'R1/R2/R3' ----
  23. ;    *p=0xf0;
  24.                         ; SOURCE LINE # 5
  25.         MOV          A,#0F0H
  26.         LCALL        ?C?CSTPTR
  27. ?C0001:
  28. ;    while(1);
  29.                         ; SOURCE LINE # 6
  30.         SJMP         ?C0001
  31. ; END OF main

  32.         END
复制代码

出0入0汤圆

发表于 2012-4-13 13:19:19 | 显示全部楼层
这是我用at89c51在keil里把程序转换为汇编的代码

出0入0汤圆

发表于 2012-4-13 13:22:57 | 显示全部楼层
jingyong 发表于 2012-4-13 13:09
不是很懂指针 但是我觉得*P是数据指针吧 不是程序指针 用汇编去理解

没有说明区别时,在keil里是通用指针,占三个字节

这个在keil的用户手册那里有说明~~~~~

出0入0汤圆

发表于 2012-4-13 13:34:47 | 显示全部楼层
第四行错了吧!!你是想把0x90这个地址放进指针里吧!!P=0x90,你可以这样写试试!!!

出0入25汤圆

发表于 2012-4-13 13:55:43 | 显示全部楼层
记得 51 的128字节SFR 与RAM高128字节是地址重叠的吧
p=( volatile unsigned char *)(0x90); 指向的RAM区0x90  非SFR区的。

出0入0汤圆

 楼主| 发表于 2012-4-13 14:13:15 | 显示全部楼层
墨非 发表于 2012-4-13 13:55
记得 51 的128字节SFR 与RAM高128字节是地址重叠的吧
p=( volatile unsigned char *)(0x90); 指向的RAM区 ...

首先谢谢大家了,你说得对,那么怎么指向SFR区呢?谢谢了

出0入0汤圆

 楼主| 发表于 2012-4-13 14:14:39 | 显示全部楼层
NemoGu 发表于 2012-4-13 13:10
典型的没事找事
0x90只是SFR地址 SFR定义到SRAM中地址不一定是0x90

呵呵 那是多少,望大虾解答一下,谢谢了

出0入0汤圆

发表于 2012-4-13 14:22:31 | 显示全部楼层
应该指针指向不对,我不懂汇编,用c语言的话应该是:
*p=P0;或者p=&P0;它就表示指向P0
在给它赋值才对

出0入0汤圆

发表于 2012-4-13 14:27:03 | 显示全部楼层
回头再看

出0入25汤圆

发表于 2012-4-13 14:58:44 | 显示全部楼层
rookieli 发表于 2012-4-13 14:13
首先谢谢大家了,你说得对,那么怎么指向SFR区呢?谢谢了

SFR指令是C51为了访问特殊功能寄存器而做的扩展,你现在想跳过它,貌似很难哦!

出0入0汤圆

发表于 2012-4-13 15:16:24 | 显示全部楼层
本帖最后由 catvevs 于 2012-4-13 22:24 编辑

avr是冯诺依曼结构的 51才是哈佛结构  间接寻址不能访问特殊功能寄存器
unsigned char*p;只能访问内部RAM

出0入0汤圆

发表于 2012-4-13 15:37:26 | 显示全部楼层
rookieli 发表于 2012-4-13 14:14
呵呵 那是多少,望大虾解答一下,谢谢了

不同的单片机不一样啊
例如 CC1111的内部8051把SFR映射到0xDF80~0xDFFF

出0入0汤圆

 楼主| 发表于 2012-4-13 16:01:35 | 显示全部楼层
NemoGu 发表于 2012-4-13 15:37
不同的单片机不一样啊
例如 CC1111的内部8051把SFR映射到0xDF80~0xDFFF

那stc89c52呢

出0入0汤圆

发表于 2012-4-13 16:22:49 | 显示全部楼层
rookieli 发表于 2012-4-13 16:01
那stc89c52呢

查看datasheet

出0入4汤圆

发表于 2012-4-13 16:28:52 | 显示全部楼层
没办法,除非你自已写个编译器,定义一个特殊指针,专门对SFR进行操作。

出0入0汤圆

发表于 2012-4-13 17:10:54 | 显示全部楼层
如果这种方法可行,不是更好吗,而且ARM等单片机都是这样搞的,干嘛还要搞出sfr来,所以,想想都知道啦

出0入17汤圆

发表于 2012-4-13 17:52:24 | 显示全部楼层
pish 发表于 2012-4-13 17:10
如果这种方法可行,不是更好吗,而且ARM等单片机都是这样搞的,干嘛还要搞出sfr来,所以,想想都知道啦 ...

这样设方便你自己,要不然还5要去记地址。

出0入0汤圆

 楼主| 发表于 2012-4-13 18:30:55 | 显示全部楼层
看来是没办法咯,可能要去看编译原理才能解决这个问题

出0入0汤圆

发表于 2012-4-13 19:28:11 | 显示全部楼层
楼主用的到底是什么单片机啊?具体型号

既然能编译通过,就说明能找到这块地址,如果是51的话就绝对是在sfr中,但对于52等ram增强型51单片机中,大于7fh的空间是与sfr重合的,用不同的寻址方式来定位具体那块地址。彻底的解决办法你在keil里面查看下ram就可以了

出0入0汤圆

 楼主| 发表于 2012-4-13 21:09:57 | 显示全部楼层
weixinal 发表于 2012-4-13 19:28
楼主用的到底是什么单片机啊?具体型号

既然能编译通过,就说明能找到这块地址,如果是51的话就绝对是在sfr ...

我用的是stc89c52

出0入0汤圆

 楼主| 发表于 2012-4-13 21:13:15 | 显示全部楼层
weixinal 发表于 2012-4-13 19:28
楼主用的到底是什么单片机啊?具体型号

既然能编译通过,就说明能找到这块地址,如果是51的话就绝对是在sfr ...

谢谢你的回复,是这样的,谢谢了

出0入0汤圆

 楼主| 发表于 2012-4-13 21:24:49 | 显示全部楼层
weixinal 发表于 2012-4-13 19:28
楼主用的到底是什么单片机啊?具体型号

既然能编译通过,就说明能找到这块地址,如果是51的话就绝对是在sfr ...

“”SFR是特种指令寄存器,地址0x80~0xFF是SFR与RAM地址重叠复用的存储区域。如果用直接寻址的指令访问该区域,则表示SFR;如果用间接寻址(通过@Ri)的指令访问该区域,则表示RAM。物理上不重合,有256字节的RAM和128字节的SFR地址。“”
那么怎么用c语言实现呢

出0入0汤圆

发表于 2012-4-13 21:37:32 | 显示全部楼层
没试过用c实现,看来是欲了解内部结构而不再实际应用,那何必用c呢,用汇编岂不更方便。非得这么做的话,你在c中嵌入汇编试下,这块没有深究

出0入0汤圆

发表于 2012-4-13 22:10:09 | 显示全部楼层
51是冯诺依曼结构的?

出0入0汤圆

发表于 2012-4-13 22:24:16 | 显示全部楼层
是哈弗结构的,因为数据和代码编码地址不统一。

出0入0汤圆

发表于 2012-4-13 22:51:30 | 显示全部楼层
51代码空间和数据空间是分开的,所以还是哈佛结构。

出0入0汤圆

发表于 2012-4-13 22:58:25 | 显示全部楼层
51  或者52的寄存器地址 和 RAM 地址是有重复的貌似  访问他们是要用不同的指令区别的  指针 是访问不到的 !

出0入93汤圆

发表于 2012-4-13 23:09:16 | 显示全部楼层
51的架构比较怪异,SFR区寄存器只能直接访问,不能通过指针间接访问的。

另外,51是哈佛结构。是哈佛结构的原因并不仅仅因为他不是统一编址的,而主要是程序和内存在内部是采用分开的总线实现的。
更高级的单片机比如ARM,外部表现全部都是统一编址,但CM0就是冯诺依曼结构,CM3就是哈佛结构。

出0入0汤圆

发表于 2012-4-14 04:30:04 | 显示全部楼层
故事又回到了开头。sfr不能在c语言中靠地址访问。只能用嵌入汇编,即楼主提到的《reg51.h》或者sfr之类。

出0入442汤圆

发表于 2012-4-14 08:10:58 | 显示全部楼层
访问SFR时,使用sfr关键字标识变量,如
sfr IOA = 0x80;
如果要使用SFR位寻址,则为
sbit IOA0 = 0x80+0;
或者
sbit IOA0 = IOA ^ 0;
这是Keil的定义,只要你这样声明,Keil会自动用SFR寻址。
能不用汇编尽量不要使用汇编,有大炮了何必再换鸟枪?怀旧?而且你能保证你的所有函数的调用和返回都符合Keil定义?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-5-20 01:18

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

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