标题: 问两个关于单片机C语言编程的问题 [打印本页]

作者: 董董    时间: 2019-6-7 06:32
标题: 问两个关于单片机C语言编程的问题
/*************************第一个问题***********************************************/
    第一个问题:如下图所示,我这里是有五个源文件,然后有四个头文件,因为函数只能在头文件声明而不能定义,所以函数都需要写在对应的源文件中。包含main()函数的主文件再编译的时候会把源文件中include的头文件都原封不动地搬到主源文件中来,但是最后链接的时候因为所有函数定义都是在别的源文件中,所以在链接的时候主源文件也会把其他源文件中定义的函数直接搬运过来吗?我可能表述的不太清楚,下面我就拿我其中一个源文件和头文件举例子吧。


************举例子**********************
以下是头文件Display.h的内容,其中有void Display(uchar firstbit, uchar num)的声明而不是定义
单片机源程序如下:
  1. #include <reg52.h>
  2. #ifndef __DISPLAY_H__
  3. #define __DISPLAY_H__

  4. #define uchar unsigned char
  5. #define uint unsigned int

  6. #define KeyPort P3
  7. #define DataPort P0

  8. sbit Bit_Latch = P2^1;
  9. sbit Seg_Latch = P2^0;
  10. extern bit ReadTimeFlag;

  11. extern code uchar DuanMa[10];
  12. extern code uchar WeiMa[8];
  13. extern uchar TempData[8];

  14. void Display(uchar firstbit, uchar num);
  15. void Init_Timer0();

  16. #endif
复制代码

以下是Display.c源文件的内容,有void Display(uchar firstbit, uchar num)的定义但是不会被include到主原函数中,那么最后主源文件被链接成功是怎么
实现Display()函数的功能呢?

  1. #include "Display.h"
  2. #include "Delay.h"


  3. uchar code DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
  4. uchar code WeiMa[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
  5. uchar TempData[8];



  6. void Display(uchar firstbit, uchar num)
  7. {
  8.         static uchar i = 0;
  9.         
  10.         DataPort=0;
  11.         Seg_Latch = 1;
  12.         Seg_Latch = 0;
  13.         
  14.         DataPort = WeiMa[i+firstbit];
  15.         Bit_Latch = 1;
  16.         Bit_Latch = 0;
  17.         

  18.         
  19.         DataPort = TempData[i];
  20.         Seg_Latch = 1;
  21.         Seg_Latch = 0;
  22.         
  23.         
  24.         
  25.         i++;
  26.         if(i == num)
  27.         {
  28.                 i = 0;
  29.         }
  30. }

  31. void Init_Timer0()
  32. {
  33.         TMOD = 0x01;
  34.         TH0 = (65535-2000)/256;
  35.         TL0 = (65535-2000)%256;
  36.         EA = 1;
  37.         ET0 = 1;
  38.         TR0 = 1;
  39. }

  40. void Timer0() interrupt 1
  41. {
  42.         
  43.         static uchar  num;
  44.         TH0 = (65535-500)/256;
  45.         TL0 = (65535-500)%256;
  46.         Display(0,8);
  47.         num++;
  48.         
  49.         if(num == 50)
  50.         {
  51.                 num = 0;
  52.                 ReadTimeFlag = 1;
  53.         }
  54.         
  55. }
复制代码


/***********************第二个问题*******************************************/
    第二个问题:在用C语言编写程序时需要经常用到unsigned char和unsigned int,我一般习惯typedef unsigned char uchar;typedef unsigned int uint;
但是头文件里用typedef会报错,而且因为我把内容分成好几个源文件写了,所以在每一个头文件里都要#define uchar unsigned char  #define uint unsigned int,这样会搞的比较麻烦。我想问下有什么好办法能够只写一次#define uchar unsigned char  #define uint unsigned int让所有头文件都能够识别使用吗?

作者: 董董    时间: 2019-6-7 06:47
如果使用typedef就会出现符号错误,如下图所示




作者: 董董    时间: 2019-6-7 20:37
各位进来看下指点下呀,多谢了
作者: univers    时间: 2019-6-7 22:28
这个就是多文件,模块化编程的原理了,每个个功能分开编写,清晰明了。放便以后移植。
作者: xing1954    时间: 2019-6-8 04:17
与编译器有关吧。
作者: 董董    时间: 2019-6-8 05:44
univers 发表于 2019-6-7 22:28
这个就是多文件,模块化编程的原理了,每个个功能分开编写,清晰明了。放便以后移植。

我知道不同功能分文件写是为了方便移植,我想问的是main()函数在最后链接的时候会调用在别的源文件中定义的函数对吧?以及第二个问题为啥typedef在头文件里不能用呢?
作者: Pee_32    时间: 2019-6-8 15:13
typedef的头文件你加了吗?
作者: suncat0504    时间: 2019-6-8 15:24
你可以单独做一个h文件,里面#define uchar unsigned char。然后再每个用到的c文件中引入这个h文件。使用typedef不行,我猜是因为关键字不能包含空格。typedef unsigned char uchar,在unsigned char之间存在空格,所以不行。但是使用typedef char* PCHAR这样的可以。
作者: lele5211314    时间: 2019-6-8 17:31
头文件相互包含
作者: 董董    时间: 2019-6-8 19:18
suncat0504 发表于 2019-6-8 15:24
你可以单独做一个h文件,里面#define uchar unsigned char。然后再每个用到的c文件中引入这个h文件。使用ty ...

但是如果我在只有一个main()函数中用typedef unsigned char uchar是可以的,后面的用uchar没有报错,但是我一分开文件在别的源文件写就报错,不太明白。不过你说的单独写一个头文件里面#define uchar unsigned char倒是一个很好的解决办法,多谢指点了!
作者: a452541823    时间: 2019-6-8 19:21
#define是C语言中定义的语法,是预处理指令,在预处理时进行简单而机械的字符串替换,不作正确性检查,只有在编译已被展开的源程序时才会发现可能的错误并报错。
typedef是关键字,在编译时处理,有类型检查功能。它在自己的作用域内给一个已经存在的类型一个别名,但不能在一个函数定义里面使用typedef。

根据typedef与define的定义,说明你的头文件没有包含标准库
作者: wfy1008    时间: 2019-6-8 19:57
董董 发表于 2019-6-8 05:44
我知道不同功能分文件写是为了方便移植,我想问的是main()函数在最后链接的时候会调用在别的源文件中定义 ...

1)第一个问题,你只要在调用的文件里include被调用函数声明的头文件即可
2)是因为你重复定义了一个符号,你可以把所有的类型定义集中到一个头文件,然后每个要使用的头文件中都包含这个就可以了,这样源文件就不用再次包含了
作者: 董董    时间: 2019-6-9 16:07
a452541823 发表于 2019-6-8 19:21
#define是C语言中定义的语法,是预处理指令,在预处理时进行简单而机械的字符串替换,不作正确性检查,只有 ...

一般单片机程序都是#include <reg52.h>不会写#include <stdio.h>呀,但是包含reg52.h条件下也能typedef unsigned char uchar
作者: 董董    时间: 2019-6-9 16:08
wfy1008 发表于 2019-6-8 19:57
1)第一个问题,你只要在调用的文件里include被调用函数声明的头文件即可
2)是因为你重复定义了一个符 ...

嗯嗯,我也觉得这是个很好的解决办法,多谢指点




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