2013-08-19 30 views
0

我正在使用恩智浦LPC1788微控制器,並且我正在嘗試編寫能讓我在模擬通道0-7上執行ADC測量的代碼。我現在所擁有的代碼是:是否有人爲恩智浦LPC17xx ADC編寫了工作代碼?

uint16_t getADCChannelValue(uint8_t adcChannel) 
{ 
    uint16_t adc_value; 

    ADC_ChannelCmd(LPC_ADC, adcChannel, ENABLE); 
    ADC_StartCmd(LPC_ADC, ADC_START_NOW); 

    // Wait for measurement to complete. 
    while (!(ADC_ChannelGetStatus(LPC_ADC, adcChannel, ADC_DATA_DONE))); 

    adc_value = ADC_ChannelGetData(LPC_ADC, adcChannel); 
    ADC_ChannelCmd(LPC_ADC, adcChannel, DISABLE); 

    // With delay - code works. Without delay - channel 0 is correct, 
    // channels 1-7 have values close to channel 0 (~2150) (incorrect). 
    //OS_Delay(1); 

    return adc_value; 
} 

有了延遲,代碼似乎工作,但我不想在那裏任意延遲。我一直在玩代碼幾個小時,不管什麼原因,延遲標誌在延遲時間被設置(也就是說,當函數輸出正確的值時它會報錯)。

我施加電壓只有模擬通道0。這是輸出我得到當延遲包括:

Channel 0 = 2151 
Channel 1 = 35 
Channel 2 = 33 
Channel 3 = 34 
Channel 4 = 32 
Channel 5 = 34 
Channel 6 = 32 
Channel 7 = 31 

當不包括它:

Channel 0 = 2150 
Channel 1 = 2151 
Channel 2 = 2151 
Channel 3 = 2150 
Channel 4 = 2150 
Channel 5 = 2150 
Channel 6 = 2149 
Channel 7 = 2150 

有沒有人編寫任何代碼,使我能夠儘快通過所有ADC通道並儘可能快地記錄它們的值,而不會出現任意延遲?

回答

1

標籤,我認爲你應該使用「突發模式」。下面是我的ADC初始化代碼:

