會員登陸
帳號:

密碼:

記住我



忘記密碼?

現在註冊!
網站導航
最新下載
訪問統計 (自2012/5/3)


正在流覽:   1 名訪客





巨集的一些問題
中級會員
註冊日期:
2014/05/28 13:30
所屬群組:
註冊會員
文章: 43
等級: 5; EXP: 35
HP : 0 / 108
MP : 14 / 982
離線
各位前輩先進大家好!

最近在讀一位學長的程式時,

發現他自己寫了一些header file

裡面內容擷取如下

/***** IO Port: TRIA, TRIC *****/
#define Rx0_Dir_Input (1 << 0)
#define Rx0_Dir_Output (0 << 0)
#define Rx1_Dir_Input (1 << 1)
#define Rx1_Dir_Output (0 << 1)
#define Rx2_Dir_Input (1 << 2)
#define Rx2_Dir_Output (0 << 2)
#define Rx3_Dir_Input (1 << 3)
#define Rx3_Dir_Output (0 << 3)
#define Rx4_Dir_Input (1 << 4)
#define Rx4_Dir_Output (0 << 4)
#define Rx5_Dir_Input (1 << 5)
#define Rx5_Dir_Output (0 << 5)

然後他在main.c如下方使用去初始化IO

TRISA = Rx0_Dir_Input |
Rx1_Dir_Input |
Rx2_Dir_Input |
Rx3_Dir_Input |
Rx4_Dir_Input |
Rx5_Dir_Input ;

我的問題是
我看的懂他header file想"表達"什麼
但是不懂在header file內
為何可以使用 (輸出入狀態 << 第幾位元) 這樣的指令
更正確的來說是我不懂此指令的依據或規範是在哪邊???
網路上搜尋的結果似乎根據及有很大的關係
但沒有類似的用法出現

此程式使用的晶片是PIC16F1503

請各位前輩先進能幫我解惑賜教
先謝過各位前輩先進!!!

2016/10/27 17:38
轉換PDF檔 列印


Re: 巨集的一些問題
資深會員
註冊日期:
2007/06/05 21:45
所屬群組:
註冊會員
文章: 926
等級: 27; EXP: 10
HP : 0 / 652
MP : 308 / 19194
離線
先談一個問題

你瞭解或知道 如何用TRISA的設定,來控制IO的(In/Out)方向嗎?

知道的話請舉例並說明之....
例: Port A (RA0-RA7) 的 RA3,RA5 為input,其他為Output
註:不一定要用上例,你可以自已舉例.

請詳細說明與解釋,你的code與你的設定關係.

2016/10/27 17:45
_________________
程式是
依照寫出來(的code),跑出結果
不是依照你想出來的,得到結果

先有需求規格 後有解決方案
轉換PDF檔 列印


Re: 巨集的一些問題
中級會員
註冊日期:
2014/05/28 13:30
所屬群組:
註冊會員
文章: 43
等級: 5; EXP: 35
HP : 0 / 108
MP : 14 / 982
離線
引用:

jason680 寫道:
先談一個問題

你瞭解或知道 如何用TRISA的設定,來控制IO的(In/Out)方向嗎?

知道的話請舉例並說明之....
例: Port A (RA0-RA7) 的 RA3,RA5 為input,其他為Output
註:不一定要用上例,你可以自已舉例.

請詳細說明與解釋,你的code與你的設定關係.


前輩您好!
我已有三年microchip的撰寫經驗,

假設我要PortA的RA3,RA5為input
其他為output

那我會這樣打
PORTA = 0x00;
TRISA = 0b00101000

PORTA = 0x00;
TRISA = 0x28;

要將IO設為輸入必須TRIS那個PORT的那個bit為1
反之則為0
前面的PORT=0x00是避免TRIS後PORT內原有的值造成誤動作

我的問題不明白的地方是
這樣的寫法是從哪裡定義來的
為什麼括號裡的右邊是位元
左邊是狀態
還有使用了<<的運算子

也許是我見識淺薄
不知道C能這樣打
還望前輩多多指導

感謝前輩的回覆
謝謝您!!

2016/10/27 22:15
轉換PDF檔 列印


