简单的寄存器测试失败

时间:2015-04-06 17:48:24

标签: c pointers microcontroller cpu-registers

我正在尝试操作MCU寄存器ADC_CON_REG。我想设置它的 1。位逻辑1 ,然后立即检查LED是否为真。

#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不会工作:

#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);

  }


}

2 个答案:

答案 0 :(得分:1)

有几个潜在的问题。

  1. 寄存器可能无法映射到代码可访问的地址。 LPC314x具有一层层模式,必须设置为启用各种子系统。有可能还有更多的事情要做,而不仅仅是访问这个地址(虽然它可能)。有关详细信息,请参阅"user" manual。在文档中找到所有适用的模式可能非常困难

  2. 寄存器的地址可能是其他地方的内存映射。在用户模式下(与内核模式相反),它可能根本无法访问。

  3. 通常没有理由认为寄存器的写入内容与其读取内容有关。虽然很多硬件的设计都是合理的,因为可以回读写入的相同位,但情况并非总是如此。

答案 1 :(得分:1)

你对寄存器是什么有误解。有些寄存器就像一个存储器,你写入逻辑1并回读,它仍然是逻辑1.但对于某些寄存器(或寄存器的某些位),它不像存储器,“写入”和“读取”不是在寄存器后面操作一个真正的总线地址。

一些LPCxxx MCU中的ADC CTRL寄存器就是一个例子。当您将逻辑1写入ADC使能位时,寄存器ADC后面开始执行使能操作,但需要一些时间,在启用操作完成之前,该位不会变为逻辑1。

所以你应该等待这一点改为1:

while ((ADC_CON_REG & (1<<1)) != (1<<1) );
LED_on(); 
相关问题