【航芯ACM32F403开发板测评】+A/D数据采集及程序分析
[复制链接]
在ACM32F403芯片内,集成了一个多通道的 12 位高精度ADC,其采集速度可达2M sps。
对于A/D数据采集,厂家提供了具用多种工作模式的Demo程序以供用户学习和验证。
以ADC_Test(TEST_POLLING_NCHANNELS)测试为例,其测试结果图1和图2所示。
图1 串口通讯就绪
图2 A/D数据采集
即每按下一次板上的用户键,就输出一轮多通道的数据采集值,其程序如下:
void ADC_Test_Polling_Nchannels(void)
{
uint32_t i, VrefP, Voltage;
uint32_t lu32_COM_OK = 0;
printfS("The ADC test ADC_Test_Polling_Nchannels start.");
VrefP = ADC_GetVrefP(ADC_CHANNEL_8);
printfS("The VrefP value is : %d \r\n", VrefP);
UserKEY_Init();
printfS("---------- Please press the USR_PB button ----------\r\n");
ADC_Init_Polling_Nchannels();
while(1)
{
while(false == UserKEY_Get());
System_Delay_MS(500);
for (i = 0; i < BUFFER_LENGTH; i++)
{
gu32_AdcBuffer[i] = 0;
}
HAL_ADC_Polling(&ADC_Handle, gu32_AdcBuffer, ADC_Handle.ChannelNum, 0);
for (i = 0; i < ADC_Handle.ChannelNum; i++)
{
printfS("The adc convert result : Channel %d = 0x%08x. ", gu32_AdcBuffer[i]>>16 & 0xFF,gu32_AdcBuffer[i]);
Voltage = (gu32_AdcBuffer[i]&0xFFF)*VrefP/4095;
printfS("The Voltage is: %d mV \r\n", Voltage);
lu32_COM_OK++;
}
printfS("ADC Test OK count %d times \r\n", lu32_COM_OK);
}
}
通过仔细观察,会发现这里少了对通道 ADC_CHANNEL_3 和ADC_CHANNEL_11的采集,这是为什么呢?
原来 ADC_CHANNEL_3所使用的引脚是PA2,而ADC_CHANNEL_11所使用的引脚是PA3。
而串口2的TX2所用的引脚正是PA2,RX2所用的引脚则是PA3,为此要使用串口2来输出信息,就必须回避对这2个引脚的使用。
当然,若使用串口1来输出信息是可以避开这个问题,但使用串口1就不能通过调试口来观察信息了,必须外接USB转TTL模块来进行串行通讯。
那为什么采集的通道顺序不是按自然的由小到大顺序呢?
原来这是与其初始化程序的编排有关,其内容为:
void ADC_Init_Polling_Nchannels(void)
{
ADC_ChannelConfTypeDef ADC_ChannelConf;
ADC_Handle.Init.ClockDiv = ADC_CLOCK_DIV8;
ADC_Handle.Init.ConConvMode = ADC_CONCONVMODE_DISABLE;
ADC_Handle.Init.JChannelMode = ADC_JCHANNELMODE_DISABLE;
ADC_Handle.Init.DiffMode = ADC_DIFFMODE_DISABLE;
ADC_Handle.Init.DMAMode = ADC_DMAMODE_DISABLE;
ADC_Handle.Init.OverMode = ADC_OVERMODE_DISABLE;
ADC_Handle.Init.OverSampMode = ADC_OVERSAMPMODE_DISABLE;
ADC_Handle.Init.AnalogWDGEn = ADC_ANALOGWDGEN_DISABLE;
ADC_Handle.Init.ExTrigMode.ExTrigSel = ADC_SOFTWARE_START;
ADC_Handle.Init.ChannelEn = ADC_CHANNEL_0_EN | ADC_CHANNEL_1_EN | ADC_CHANNEL_2_EN | \
ADC_CHANNEL_4_EN | ADC_CHANNEL_5_EN | ADC_CHANNEL_6_EN | ADC_CHANNEL_7_EN | \
ADC_CHANNEL_8_EN | ADC_CHANNEL_9_EN | ADC_CHANNEL_10_EN | \
ADC_CHANNEL_12_EN | ADC_CHANNEL_13_EN | ADC_CHANNEL_14_EN | ADC_CHANNEL_15_EN;
ADC_Handle.Instance = ADC;
HAL_ADC_Init(&ADC_Handle);
/* The total adc regular channels number */
ADC_Handle.ChannelNum = 14;
/* Add adc channels */
ADC_ChannelConf.Channel = ADC_CHANNEL_0;
ADC_ChannelConf.RjMode = 0;
ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ1;
ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);
ADC_ChannelConf.Channel = ADC_CHANNEL_15;
ADC_ChannelConf.RjMode = 0;
ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ2;
ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);
ADC_ChannelConf.Channel = ADC_CHANNEL_2;
ADC_ChannelConf.RjMode = 0;
ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ3;
ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);
ADC_ChannelConf.Channel = ADC_CHANNEL_4;
ADC_ChannelConf.RjMode = 0;
ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ4;
ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);
ADC_ChannelConf.Channel = ADC_CHANNEL_5;
ADC_ChannelConf.RjMode = 0;
ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ5;
ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);
ADC_ChannelConf.Channel = ADC_CHANNEL_6;
ADC_ChannelConf.RjMode = 0;
ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ6;
ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);
ADC_ChannelConf.Channel = ADC_CHANNEL_7;
ADC_ChannelConf.RjMode = 0;
ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ7;
ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);
ADC_ChannelConf.Channel = ADC_CHANNEL_8;
ADC_ChannelConf.RjMode = 0;
ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ8;
ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);
ADC_ChannelConf.Channel = ADC_CHANNEL_9;
ADC_ChannelConf.RjMode = 0;
ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ9;
ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);
ADC_ChannelConf.Channel = ADC_CHANNEL_10;
ADC_ChannelConf.RjMode = 0;
ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ10;
ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);
ADC_ChannelConf.Channel = ADC_CHANNEL_12;
ADC_ChannelConf.RjMode = 0;
ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ11;
ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);
ADC_ChannelConf.Channel = ADC_CHANNEL_13;
ADC_ChannelConf.RjMode = 0;
ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ12;
ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);
ADC_ChannelConf.Channel = ADC_CHANNEL_14;
ADC_ChannelConf.RjMode = 0;
ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ13;
ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);
ADC_ChannelConf.Channel = ADC_CHANNEL_1;
ADC_ChannelConf.RjMode = 0;
ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ14;
ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);
}
这样我们在看如下的主程序,就清晰了很多。
int main(void)
{
System_Init();
Uart_Init();
ADC_Test(TEST_POLLING_NCHANNELS);
while(1)
{
}
}
此外,在此基础上我们还以随意地裁剪采集的通道数量,乃至只采集需要的指定通道。
只采集通道0和通道15的结果如图3所示,连续对通道1进行数据采集的结果如图4所示。
图3 双通道采集
图4 单通道连续采集
|