Re: 巨集的一些問題
版主
註冊日期:
2004/04/30 10:53
來自 CAE, Microchip
所屬群組:
站務管理者
註冊會員
MICROCHIP
文章: 13983
等級: 72; EXP: 24
HP : 1068 / 1781
MP : 4661 / 68510
離線
1. PIC16F 的 MCU I/O 腳有 ADC 輸入功能的,開機後都會自動設成ADC 類比輸入腳功能。所以一定要知道你所使用的腳位除需要的 ADC 輸入腳位外,其餘的腳位都要將 ADC 類比輸入功能關閉。
PIC16F1503 有三個暫存器是用來關閉 ADC 類比輸入叫的功能: ANSELA,ANSELB & ANSELC 三個暫存器。
Data Sheet 第 11 章 I/O PORTS 。

2. 到右紫色的"教育訓練光碟下" 的 RTC教育訓練課程 下的:
8-Bits MCU 相關課程 -->
PIC101 X IDE & MCC & XC8 的綜合基礎課程 New!
下載此課程讀一下。

2016/10/28 09:40
轉換PDF檔 列印


Re: 巨集的一些問題
中級會員
註冊日期:
2014/05/28 13:30
所屬群組:
註冊會員
文章: 43
等級: 5; EXP: 35
HP : 0 / 108
MP : 14 / 982
離線
引用:

Ryang 寫道:
1. PIC16F 的 MCU I/O 腳有 ADC 輸入功能的,開機後都會自動設成ADC 類比輸入腳功能。所以一定要知道你所使用的腳位除需要的 ADC 輸入腳位外,其餘的腳位都要將 ADC 類比輸入功能關閉。
PIC16F1503 有三個暫存器是用來關閉 ADC 類比輸入叫的功能: ANSELA,ANSELB & ANSELC 三個暫存器。
Data Sheet 第 11 章 I/O PORTS 。

2. 到右紫色的"教育訓練光碟下" 的 RTC教育訓練課程 下的:
8-Bits MCU 相關課程 -->
PIC101 X IDE & MCC & XC8 的綜合基礎課程 New!
下載此課程讀一下。


Ryang版主您好!!

ANSELx這幾個暫存我知道,
他並不是每顆PIC都會有,

不過我要問的問題跟這個暫存器無關,
可能我的問題表達的不夠清楚
換個例子舉例好了

如下為其中一個header file的定義內容

#define T1_Off (0 << 0)
#define T1_On (1 << 0)

#define T1_Clock_Synchronized (0 << 2)
#define T1_Clock_Not_Synchronized (1 << 2)
#define T1_Clock_Div_1 (0 << 4)
#define T1_Clock_Div_2 (1 << 4)
#define T1_Clock_Div_4 (2 << 4)
#define T1_Clock_Div_8 (3 << 4)
#define T1_Clock_Source_LFINTOSC (3 << 6)
#define T1_Clock_Source_T1CKI (2 << 6)
#define T1_Clock_Source_Fosc (1 << 6)
#define T1_Clock_Source_Fosc_Div_4 (0 << 6)

如第一二行所示
我懂這段定義想表達的內容是
T1_Off 是第0bit令為0
T1_On 是第0bit令為1

但我不懂為何括號內
左邊是放0或1 而 右邊是放第幾個bit
中間放了 << 這樣的符號


最後在c file內只需要如下以or的方式即可完成設定

T1CON = T1_Clock_Source_Fosc_Div_4 |
T1_Clock_Div_4 |
T1_Clock_Not_Synchronized |
T1_Off;

以上是我的問題
謝謝版主的回覆 謝謝您!!

2016/10/28 10:01
轉換PDF檔 列印


Re: 巨集的一些問題
資深會員
註冊日期:
2007/06/05 21:45
所屬群組:
註冊會員
文章: 926
等級: 27; EXP: 10
HP : 0 / 652
MP : 308 / 19194
離線
很好, 當我們都知道 如何設定後...

>> 假設我要PortA的RA3,RA5為input,其他為output
>> TRISA = 0b00101000
>> 或
>> TRISA = 0x28;

不管 0b00101000 或 0x28,都是"人工組合",
什麼意思叫人工組合,就是你在你心中(大腦)計算,
最後組合出答案...

這樣說好了...
我們先用熟知的十進位,來看問題...
假設 我們要寫出10萬1千元的數字...
00101000 (人工組合)
跟 0 (千萬) 0 (百萬) 1 (十萬) 0 萬 1 千 0 百 0 拾 0 個
"固定單位"已經填好.

或 1萬零1百
00010100
跟 0 (千萬) 0 (百萬) 0 (十萬) 1 萬 0 千 1 百 0 拾 0 個

