[問題] 請益標頭檔內的結構共用問題

看板C_and_CPP作者 (維尼X維尼)時間4年前 (2020/01/30 18:13), 4年前編輯推噓4(5131)
留言37則, 9人參與, 4年前最新討論串1/1
開發平台(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://www.ptt.cc/bbs/C_and_CPP/M.1580379194.A.CED.html

01/30 18:47, 4年前 , 1F
恩...你知道 definition、declaration 的差別嗎?
01/30 18:47, 1F
不知道...正在看!只會宣告變數跟定義變數內容,細節還真的沒有仔細看過... ※ 編輯: wargods8402 (115.82.148.103 臺灣), 01/30/2020 19:02:58

01/30 22:44, 4年前 , 2F
#ifndef A_REG_H #define A_REG_H (中略) #endif
01/30 22:44, 2F
目前還在鑽研這個用法,感謝!

01/31 01:29, 4年前 , 3F
我的水晶球看起來可能也是樓上這個
01/31 01:29, 3F

01/31 01:30, 4年前 , 4F
但還是想請你貼一下完整的錯誤訊息 (不要只有錯誤那行)
01/31 01:30, 4F
#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;

01/31 11:59, 4年前 , 5F
我猜他可能是寫了 struct { ... } temp = { ... };
01/31 11:59, 5F
直接在結構後面宣告並定義變數(? ※ 編輯: wargods8402 (220.130.184.118 臺灣), 01/31/2020 13:54:06 ※ 編輯: wargods8402 (220.130.184.118 臺灣), 01/31/2020 13:56:07

01/31 14:33, 4年前 , 6F
使用別的檔案的變數沒有extern?
01/31 14:33, 6F
不確定這樣對不對,有錯請指正,謝謝! 將 _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

01/31 16:24, 4年前 , 7F
通常是在標頭檔放 declaration,在原始檔案 definitio
01/31 16:24, 7F

01/31 16:24, 4年前 , 8F
n。Linker 找不到 definition 就會出現 undefined refe
01/31 16:24, 8F

01/31 16:24, 4年前 , 9F
rence 啊
01/31 16:24, 9F
剛剛已經解決了,謝謝。 問題出在沒有在a_REG.h內對temp的結構宣告使用extern 改成,把放在a.h裡的結構變數宣告以及定義放到a.c中 編譯就過了,謝謝以上各位先進。 1.另外請問是否有韌體相關資源? 2.是否有對於程式模組化的實作資訊或書籍? 謝謝! ※ 編輯: wargods8402 (220.130.184.118 臺灣), 01/31/2020 16:37:42

01/31 16:30, 4年前 , 10F
不然你找找看編譯參數有沒有 -fno-common
01/31 16:30, 10F

01/31 20:46, 4年前 , 11F
資源就官方範例、論壇、datasheet、google
01/31 20:46, 11F
範例寫的太複雜...多顆MCU都寫一起,沒人講解實在不知道怎麼下手 論壇請問有推薦的嗎?謝謝 Microchip 的datasheet寫的實在有點含糊== 想要找的東西都簡略帶過 Google嘛...不知道是不是大家都不太願意分享技術還是怎麼樣,相關文章或是教學少之 又少 ※ 編輯: wargods8402 (115.82.148.103 臺灣), 02/01/2020 00:39:23

02/01 10:29, 4年前 , 12F
你想太多了,才不會是大家不太願意分享技術勒= =
02/01 10:29, 12F
韌體相關資源太難找...頭痛...

02/01 10:30, 4年前 , 13F
重複include的速解2樓跟你說了,
02/01 10:30, 13F

02/01 10:31, 4年前 , 14F
變數你直接宣告在某.c,其他要用的.c直接extern最快
02/01 10:31, 14F
後來問到的前輩跟我說,結構變數宣告通常放.h裡,定義放.c。 不知道把宣告放.c的差別是什麼呢?謝謝

02/01 14:47, 4年前 , 15F
因為你連基本常識都不會,所以就算前幾樓把答案直接
02/01 14:47, 15F

02/01 14:47, 4年前 , 16F
打出來,你也會以為人家藏步。如果有好好買本書看完
02/01 14:47, 16F

02/01 14:47, 4年前 , 17F
基本上連這個問題都不會遇到
02/01 14:47, 17F
C的基礎我確實不夠好,也正在學習中。 我回應的是學習韌體開發的學習資源,而非C語言學習的資源,爬文可以得到不少,謝謝 。 我並不想直接要答案當個伸手牌,我只想知道哪裡出問題並且記下來、學習,也非常謝謝 回答的各位。網路上分享韌體實作的的確很少,不知道您否能提供資源參考呢?謝謝 誠如開頭所述,我正在學習韌體開發,對於一些大型專案的實作經驗不足,對模組化程式 並不熟悉,閱讀的書籍也不足,所以我想直接發問應該可以得到寶貴的經驗。 如有冒犯,請見諒。

02/01 18:41, 4年前 , 18F
官方論壇啊,還會有他們的人員專門處理問題。
02/01 18:41, 18F

02/01 18:41, 4年前 , 19F
如果你是用中斷更新 temp 的話 讀的時候要暫時關掉中斷
02/01 18:41, 19F
問了兩個問題,官方給不出答案,打上關鍵字也沒有,後來是在國外的論壇找到解法... 沒辦法透過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

02/01 22:52, 4年前 , 20F
MCU 的 C 程式碼可以在這問,
02/01 22:52, 20F

02/01 22:52, 4年前 , 21F
純粹討論 Datasheet 可以到 Electronics 板
02/01 22:52, 21F

02/01 22:52, 4年前 , 22F
這些沒什麼好藏的,都是公開資訊不是門派機密
02/01 22:52, 22F
謝謝,我會再看看的謝謝! ※ 編輯: wargods8402 (180.204.98.201 臺灣), 02/02/2020 00:23:42

02/03 08:48, 4年前 , 23F
Uart 沒辦法print出浮點數, 請問這是什麼意思?
02/03 08:48, 23F
抱歉,用詞已經修正。應是無法透過Uart 對終端機print出浮點數。

02/04 01:40, 4年前 , 24F
我猜library給的printf是輸出到uart
02/04 01:40, 24F
沒錯,library所提供的printf函式可以直接對Uart輸出

02/04 01:40, 4年前 , 25F
然後設定可能是tiny之類 所以有些型別不能輸出
02/04 01:40, 25F
後來官方終於有回覆了,應該是官方提供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

02/04 19:39, 4年前 , 26F
MCU用的Lib有些printf會被精簡掉,需要設定成full才會全
02/04 19:39, 26F

02/04 19:39, 4年前 , 27F
函數能使用,不然可以用sprintf的方式來做輸出,這種通
02/04 19:39, 27F

02/04 19:39, 4年前 , 28F
常內部實作不會精簡。
02/04 19:39, 28F
先謝謝前輩的回覆!關於MCU的Library部分,還在學習當中,函數不像在DevC++中實 做可以一樣,寫上去就能使用,還要往更底層的部分深入,又學到了一課,謝謝!

02/04 19:43, 4年前 , 29F
不同.c 呼叫外部的變數時請加extern 變數類型 變數名稱
02/04 19:43, 29F

02/04 19:43, 4年前 , 30F
;這樣編譯器才會知道這變數是要找外部變數
02/04 19:43, 30F
問題已經解決了,也了解放在.h.c檔中的變數如果需要在多個.c中使用的話,必須在變數源 頭加上extern,給予其他的.c中使用。

02/04 19:47, 4年前 , 31F
教學文件 就datasheet 你要的是application note用examp
02/04 19:47, 31F

02/04 19:47, 4年前 , 32F
le code 如果說一般通訊模組無帶通訊協議通常都會有給,
02/04 19:47, 32F

02/04 19:47, 4年前 , 33F
帶通訊協議則看各廠家規範,有些需要花錢或簽訂NDA才會
02/04 19:47, 33F

02/04 19:47, 4年前 , 34F
02/04 19:47, 34F
不瞞前輩,現在所使用的是Microchip的MiWi無線通訊,要從sample code中了解幾本運作原理, 對於我這個菜鳥來說實在是蠻困難的...目前還在努力摸索當中!

02/05 08:46, 4年前 , 35F

02/05 08:46, 4年前 , 36F
for-stm32f4discovery-10.html
02/05 08:46, 36F

02/05 08:47, 4年前 , 37F
怎麼印出 float 的作法, 給你參考一下。
02/05 08:47, 37F
感謝!獲益良多! ※ 編輯: wargods8402 (220.130.184.118 臺灣), 02/05/2020 12:00:00
文章代碼(AID): #1UCgmwpj (C_and_CPP)