2011-03-31 22 views
0

由於設計上的限制,我在PIC 18F4550的3個不同端口上分配了內存控制器的地址線。 映射:PIC18在跨端口分割時讀取/寫入數據

#define A0 PORTBbits.RB2 
#define A1 PORTBbits.RB3 
#define A2 PORTBbits.RB4 
#define A3 PORTBbits.RB5 
#define A4 PORTAbits.RA0 
#define A5 PORTAbits.RÄ1 
#define A6 PORTAbits.RÄ2 
#define A7 PORTAbits.RÄ3 
#define A8 PORTAbits.RÄ4 
#define A9 PORTAbits.RÄ5 
#define A10 PORTEbits.RE0 
#define A11 PORTEbits.RE1 
#define A12 PORTEbits.RE2 

我想訪問這個作爲一個單一的變量地址,並使用工會做都試過了,但只是得到一個「語法錯誤」有:

union 
{ 
     struct 
     { 
      A0 :1; 
      A1 :1; 
      A2 :1; 
      A3 :1; 
      A4 :1; 
      A5 :1; 
      A6 :1; 
      A7 :1; 
      A8 :1; 
      A9 :1; 
      A10 :1; 
      A11 :1; 
      A12 :1; 
     }; 
} ADDRESS; 

如何我會這樣做嗎?

+0

不,這是從來沒有去上班 - 你不能用一個聯盟來做到這一點。無論你想出什麼解決辦法,恐怕它會變得醜陋。您可能需要一個或多個宏或函數來在地址和各個端口位之間進行轉換。 – 2011-03-31 21:55:32

+0

好吧,所以我懷疑,需要一些位移和掩蔽。我明天會出去並發表迴應。 – 2011-03-31 22:01:49

回答

0

如果您正在使用的I/O被散列到多個端口,這將不是那麼容易。

,你唯一可以做的簡化是管理你的記憶變成由三個不同的地址塊訪問的頁面:

lowAddr will be RB2:RB5 
midAddr will be RA0:RA5 
highAdd will be RE0:RE2 

這本來是最好有低地址部分的更大的塊所以內存頁面可以更大。這裏你只有16個字節的頁面。

因此,您可以定義一個位域結構來將您的內存管理爲一個變量。

struct { 
    uint16 lowAddr : 4; 
    uint16 midAddr : 6; 
    uint16 highAddr : 3; 
    uint16 : 3; 
} memoryAddr; 

這種方式可以處理更有效的端口更新像端口B:

LATB &= 0xFF^(3 << 2); 
LATB |= memoryAddr.lowAddr << 2; 
+0

我通常直接寫入PORTB,那麼使用LATB寄存器有什麼好處呢? – 2011-04-01 15:47:47

+0

@Ali你會在下面的鏈接中找到這個問題的一個很好的答案:http://stackoverflow.com/questions/2623428/difference-between-port-and-latch-on-pic-18f – greydet 2011-04-01 20:09:44