比較一下"人工組合"與 "固定單位"(銀行存提)差異"...
00101000 (人工組合)
00010100

0 (千萬) 0 (百萬) 1 (十萬) 0 萬 1 千 0 百 0 拾 0 個 (銀行存錢)
0 (千萬) 0 (百萬) 0 (十萬) 1 萬 0 千 1 百 0 拾 0 個

人工組合,在你入門剛學的時候,會覺得很簡單,直覺...
但當你寫多了,會發現,很容易出錯...

如果是 1萬, 10萬...
00010000 => 1 萬
00100000 => 1 (十萬)
應該很容易看出"人工組合"與 "固定單位"(銀行存提)的優缺點...

bit5,bit3為 input
TRISA = 0b00101000; //對的

TRISA = 0b00010100; //錯的

TRISA = 0b000101000 //對的, 前面多一個0
很容易就搞錯了(還要算半天,0,1,2,3..)....
你寫出來的code,不容易看出來在做什麼?
意思是 TRISA = 0b00101000;
1. 要知道1為input, 0為output
2. 還要算一算,才知道是那幾個bit...

其實
0b00101000 // bit5, bit3
把它拆開來
0b00001000 //bit3
0b00100000 //bit5
用相加的觀念或者邏輯中的 OR (符號為 |)

那bit3, bit5 也要算,也會錯....
所就用"移位"的,在C中,移位就是
左移 << (相當是乘以2)
右移 >> (相當是除以2)

0001 << 1; // 左移1次, 0010 (bit 1)
0001 << 2; // 左移2次, 0100 (bit 2)
0001 << 3; // 左移3次, 1000 (bit 3)
以此類推...
前面的0不用寫出來
1 << 3; // 左移3次, 0000 1000 (bit 3)
1 << 5; // 左移5次, 0010 0000 (bit 5)

所以,最後 你要 bit5, bit3 為 1(input)
0b00101000 // bit5, bit3
分解(展開)為
0b00001000 //bit3
0b00100000 //bit5
換成 左移方式...
1 << 3; // 左移3次, 0000 1000 (bit 3)
1 << 5; // 左移5次, 0010 0000 (bit 5)

最後寫成macro,就是你看到的樣子了...
#define Rx3_Dir_Input (1 << 3)
#define Rx5_Dir_Input (1 << 5)


註: 其他為0,可寫也可不寫....
0 << 1; //bit1 為 0
#define Rx1_Dir_Output (0 << 1)
#define Rx2_Dir_Output (0 << 2)
其實都是0,只是易不易懂的問題.

TRISA =
Rx0_Dir_Output |
Rx1_Dir_Output |
Rx2_Dir_Output |
Rx3_Dir_Input |
Rx4_Dir_Output |
Rx5_Dir_Input ;
這樣你的code,直接就說明了,
那些是input,那些是ouput,設錯了一眼就看出來
再看一次原本的 TRISA = 0b00101000;
優缺點馬上看出...

TRISA = Rx5_Dir_Input | Rx3_Dir_Input ;
註:看個人習慣...
1. bit0~7,還是bit7~0
2. Output的0,要不要寫...

如果 define名稱太長的話...
TRISA = Rx5_IN | Rx3_IN ;

2016/10/28 10:01
_________________
程式是
依照寫出來(的code),跑出結果
不是依照你想出來的,得到結果

先有需求規格 後有解決方案
轉換PDF檔 列印


Re: 巨集的一些問題
中級會員
註冊日期:
2014/05/28 13:30
所屬群組:
註冊會員
文章: 43
等級: 5; EXP: 35
HP : 0 / 108
MP : 14 / 982
離線
引用:

jason680 寫道:
很好, 當我們都知道 如何設定後...

>> 假設我要PortA的RA3,RA5為input,其他為output
>> TRISA = 0b00101000
>> 或
>> TRISA = 0x28;

不管 0b00101000 或 0x28,都是"人工組合",
什麼意思叫人工組合,就是你在你心中(大腦)計算,
最後組合出答案...

這樣說好了...
我們先用熟知的十進位,來看問題...
假設 我們要寫出10萬1千元的數字...
00101000 (人工組合)
跟 0 (千萬) 0 (百萬) 1 (十萬) 0 萬 1 千 0 百 0 拾 0 個
"固定單位"已經填好.

或 1萬零1百
00010100
跟 0 (千萬) 0 (百萬) 0 (十萬) 1 萬 0 千 1 百 0 拾 0 個