void adcHandlerInit() 
{ 
    // Clear all bits of the analog pin registers except for the filter disable 
    // bit. 
    *((uint32_t *)(LPC_IOCON_BASE + ((BRD_ADC_CH_PORT_0 * 32 
          + BRD_ADC_CH_PIN_23)*sizeof(uint32_t)))) = 1 << 8; 
    *((uint32_t *)(LPC_IOCON_BASE + ((BRD_ADC_CH_PORT_0 * 32 
          + BRD_ADC_CH_PIN_24)*sizeof(uint32_t)))) = 1 << 8; 
    *((uint32_t *)(LPC_IOCON_BASE + ((BRD_ADC_CH_PORT_0 * 32 
          + BRD_ADC_CH_PIN_25)*sizeof(uint32_t)))) = 1 << 8; 
    *((uint32_t *)(LPC_IOCON_BASE + ((BRD_ADC_CH_PORT_0 * 32 
          + BRD_ADC_CH_PIN_26)*sizeof(uint32_t)))) = 1 << 8; 
    *((uint32_t *)(LPC_IOCON_BASE + ((BRD_ADC_CH_PORT_1 * 32 
          + BRD_ADC_CH_PIN_30)*sizeof(uint32_t)))) = 1 << 8; 
    *((uint32_t *)(LPC_IOCON_BASE + ((BRD_ADC_CH_PORT_1 * 32 
          + BRD_ADC_CH_PIN_31)*sizeof(uint32_t)))) = 1 << 8; 
    *((uint32_t *)(LPC_IOCON_BASE + ((BRD_ADC_CH_PORT_0 * 32 
          + BRD_ADC_CH_PIN_12)*sizeof(uint32_t)))) = 1 << 8; 
    *((uint32_t *)(LPC_IOCON_BASE + ((BRD_ADC_CH_PORT_0 * 32 
          + BRD_ADC_CH_PIN_13)*sizeof(uint32_t)))) = 1 << 8; 

    PINSEL_ConfigPin(BRD_ADC_CH_PORT_0, BRD_ADC_CH_PIN_23, BRD_ADC_CH_FUNC_NO_1); 
    PINSEL_ConfigPin(BRD_ADC_CH_PORT_0, BRD_ADC_CH_PIN_24, BRD_ADC_CH_FUNC_NO_1); 
    PINSEL_ConfigPin(BRD_ADC_CH_PORT_0, BRD_ADC_CH_PIN_25, BRD_ADC_CH_FUNC_NO_1); 
    PINSEL_ConfigPin(BRD_ADC_CH_PORT_0, BRD_ADC_CH_PIN_26, BRD_ADC_CH_FUNC_NO_1); 
    PINSEL_ConfigPin(BRD_ADC_CH_PORT_1, BRD_ADC_CH_PIN_30, BRD_ADC_CH_FUNC_NO_3); 
    PINSEL_ConfigPin(BRD_ADC_CH_PORT_1, BRD_ADC_CH_PIN_31, BRD_ADC_CH_FUNC_NO_3); 
    PINSEL_ConfigPin(BRD_ADC_CH_PORT_0, BRD_ADC_CH_PIN_12, BRD_ADC_CH_FUNC_NO_3); 
    PINSEL_ConfigPin(BRD_ADC_CH_PORT_0, BRD_ADC_CH_PIN_13, BRD_ADC_CH_FUNC_NO_3); 

    /* Configuration for ADC : 
    * ADC conversion rate = 400Khz 
    */ 
    ADC_Init(LPC_ADC, 400000); 

    ADC_IntConfig(LPC_ADC, BRD_ADC_INTR_0, DISABLE); 
    ADC_IntConfig(LPC_ADC, BRD_ADC_INTR_1, DISABLE); 
    ADC_IntConfig(LPC_ADC, BRD_ADC_INTR_2, DISABLE); 
    ADC_IntConfig(LPC_ADC, BRD_ADC_INTR_3, DISABLE); 
    ADC_IntConfig(LPC_ADC, BRD_ADC_INTR_4, DISABLE); 
    ADC_IntConfig(LPC_ADC, BRD_ADC_INTR_5, DISABLE); 
    ADC_IntConfig(LPC_ADC, BRD_ADC_INTR_6, DISABLE); 
    ADC_IntConfig(LPC_ADC, BRD_ADC_INTR_7, DISABLE); 

    // Start burst mode. 
    ADC_ChannelCmd(LPC_ADC, ADC_CHANNEL_0, ENABLE); 
    ADC_ChannelCmd(LPC_ADC, ADC_CHANNEL_1, ENABLE); 
    ADC_ChannelCmd(LPC_ADC, ADC_CHANNEL_2, ENABLE); 
    ADC_ChannelCmd(LPC_ADC, ADC_CHANNEL_3, ENABLE); 
    ADC_ChannelCmd(LPC_ADC, ADC_CHANNEL_4, ENABLE); 
    ADC_ChannelCmd(LPC_ADC, ADC_CHANNEL_5, ENABLE); 
    ADC_ChannelCmd(LPC_ADC, ADC_CHANNEL_6, ENABLE); 
    ADC_ChannelCmd(LPC_ADC, ADC_CHANNEL_7, ENABLE); 
    ADC_StartCmd(LPC_ADC, ADC_START_CONTINUOUS); 
    ADC_BurstCmd(LPC_ADC, ENABLE); 
} 

底部的部分是很重要的。它將使微控制器在所有ADC通道上執行重複測量。之後,你可以得到通道電壓值:

uint16_t getADCChannelValue(uint8_t adcChannel) 
{ 
    return (uint16_t)ADC_ChannelGetData(LPC_ADC, adcChannel); 
} 

這應該會幫助你。然而,如果沒有使用突發模式,很高興看到這樣做的方式,所以任何有正確答案但不依賴突發模式的人應該被授予接受的答案來代替我。

+0

謝謝。這很好。 – Tagc

0

我注意到,在相同類型和相同生產批次的不同控制器上,每個控制器的行爲都不相同。

我也有,有時通道0是做了錯誤的測量結果

這個問題通過添加啓用通道,並開始CMD之間的延遲解決了這個問題。這個延遲是1us。

儘管如此,對於每個控制器來說,這種延遲還是不夠的。現在是4us。但它不是一個希望的解決方案。

un16 adcMeasureChannelBlocked(un8 channel) 
{ 
un16 value; 

// Enable channel 
ADC_ChannelCmd(LP_ADC_PERHIPHERAL, channel, ENABLE); 

// Reset delay timer 
adcTimeOutTimer = timingGetTicks(); 
while(!(timingHasElapsed(&adcTimeOutTimer, TIMING_TIME_US(4)))); 

// Start measurement 
ADC_StartCmd(LP_ADC_PERHIPHERAL, ADC_START_NOW); 

// Reset timeout timer 
adcTimeOutTimer = timingGetTicks(); 

// Wait until done 
while(!ADC_ChannelGetDoneStatus(LP_ADC_PERHIPHERAL, channel, &value)); 
{ 
    if (timingHasElapsed(&adcTimeOutTimer, TIMING_TIME_MS(2))) 
    { 
     bmsStatusEvent(STATUS_EVT_SET,ERROR_HW_ADC_DATA); 
    } 
} 

// Disable channel 
ADC_ChannelCmd(LP_ADC_PERHIPHERAL, channel, DISABLE); 

return value; 
} 
相關問題