2015-04-06 156 views
0

我試圖操縱一個MCU寄存器ADC_CON_REG。我想將其設置爲1.位邏輯1然後立即檢查這是否屬實。簡單寄存器測試失敗

#define ADC_CON_REG (*((volatile unsigned int *) 0x13002020)) 

ADC_CON_REG = ADC_CON_REG | (1<<1); 

if ((ADC_CON_REG & (1<<1)) == (1<<1)){ 
    LED_on(); 
} 

以前工作的我的LED在這種情況下不會打開。我錯過了什麼,或者我的登記冊被破?


地址: 所以爲了使ADC和測試寄存器我做了什麼教程在LPC3141 user manual

enter image description here

這是我想出了 - ADC贏得't work:

#define ADC_R0_REG  (*((volatile unsigned int *) 0x13002000)) 
#define ADC_R1_REG  (*((volatile unsigned int *) 0x13002004)) 
#define ADC_R2_REG  (*((volatile unsigned int *) 0x13002008)) 
#define ADC_R3_REG  (*((volatile unsigned int *) 0x1300200C)) 
#define ADC_CON_REG  (*((volatile unsigned int *) 0x13002020)) 
#define ADC_CSEL_REG  (*((volatile unsigned int *) 0x13002024)) 
#define ADC_INT_ENABLE_REG (*((volatile unsigned int *) 0x13002028)) 
#define ADC_INT_STATUS_REG (*((volatile unsigned int *) 0x1300202C)) 
#define ADC_INT_CLEAR_REG (*((volatile unsigned int *) 0x13002030)) 


//prototypes 
void adc_reset(void); 
void adc_setup(void); 
unsigned int adc_run_continuous(void); 

//variables (each chanel) 
unsigned int val_0; 
unsigned int val_1; 
unsigned int val_2; 
unsigned int val_3; 


void c_entry(void){ 

    MODE1_SET = MODE1_SET | (0x1 << 14); 

    adc_reset(); 
    adc_setup(); 
    adc_run_continuous(); 

} 

void adc_reset(void){ 

    ADC_CON_REG = ADC_CON_REG & !(1<<1); 
    ADC_CON_REG = ADC_CON_REG & !(1<<3); 
    ADC_CON_REG = ADC_CON_REG & !(1<<0); 
    ADC_CON_REG = ADC_CON_REG & !(1<<2); 
    ADC_CSEL_REG = ADC_CSEL_REG & !(0xFFFF); 
    ADC_INT_ENABLE_REG = ADC_INT_ENABLE_REG & !(1<<0); 
    ADC_INT_CLEAR_REG = ADC_INT_CLEAR_REG | (1<<0); 

} 

void adc_setup(void){ 

    while((ADC_INT_STATUS_REG & (1<<0)) != 0x0); 
    ADC_INT_ENABLE_REG = ADC_INT_ENABLE_REG | (1<<0); 
    while((ADC_INT_STATUS_REG & (1<<0)) != 0x0); 
    ADC_CON_REG = ADC_CON_REG | (1<<0); 
    ADC_CSEL_REG = ADC_CSEL_REG & !(0xFFFF); 
    ADC_CSEL_REG = ADC_CSEL_REG | 0xAAAA; 
    ADC_CON_REG = ADC_CON_REG | (1<<1); 

} 


void adc_run_continuous(void){ 

    ADC_CON_REG = ADC_CON_REG | (1<<2); 
    ADC_CON_REG = ADC_CON_REG | (1<<3); 
    ADC_CON_REG = ADC_CON_REG & !(1<<3); 

    while(1){ 
    while((ADC_INT_STATUS_REG & (1<<0)) == 0x0); 

    if((ADC_INT_STATUS_REG & (1<<0)) == 0x1){ 
     ADC_INT_CLEAR_REG = ADC_INT_CLEAR_REG | (1<<0); 
    } 

    val_0 = ADC_R0_REG; 
    val_1 = ADC_R1_REG; 
    val_2 = ADC_R2_REG; 
    val_3 = ADC_R3_REG; 

    while((ADC_INT_STATUS_REG & (1<<0)) != 0x0); 

    } 


} 
+1

該寄存器是硬件。寫一些不必要的東西在閱讀時會實際修改它們。可能它處於某種狀態,它不能被更改。 –

+0

它是一個**讀/寫**(R/W)寄存器。所以這不應該是我想的問題。 – 71GA

+0

這不是寫的問題。但問題是,之後的閱讀不符合你的期望。它可以被寫入,但後來立即被硬件改回。 –

回答

1

您對寄存器是什麼有誤解。一些寄存器就像一個內存,你寫邏輯1並回讀,它仍然是邏輯1.但是對於一些寄存器(或寄存器的某些位)它不像內存,「寫入」和「讀取」不會在寄存器後面運行真實的總線地址。

一些LPCxxx MCU中的ADC CTRL寄存器就是一個例子。當您向ADC使能位寫入邏輯1時,在寄存器ADC後面開始執行使能操作,但需要時間,直到使能操作完成,該位纔會變爲邏輯1。

所以你應該等待此位變爲1這樣的:

while ((ADC_CON_REG & (1<<1)) != (1<<1)); 
LED_on(); 
+0

感謝您的信息和sugesstion。 – 71GA

1

有幾個潛在的問題EMS。

  1. 寄存器不能映射到代碼可以訪問的地址。 LPC314x具有層疊的模式,必須將其設置爲啓用各種子系統。可能還有更多的事情要做,而不是僅僅訪問這個地址(儘管這可能是可能的)。詳細信息請參閱"user" manual。它可能是很難找到文檔中的所有適用模式。

  2. 該寄存器的地址可能是內存映射到別的地方。在用戶模式下(與內核模式相反),它可能根本無法訪問。

  3. 通常沒有理由認爲寄存器的寫入內容與其讀取內容有關。儘管許多硬件被設計爲合理的,因爲可以讀回相同的位,但情況並非總是如此。

+0

** 1。)**在您指定的用戶手冊中有第324頁的「編程指南」。我試圖按照本指南進行操作,但仍有不清楚的地方。請閱讀ADD2給我的anwser。 ** 2。)**我沒有使用操作系統。我用裸機做這​​件事,到目前爲止沒有重新映射。 ** 3)**我同意情況並非總是如此,但對於LPC,這通常通過用** R **或** W **標記寄存器來指示,而不是** R/W **這意味着讀寫... – 71GA