作者wargods8402 (维尼X维尼)
看板C_and_CPP
标题[问题] 请益标头档内的结构共用问题
时间Thu Jan 30 18:13:10 2020
开发平台(Platform): (Ex: Win10, Linux, ...) win10
编译器(Ex: GCC, clang, VC++...)+目标环境(跟开发平台不同的话需列出)
Atmel studio GCC
额外使用到的函数库(Library Used): (Ex: OpenGL, ...)
无
问题(Question):
小弟第一次在这发文,如有不对烦请指证,谢谢!
目前正在学习韧体开发,遇到一个结构与标头档使用的问题,问题如下:
我在范例程式专案中加入了我自己写的Library,分别为a_measure.c、
a_measure.h、a_REG.h,结构都放在a_REG.h里面。
范例为b.c、b.h
现在我想把a_measure.c运算後的结果存放进a_REG.h的一个名为temp的结构里面
,并且让b.c能够存取temp的内容。
我的认知中,应该是只要在b.c#include "a_REG.h" 这个标头档即可使用temp
这个结构,并能赋值与取值。
目前的各函式include内容:
a.c => #include a.h
#include a_REG.h
b.c => #include a_REG.h
但是,在实作的後却出现a_REG.h多重定义的错误。
将a_REG.h从b.c拿掉後却又造成temp undeclared。
怎麽做都不对...故想请问各位先进该如何解决呢?
或是有参考的资料,谢谢!
喂入的资料(Input):
预期的正确结果(Expected Output):
错误结果(Wrong Output):
程式码(Code):(请善用置底文网页, 记得排版,禁止使用图档)
抱歉,程式内容过於庞大,无法贴上来...请见谅
补充说明(Supplement):
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 220.130.184.118 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1580379194.A.CED.html
1F:→ Lipraxde: 恩...你知道 definition、declaration 的差别吗?01/30 18:47
不知道...正在看!只会宣告变数跟定义变数内容,细节还真的没有仔细看过...
※ 编辑: wargods8402 (115.82.148.103 台湾), 01/30/2020 19:02:58
2F:推 chuegou: #ifndef A_REG_H #define A_REG_H (中略) #endif01/30 22:44
目前还在钻研这个用法,感谢!
3F:推 LPH66: 我的水晶球看起来可能也是楼上这个01/31 01:29
4F:→ LPH66: 但还是想请你贴一下完整的错误讯息 (不要只有错误那行)01/31 01:30
#ifndef的部分刚刚尝试过。在编译的过程中,b.c出现的错误讯息如下:
https://imgur.com/FGL7i9R ,Si7020_temp即是上述的temp这个结构。
temp结构如下:
typedef struct _Si7020_temp{
uint16_t Si7020_temp_Code;
float Si7020_Temp;
}_Si7020_temp;
_Si7020_temp Si7020_temp;
另,在b.c中我建了另一个结构来储存temp的内容,如下:
struct _measure_info{
float measure_temp;
float measure_hum;
}measure_info;
并在b.c内使用,如下:
measure_info.measure_temp = Si7020_temp.Si7020_Temp;
measure_info.measure_hum = Si7020_hum.Si7020_Hum;
5F:→ Lipraxde: 我猜他可能是写了 struct { ... } temp = { ... };01/31 11:59
直接在结构後面宣告并定义变数(?
※ 编辑: wargods8402 (220.130.184.118 台湾), 01/31/2020 13:54:06
※ 编辑: wargods8402 (220.130.184.118 台湾), 01/31/2020 13:56:07
6F:→ tsoahans: 使用别的档案的变数没有extern?01/31 14:33
不确定这样对不对,有错请指正,谢谢!
将 _Si7020_temp Si7020_temp;
改成 extern _Si7020_temp Si7020_temp;
在b.c档中会出现以下错误
https://imgur.com/bnNDUWu
※ 编辑: wargods8402 (220.130.184.118 台湾), 01/31/2020 14:51:08
7F:→ Lipraxde: 通常是在标头档放 declaration,在原始档案 definitio01/31 16:24
8F:→ Lipraxde: n。Linker 找不到 definition 就会出现 undefined refe01/31 16:24
9F:→ Lipraxde: rence 啊01/31 16:24
刚刚已经解决了,谢谢。
问题出在没有在a_REG.h内对temp的结构宣告使用extern
改成,把放在a.h里的结构变数宣告以及定义放到a.c中
编译就过了,谢谢以上各位先进。
1.另外请问是否有韧体相关资源?
2.是否有对於程式模组化的实作资讯或书籍?
谢谢!
※ 编辑: wargods8402 (220.130.184.118 台湾), 01/31/2020 16:37:42
10F:→ Lipraxde: 不然你找找看编译参数有没有 -fno-common01/31 16:30
11F:→ Lipraxde: 资源就官方范例、论坛、datasheet、google01/31 20:46
范例写的太复杂...多颗MCU都写一起,没人讲解实在不知道怎麽下手
论坛请问有推荐的吗?谢谢
Microchip 的datasheet写的实在有点含糊==
想要找的东西都简略带过
Google嘛...不知道是不是大家都不太愿意分享技术还是怎麽样,相关文章或是教学少之
又少
※ 编辑: wargods8402 (115.82.148.103 台湾), 02/01/2020 00:39:23
12F:→ kobe8112: 你想太多了,才不会是大家不太愿意分享技术勒= =02/01 10:29
韧体相关资源太难找...头痛...
13F:→ kobe8112: 重复include的速解2楼跟你说了,02/01 10:30
14F:→ kobe8112: 变数你直接宣告在某.c,其他要用的.c直接extern最快 02/01 10:31
後来问到的前辈跟我说,结构变数宣告通常放.h里,定义放.c。
不知道把宣告放.c的差别是什麽呢?谢谢
15F:嘘 loveme00835: 因为你连基本常识都不会,所以就算前几楼把答案直接02/01 14:47
16F:→ loveme00835: 打出来,你也会以为人家藏步。如果有好好买本书看完02/01 14:47
17F:→ loveme00835: 基本上连这个问题都不会遇到02/01 14:47
C的基础我确实不够好,也正在学习中。
我回应的是学习韧体开发的学习资源,而非C语言学习的资源,爬文可以得到不少,谢谢
。
我并不想直接要答案当个伸手牌,我只想知道哪里出问题并且记下来、学习,也非常谢谢
回答的各位。网路上分享韧体实作的的确很少,不知道您否能提供资源参考呢?谢谢
诚如开头所述,我正在学习韧体开发,对於一些大型专案的实作经验不足,对模组化程式
并不熟悉,阅读的书籍也不足,所以我想直接发问应该可以得到宝贵的经验。
如有冒犯,请见谅。
18F:→ Lipraxde: 官方论坛啊,还会有他们的人员专门处理问题。02/01 18:41
19F:→ Lipraxde: 如果你是用中断更新 temp 的话 读的时候要暂时关掉中断02/01 18:41
问了两个问题,官方给不出答案,打上关键字也没有,後来是在国外的论坛找到解法...
没办法透过Uart 对终端机print出浮点数,官方根本没帮忙解答,自己盲目测试後,从别颗MCU上找到
类似的答案。原来是IDE的library优化导致。
另外,跟原厂索取无线通讯模组的教学文件、无线模组的运作原理,问了之後,官方给的
答案就是看spec,看了之後并不是我想要的东西,再次提问就没下文了...
连范例里面的Tool都是不能使用的...
只能当个无头苍蝇乱摸索...
※ 编辑: wargods8402 (101.12.131.171 台湾), 02/01/2020 19:38:57
※ 编辑: wargods8402 (101.12.131.171 台湾), 02/01/2020 19:42:40
20F:推 Schottky: MCU 的 C 程式码可以在这问,02/01 22:52
21F:→ Schottky: 纯粹讨论 Datasheet 可以到 Electronics 板02/01 22:52
22F:→ Schottky: 这些没什麽好藏的,都是公开资讯不是门派机密 02/01 22:52
谢谢,我会再看看的谢谢!
※ 编辑: wargods8402 (180.204.98.201 台湾), 02/02/2020 00:23:42
23F:→ descent: Uart 没办法print出浮点数, 请问这是什麽意思? 02/03 08:48
抱歉,用词已经修正。应是无法透过Uart 对终端机print出浮点数。
24F:推 chuegou: 我猜library给的printf是输出到uart 02/04 01:40
没错,library所提供的printf函式可以直接对Uart输出
25F:→ chuegou: 然後设定可能是tiny之类 所以有些型别不能输出 02/04 01:40
後来官方终於有回覆了,应该是官方提供library上有缺少一点东西。
解法如下:
在main()或是function()中, 添加inline assembler code
asm(".global _printf_float");
asm(".global _scanf_float");
※ 编辑: wargods8402 (220.130.184.118 台湾), 02/04/2020 10:25:31
26F:→ easypro: MCU用的Lib有些printf会被精简掉,需要设定成full才会全 02/04 19:39
27F:→ easypro: 函数能使用,不然可以用sprintf的方式来做输出,这种通 02/04 19:39
28F:→ easypro: 常内部实作不会精简。 02/04 19:39
先谢谢前辈的回覆!关於MCU的Library部分,还在学习当中,函数不像在DevC++中实
做可以一样,写上去就能使用,还要往更底层的部分深入,又学到了一课,谢谢!
29F:推 easypro: 不同.c 呼叫外部的变数时请加extern 变数类型 变数名称 02/04 19:43
30F:→ easypro: ;这样编译器才会知道这变数是要找外部变数 02/04 19:43
问题已经解决了,也了解放在.h.c档中的变数如果需要在多个.c中使用的话,必须在变数源
头加上extern,给予其他的.c中使用。
31F:→ easypro: 教学文件 就datasheet 你要的是application note用examp 02/04 19:47
32F:→ easypro: le code 如果说一般通讯模组无带通讯协议通常都会有给, 02/04 19:47
33F:→ easypro: 带通讯协议则看各厂家规范,有些需要花钱或签订NDA才会 02/04 19:47
34F:→ easypro: 给 02/04 19:47
不瞒前辈,现在所使用的是Microchip的MiWi无线通讯,要从sample code中了解几本运作原理,
对於我这个菜鸟来说实在是蛮困难的...目前还在努力摸索当中!
36F:→ descent: for-stm32f4discovery-10.html 02/05 08:46
37F:→ descent: 怎麽印出 float 的作法, 给你参考一下。 02/05 08:47
感谢!获益良多!
※ 编辑: wargods8402 (220.130.184.118 台湾), 02/05/2020 12:00:00