找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1620|回复: 13
收起左侧

问两个关于单片机C语言编程的问题

[复制链接]
ID:523537 发表于 2019-6-7 06:32 | 显示全部楼层 |阅读模式
/*************************第一个问题***********************************************/
    第一个问题:如下图所示,我这里是有五个源文件,然后有四个头文件,因为函数只能在头文件声明而不能定义,所以函数都需要写在对应的源文件中。包含main()函数的主文件再编译的时候会把源文件中include的头文件都原封不动地搬到主源文件中来,但是最后链接的时候因为所有函数定义都是在别的源文件中,所以在链接的时候主源文件也会把其他源文件中定义的函数直接搬运过来吗?我可能表述的不太清楚,下面我就拿我其中一个源文件和头文件举例子吧。
question1.png

************举例子**********************
以下是头文件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让所有头文件都能够识别使用吗?
回复

使用道具 举报

ID:517466 发表于 2019-6-8 15:24 | 显示全部楼层
你可以单独做一个h文件,里面#define uchar unsigned char。然后再每个用到的c文件中引入这个h文件。使用typedef不行,我猜是因为关键字不能包含空格。typedef unsigned char uchar,在unsigned char之间存在空格,所以不行。但是使用typedef char* PCHAR这样的可以。
回复

使用道具 举报

ID:519141 发表于 2019-6-8 19:21 | 显示全部楼层
#define是C语言中定义的语法,是预处理指令,在预处理时进行简单而机械的字符串替换,不作正确性检查,只有在编译已被展开的源程序时才会发现可能的错误并报错。
typedef是关键字,在编译时处理,有类型检查功能。它在自己的作用域内给一个已经存在的类型一个别名,但不能在一个函数定义里面使用typedef。

根据typedef与define的定义,说明你的头文件没有包含标准库
回复

使用道具 举报

ID:557861 发表于 2019-6-8 19:57 | 显示全部楼层
董董 发表于 2019-6-8 05:44
我知道不同功能分文件写是为了方便移植,我想问的是main()函数在最后链接的时候会调用在别的源文件中定义 ...

1)第一个问题,你只要在调用的文件里include被调用函数声明的头文件即可
2)是因为你重复定义了一个符号,你可以把所有的类型定义集中到一个头文件,然后每个要使用的头文件中都包含这个就可以了,这样源文件就不用再次包含了
回复

使用道具 举报

ID:523537 发表于 2019-6-7 06:47 | 显示全部楼层
如果使用typedef就会出现符号错误,如下图所示 question3.png
question2.png


回复

使用道具 举报

ID:523537 发表于 2019-6-7 20:37 | 显示全部楼层
各位进来看下指点下呀,多谢了
回复

使用道具 举报

ID:382454 发表于 2019-6-7 22:28 来自手机 | 显示全部楼层
这个就是多文件,模块化编程的原理了,每个个功能分开编写,清晰明了。放便以后移植。
回复

使用道具 举报

ID:525821 发表于 2019-6-8 04:17 | 显示全部楼层
与编译器有关吧。
回复

使用道具 举报

ID:523537 发表于 2019-6-8 05:44 | 显示全部楼层
univers 发表于 2019-6-7 22:28
这个就是多文件,模块化编程的原理了,每个个功能分开编写,清晰明了。放便以后移植。

我知道不同功能分文件写是为了方便移植,我想问的是main()函数在最后链接的时候会调用在别的源文件中定义的函数对吧?以及第二个问题为啥typedef在头文件里不能用呢?
回复

使用道具 举报

ID:552592 发表于 2019-6-8 15:13 | 显示全部楼层
typedef的头文件你加了吗?
回复

使用道具 举报

ID:93224 发表于 2019-6-8 17:31 | 显示全部楼层
头文件相互包含
回复

使用道具 举报

ID:523537 发表于 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倒是一个很好的解决办法,多谢指点了!
回复

使用道具 举报

ID:523537 发表于 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
回复

使用道具 举报

ID:523537 发表于 2019-6-9 16:08 | 显示全部楼层
wfy1008 发表于 2019-6-8 19:57
1)第一个问题,你只要在调用的文件里include被调用函数声明的头文件即可
2)是因为你重复定义了一个符 ...

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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