有人为NXP LPC17xx ADC编写过工作代码吗?
我正在使用NXP LPC1788微控制器,我正在尝试编写代码,使我能够在模拟通道0-7上执行ADC测量。我现在掌握的代码是:有人为NXP LPC17xx ADC编写过工作代码吗?,c,microcontroller,lpc,adc,C,Microcontroller,Lpc,Adc,我正在使用NXP LPC1788微控制器,我正在尝试编写代码,使我能够在模拟通道0-7上执行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
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
如果不包括:
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通道并尽快记录它们的值?标签,我认为您应该使用“突发模式”。以下是我的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);
}
这应该对你有所帮助。但是,如果能找到一种不使用突发模式的方法来实现这一点,那就太好了。因此,如果其他人有一个不依赖于突发模式的正确答案,那么就应该授予被接受的答案来代替我。我注意到,在同一类型和同一生产批次的不同控制器上,每个控制器的行为都不同 我还有一个问题,就是有时候通道0的测量结果是错误的 通过在启用通道和启动命令之间添加延迟,解决了此问题。这个延迟是1U 尽管如此,对于每个控制器来说,这种延迟仍然不够。现在是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;
}