标题: 为什么keil的多文件工程就有问题 [打印本页]

作者: 3038838599    时间: 2023-9-5 16:52
标题: 为什么keil的多文件工程就有问题
事情是这样的,在keil上我用单文件功能能实现的功能。
再用多文件工程的时候,功能就实现不了了,就是一个外部中断控制灯的程序。
用的是51单片机,普中的开发板。


实实在在搞了,两天没什么头绪,工程的各种添加也都添加了,特来交流交流。

14、按键换挡模仿产品控制板 - 副本.rar

24.01 KB, 下载次数: 11

程序

普中-2&普中-3&普中-4开发板原理图.pdf

151.73 KB, 下载次数: 8

原理图


作者: lkc8210    时间: 2023-9-5 18:09


作者: Hephaestus    时间: 2023-9-5 22:26
你早说是C51啊??

我还以为是RVMDK,兴冲冲的进来,扫兴回去。
作者: changhz    时间: 2023-9-6 00:52
中断就是等按键按下,你把按键放中断里,永远都进不去。
单玩玩的话,去掉按键部份,直接按P3.3就可以的,不过没有消抖会跳,如下1和2。
1、exint1.c
void exti1() interrupt 2 //外部中断1中断函数
{
    mode++;       
    if(mode>=3)
                mode=0;       
}

2、exint1.h
sbit KEY4=P3^5;

想加个按键触发的话如下3。
1、exint1.c
void exti1_init(void)
{
        IT1=1;//跳变沿触发方式(下降沿)
        EX1=1;//打开INT1的中断允许
        EA=1;//打开总中断
}

void key(void)
{
        if(!KEY4)
        {
                delay_10us(2000);
                if(!KEY4)
                {          
                        Flag = 0;                               
                }
                while(!KEY4)
                Flag = 1;       
        }
}

void exti1() interrupt 2 //外部中断1中断函数
{
        mode++;
        if(mode>=3)
                        mode=0;                       
}


2、exint1.h
//定义独立按键K4控制脚
sbit KEY4=P3^5;
sbit Flag=P3^3;


3、main.c
while(1)
        {               
            key();               
                        switch(mode)
                {
                        case 0: led1=1;led2=1;led3=1;break;
                        case 1: led1=0;led2=0;led3=0;break;
                        case 2: led1=0;led2=0;led3=1;break;
                        case 3: led1=0;led2=1;led3=1;break;
                }
               
        }       


作者: chxelc    时间: 2023-9-6 08:50
沙发说的对,mode全局变量只在exint1.h中定义为extern u8 mode;表示外部已经定义了,但我找遍工程都没看到哪里有定义。建议在main.c中加入变量申明u8 mode;试试。
作者: sttt300    时间: 2023-9-6 08:59

我用你的文件建了个工程,问题如下:
1. 首先出现以下问题,这个只需要把库文件路径设置一下就好了,相信你肯定不是这个问题引起的


2. 已经成功编译,但是一堆警告,问题点指向mode变量。


没错,就是这个变量的问题。
你在exint1.h文件中定义全局变量,但是用了extern u8 mode;这个是引用变量
应该这么改,在main()函数上面定义u8 mode,这样就没问题了
或者你把exint1.h文件中的extern u8 mode改成u8 mode,然后在main()函数上面写上extern u8 mode,也是一样的
还可以





作者: sttt300    时间: 2023-9-6 09:07
刚刚又试了一下,有一点说错了,如果mode变量要放在exit文件中定义的话,放.h文件是不行的,要放.c文件中定义,也就是2楼的图中那样写
main()函数中还是要加extern u8 mode的,不然mode变量传不过去的
作者: joyb    时间: 2023-9-6 09:15
在keil4上,不能编译
作者: 3038838599    时间: 2023-9-8 10:40
joyb 发表于 2023-9-6 09:15
在keil4上,不能编译

用的是keil c51  而且一个全局变量有问题可能编译不成功。
作者: 3038838599    时间: 2023-9-8 10:43
lkc8210 发表于 2023-9-5 18:09

是的  就是这个全局变量处理不好,已经解决了,感谢感谢
作者: 3038838599    时间: 2023-9-8 10:47
Hephaestus 发表于 2023-9-5 22:26
你早说是C51啊??

我还以为是RVMDK,兴冲冲的进来,扫兴回去。

下次在标题标明一下,现在只是在用51单片机,也不知道RVMDK这些东西
作者: 3038838599    时间: 2023-9-8 11:34
sttt300 发表于 2023-9-6 09:07
刚刚又试了一下,有一点说错了,如果mode变量要放在exit文件中定义的话,放.h文件是不行的,要放.c文件中定 ...

对是的  我是想在.H文件里用extren定义了mode ,然后在main.c文件里再包含对应的.h文件就行了。实际上是不行的,而是要在main.c里面先定义mode,然后再在.h文件用extern声明才可以用,其中的原因也不清楚。
  不知道是不是文件在多个文件夹的原因,因为在一个文件夹里就可以的。
  
作者: labview_mcu    时间: 2023-9-8 12:10
会不会是优化等级优化了 volatile 试试。
作者: Hephaestus    时间: 2023-9-8 16:39
labview_mcu 发表于 2023-9-8 12:10
会不会是优化等级优化了 volatile 试试。

c51与众不同,假定其用户都不懂volatile,所以不加都没有问题。
作者: sttt300    时间: 2023-9-9 11:04
3038838599 发表于 2023-9-8 11:34
对是的  我是想在.H文件里用extren定义了mode ,然后在main.c文件里再包含对应的.h文件就行了。实际上是不 ...

跟文件在哪没关系,文件在哪只影响你lib路径的选择
extern是引用其他文件中的变量,不是定义变量
一定要在一个.c文件中定义了全局变量
如果这个全局变量在另外一个.c文件中引用了的话,就要在那个.c文件也加上这个全局变量的声明,并且要加extern
也就是这两句“int mode”和“extern int mode”需要分别放在main.c和exit.c文件中
至于哪句放哪个文件?都可以,只要一个文件一句就行,效果一样。





欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1