比較一下"人工組合"與 "固定單位"(銀行存提)差異"...
00101000 (人工組合)
00010100

0 (千萬) 0 (百萬) 1 (十萬) 0 萬 1 千 0 百 0 拾 0 個 (銀行存錢)
0 (千萬) 0 (百萬) 0 (十萬) 1 萬 0 千 1 百 0 拾 0 個

人工組合,在你入門剛學的時候,會覺得很簡單,直覺...
但當你寫多了,會發現,很容易出錯...

如果是 1萬, 10萬...
00010000 => 1 萬
00100000 => 1 (十萬)
應該很容易看出"人工組合"與 "固定單位"(銀行存提)的優缺點...

bit5,bit3為 input
TRISA = 0b00101000; //對的

TRISA = 0b00010100; //錯的

TRISA = 0b000101000 //對的, 前面多一個0
很容易就搞錯了(還要算半天,0,1,2,3..)....
你寫出來的code,不容易看出來在做什麼?
意思是 TRISA = 0b00101000;
1. 要知道1為input, 0為output
2. 還要算一算,才知道是那幾個bit...

其實
0b00101000 // bit5, bit3
把它拆開來
0b00001000 //bit3
0b00100000 //bit5
用相加的關念或者邏輯中的 OR (符號為 |)

那bit3, bit5 也要算,也會錯....
所就用"移位"的,在C中,移位就是
左移 << (相當是乘以2)
右移 >> (相當是除以2)

0001 << 1; // 左移1次, 0010 (bit 1)
0001 << 2; // 左移2次, 0100 (bit 2)
0001 << 3; // 左移3次, 1000 (bit 3)
以此類推...
前面的0不用寫出來
1 << 3; // 左移3次, 0000 1000 (bit 3)
1 << 5; // 左移5次, 0010 0000 (bit 5)

所以,最後 你要 bit5, bit3 為 1(input)
0b00101000 // bit5, bit3
分解(展開)為
0b00001000 //bit3
0b00100000 //bit5
換成 左移方式...
1 << 3; // 左移3次, 0000 1000 (bit 3)
1 << 5; // 左移3次, 0010 0000 (bit 5)

最後寫成macro,就是你看到的樣子了...
#define Rx3_Dir_Input (1 << 3)
#define Rx5_Dir_Input (1 << 5)


註: 其他為0,可寫也可不寫....
0 << 1; //bit1 為 0
#define Rx1_Dir_Output (0 << 1)
#define Rx2_Dir_Output (0 << 2)
其實都是0,只是易不易懂的問題.

TRISA =
Rx0_Dir_Output |
Rx1_Dir_Output |
Rx2_Dir_Output |
Rx3_Dir_Input |
Rx4_Dir_Output |
Rx5_Dir_Input ;
這樣你的code,直接就說明了,
那些是input,那些是ouput,設錯了一眼就看出來
再看一次原本的 TRISA = 0b00101000;
優缺點馬上看出...

TRISA = Rx5_Dir_Input | Rx3_Dir_Input ;
註:看個人習慣...
1. bit0~7,還是bit7~0
2. Output的0,要不要寫...

如果 define名稱太長的話...
TRISA = Rx5_IN | Rx3_IN ;


非常感謝前輩的耐心回覆!!

我知道這種寫法是為了在閱讀時有更好的閱讀性
或更改程式的時候增加便利性降低錯誤率

經過您的講解突然懂這段code在寫什麼了
本來就知道左右移的運算
但腦子一時卡住 就卡在問題點繞不出來了

真的非常感謝您的解答!!
謝謝您!!

2016/10/28 10:13
轉換PDF檔 列印


Re: 巨集的一些問題
資深會員
註冊日期:
2007/06/05 21:45
所屬群組:
註冊會員
文章: 926
等級: 27; EXP: 10
HP : 0 / 652
MP : 308 / 19194
離線
>>我已有三年microchip的撰寫經驗,

三年剛好是一個不錯的階段,
基本能力都已具備,也是該學學更進階的項目...

1. 多看規格書
2. 多看底層資訊...
例:
#define T1_Clock_Div_1 (0 << 4)
#define T1_Clock_Div_2 (1 << 4)
#define T1_Clock_Div_4 (2 << 4)
#define T1_Clock_Div_8 (3 << 4)
#define T1_Clock_Source_LFINTOSC (3 << 6)
#define T1_Clock_Source_T1CKI (2 << 6)
#define T1_Clock_Source_Fosc (1 << 6)
#define T1_Clock_Source_Fosc_Div_4 (0 << 6)

