找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1876|回复: 15
收起左侧

关于单片机IO口定义的问题

[复制链接]
ID:542552 发表于 2022-6-17 23:02 | 显示全部楼层 |阅读模式
3.png          
    上图,为什么在主函数外直接给P1口赋值,编译时会报出未定义,编译通不过?
下图,而在主函数中赋值却可以通过编译。
2.png


回复

使用道具 举报

ID:99525 发表于 2022-6-18 00:51 | 显示全部楼层
放在main()函数前要显性指明sfr:
sfr P1=0xFE;
回复

使用道具 举报

ID:213173 发表于 2022-6-18 07:15 | 显示全部楼层
P1已经在头文件中被定义为寄存器的地址名:sfr P1 = 0x90;。在函数外写P1=0xfe;被编译器当变量处理当然出现语法错误。在函数内写P1=0xfe;实际是把0xfe写入地址0x90的寄存器。
回复

使用道具 举报

ID:372579 发表于 2022-6-18 09:51 | 显示全部楼层
在主函数外要声明
sbit P1 = 0xFE;
回复

使用道具 举报

ID:542552 发表于 2022-6-18 12:04 | 显示全部楼层
aide51 发表于 2022-6-18 09:51
在主函数外要声明
sbit P1 = 0xFE;

1.在keil软件尝试了一下,编译不通过。
2.sbit是对位进行操作的,而且是对于能位操作的寄存器才能使用。
如P1^1 = 0XFE; 这样是没有问题的
回复

使用道具 举报

ID:542552 发表于 2022-6-18 12:05 | 显示全部楼层
雪玉寐影 发表于 2022-6-18 00:51
放在main()函数前要显性指明sfr:
sfr P1=0xFE;

尝试了,编译通过不了。
回复

使用道具 举报

ID:383215 发表于 2022-6-18 12:29 | 显示全部楼层
这是楼主编程不规范造成的,按照我自己的理解,标准的单片机C语言,第一句是头文件,头文件到主函数之间是库文件、常量、变量、子函数声明定义、以及各种数组之类的定义,中断函数和所有子函数必须放在主函数之后,主函数之前定义的变量是全局变量,子函数内部定义的变量是局部变量,我就是这样编所有的单片机程序,所以这方面我基本没有出过问题,有人为了偷懒,把子函数放在主函数之前,免去了函数声明之类的语句,我觉得看着就不舒服,程序就像倒着放一样,P1=0xfe,这已经是实质性的赋值运算语句,怎么能放在主函数前面?
回复

使用道具 举报

ID:542552 发表于 2022-6-18 12:32 | 显示全部楼层
wulin 发表于 2022-6-18 07:15
P1已经在头文件中被定义为寄存器的地址名:sfr P1 = 0x90;。在函数外写P1=0xfe;被编译器当变量处理当然出现 ...

那顺便帮我看下下面的代码:
P1 = 0Xfe;
while(1)
        {
                        P1= _crol_(P1,1);
                        Delay(100);
        }
为什么这个代码没有流水的效果?
我的理解是每一次循环P1里面的位都向左移一位,不知道我的理解是不是错误.
如:第一次循环后:P1 是1111 1101
      第二次循环后:P1 是1111 1011
然后以此类推,产生流水的效果。
实际过程中,第一个灯亮后,第二个灯亮,然后就一直停留在第二个灯亮,第三个灯不亮,后面的灯也不亮。
下面的代码可以实现流水灯:
P1 = 0xFE;
        while(1)
        {
                for(k = 0;k < 8;k++)
                {
                        P1= _crol_(P1,1);
                        Delay(100);
                }
        }
回复

使用道具 举报

ID:542552 发表于 2022-6-18 12:40 | 显示全部楼层
kmsj 发表于 2022-6-18 12:29
这是楼主编程不规范造成的,按照我自己的理解,标准的单片机C语言,第一句是头文件,头文件到主函数之间是 ...

学习了,学习了。出现了语法上的错误。
回复

使用道具 举报

ID:213173 发表于 2022-6-18 13:35 | 显示全部楼层
51520 发表于 2022-6-18 12:32
那顺便帮我看下下面的代码:
P1 = 0Xfe;
while(1)
  1. #include <reg51.H>
  2. #include <intrins.h>
  3. #define uint unsigned int
  4. #define uchar unsigned char

  5. void Delay(uint k)
  6. {
  7.         uint i,j;
  8.         for(i=k;i>0;i--)
  9.                 for(j=110;j>0;j--);
  10. }

  11. void main()
  12. {
  13.         P1=0xfe;
  14.         while(1)
  15.         {
  16.                 P1= _crol_(P1,1);
  17.                 Delay(100);
  18.         }
  19. }
复制代码
回复

使用道具 举报

ID:824490 发表于 2022-6-18 17:12 | 显示全部楼层
你这个是函数外的赋值代码,当然报错了。
回复

使用道具 举报

ID:491577 发表于 2022-6-18 18:31 | 显示全部楼层
51520 发表于 2022-6-18 12:32
那顺便帮我看下下面的代码:
P1 = 0Xfe;
while(1)

你的Delay(100);是延长100us吗?如果是的话你的程序其实已经实现了流水灯的效果,只是你的眼睛不行没有看出来而已。
回复

使用道具 举报

ID:542552 发表于 2022-6-18 23:21 | 显示全部楼层

现在可以了,麻烦了。
回复

使用道具 举报

ID:139866 发表于 2022-6-21 17:17 | 显示全部楼层
kmsj 发表于 2022-6-18 12:29
这是楼主编程不规范造成的,按照我自己的理解,标准的单片机C语言,第一句是头文件,头文件到主函数之间是 ...

你的程序肯定只有一个.c文件吧
回复

使用道具 举报

ID:383215 发表于 2022-6-21 23:28 | 显示全部楼层
天ノ忆 发表于 2022-6-21 17:17
你的程序肯定只有一个.c文件吧

目前只有一个c文件够用了,以前程序越编越长,觉得可以分成几个模块就好了,后来发现Keil有折叠功能,我把所有程序折叠起来,需要修改哪个打开哪个,我现在编的程序不复杂,不到2000行,等到折叠都很麻烦的时候再考虑分成几个模块。
回复

使用道具 举报

ID:139866 发表于 2022-6-24 12:52 | 显示全部楼层
kmsj 发表于 2022-6-21 23:28
目前只有一个c文件够用了,以前程序越编越长,觉得可以分成几个模块就好了,后来发现Keil有折叠功能,我 ...

肯定是一个模块一个.C文件这样写更方便,需要哪个模块直接复制过来改一下配置
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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