想想它要表達什麼,為什麼可以這樣用,原理/過程是什麼,
原來可以這樣用,為什麼我沒想到/沒想過----學起來.


如果以上"為什麼"你都能找到答案/知道原理,
那一定能更上一層樓....

就可以達到 code有說明,說明中又是code...
T1CON = T1_Clock_Source_Fosc_Div_4 |
T1_Clock_Div_4 |
T1_Clock_Not_Synchronized |
T1_Off;

更上一層樓之後,回頭一看以前寫的code,
一定會想,這真的是我寫的code嗎?,怎麼會....
T1CON = 0x234; // Clock source = f/4, T1 off, ....
(只是舉例,值(0x234)亂寫的)

1. 值跟說明 不一定同步
* 值設錯了,也不知道.
* 不一定有說明,說明也不一定對...

2. code review時
都要回頭一個一個看spec,才能知道有沒有問題...

2016/10/28 10:43
_________________
程式是
依照寫出來(的code),跑出結果
不是依照你想出來的,得到結果

先有需求規格 後有解決方案
轉換PDF檔 列印


Re: 巨集的一些問題
中級會員
註冊日期:
2014/05/28 13:30
所屬群組:
註冊會員
文章: 43
等級: 5; EXP: 35
HP : 0 / 108
MP : 14 / 982
離線
引用:

jason680 寫道:
>>我已有三年microchip的撰寫經驗,

三年剛好是一個不錯的階段,
基本能力都已具備,也是該學學更進階的項目...

1. 多看規格書
2. 多看底層資訊...
例:
#define T1_Clock_Div_1 (0 << 4)
#define T1_Clock_Div_2 (1 << 4)
#define T1_Clock_Div_4 (2 << 4)
#define T1_Clock_Div_8 (3 << 4)
#define T1_Clock_Source_LFINTOSC (3 << 6)
#define T1_Clock_Source_T1CKI (2 << 6)
#define T1_Clock_Source_Fosc (1 << 6)
#define T1_Clock_Source_Fosc_Div_4 (0 << 6)

想想它要表達什麼,為什麼可以這樣用,原理/過程是什麼,
原來可以這樣用,為什麼我沒想到/沒想過----學起來.


如果以上"為什麼"你都能找到答案/知道原理,
那一定能更上一層樓....

就可以達到 code有說明,說明中又是code...
T1CON = T1_Clock_Source_Fosc_Div_4 |
T1_Clock_Div_4 |
T1_Clock_Not_Synchronized |
T1_Off;

更上一層樓之後,回頭一看以前寫的code,
一定會想,這真的是我寫的code嗎?,怎麼會....
T1CON = 0x234; // Clock source = f/4, T1 off, ....
(只是舉例,值(0x234)亂寫的)

1. 值跟說明 不一定同步
* 值設錯了,也不知道.
* 不一定有說明,說明也不一定對...

2. code review時
都要回頭一個一個看spec,才能知道有沒有問題...


前輩您好!!

這三年撰寫經驗都是在大學與碩班在學期間
的確如您所說奠定一定的基礎
Microchip 8 16 32bit的datasheet也讀了不少

唯獨code的部分在效率與系統化一直覺得自己做的不好
以前也曾看過與模仿此種撰寫方式
但都學的四不像也沒有那麼多時間去精通
一直到現在是自我要求與工作需求
所以無論如何都需要問清楚

這次問題的寫法
在應用上一定可以增加程式的可讀性與後續維護的便利
再回頭看以前的程式真的會覺得滿糟的

再次感謝前輩的解答.建議.指導!!
謝謝您!!

2016/10/28 11:05
轉換PDF檔 列印






無法在此發表文章
可以在此觀看文章
無法回覆文章
無法編輯自己的文章
無法刪除自己的文章
無法發起投票調查
無法在此投票
無法上傳附加檔案
無法不經審核直接發表文章

[進階搜尋]


搜尋
線上教學影片
網頁捷徑
2017 Summer Elite 報名
教育訓練
其它網站連結
電話: 02-25000405
產品技術問題產品技術支援專線:0800-717718 台北02-25088600 新竹03-5778366 Ext. 8600 高雄07-2137830 MicrochipDIRECT 專線: 07-2137830
Powered by XOOPS © 2001-2012 The XOOPS Project