jinglixixi 发表于 2022-1-30 18:31

【国民技术N32G457评测】ADC数据采集

本帖最后由 jinglixixi 于 2022-1-30 18:32 编辑

<p style="text-align:justify">由资料可知,在N32G457的片内有4个12bit 5Msps 高速 ADC, 并可配置为 12/10/8/6bit 模式来使用。此外,它有多达 40 路外部单端输入通道,并支持差分输入模式。</p>

<p>单端输入通道。</p>

<p>以采样ADC1的模拟电压为例,可由引脚PC0和 PC1 来提供检测范围内的模拟信号。</p>

<p>进行数据采集的主程序为:</p>

<pre>
<code class="language-cpp">int main(void)
{
    RCC_Configuration();
    GPIO_Configuration();
    ADC_Initial(ADC1);
    USART1_Config();
    while(1)
    {
        ADC1ConvertedValue=ADC_GetData(ADC1,ADC1_Channel_06_PC0);
        ADC1ConvertedValue=ADC_GetData(ADC1,ADC1_Channel_07_PC1);
        printf("\r\n ADC1ConvertedValue = %d \r\n",ADC1ConvertedValue);
        printf("\r\n ADC1ConvertedValue = %d \r\n",ADC1ConvertedValue);
        Delay(1000000000);
    }
}</code></pre>

<p>相应的通道采集函数为:</p>

<pre>
<code class="language-cpp">uint16_t ADC_GetData(ADC_Module* ADCx, uint8_t ADC_Channel)
{
    uint16_t dat;
    ADC_ConfigRegularChannel(ADCx, ADC_Channel, 1, ADC_SAMP_TIME_239CYCLES5);
    ADC_EnableSoftwareStartConv(ADCx, ENABLE);
    while(ADC_GetFlagStatus(ADCx, ADC_FLAG_ENDC)==0);
    ADC_ClearFlag(ADCx, ADC_FLAG_ENDC);
    ADC_ClearFlag(ADCx, ADC_FLAG_STR);
    dat=ADC_GetDat(ADCx);
    return dat;
}</code></pre>

<p>经程序的编译与下载,其采集结果如图1所示:</p>

<p>图1&nbsp; ADC数据采集</p>

<p>&nbsp;</p>

<p>也就是说在PC0接3.3V电源,在 PC1接电源地时就可完成检测的目的,且能观察到检测的最大值和最小值。</p>

<p>以该程序为基础在配接相应模拟传感器的情况下,即可获得外部的状态变化,如使用火焰传感器来感知周围是否有火情发生,用土壤湿度传感器可检测绿植是否缺水等。</p>

<p>&nbsp;</p>

<p>稍感意外的是在使用例程进行片内温度检测时,却发现其检测结果并非可信的问题,其程序为:</p>

<pre>
<code class="language-cpp">int main(void)
{
    RCC_Configuration();
    DMA_DeInit(DMA1_CH1);
    DMA_InitStructure.PeriphAddr     = (uint32_t)&amp;ADC1-&gt;DAT;
    DMA_InitStructure.MemAddr        = (uint32_t)&amp;ADCConvertedValue;
    DMA_InitStructure.Direction      = DMA_DIR_PERIPH_SRC;
    DMA_InitStructure.BufSize        = 1;
    DMA_InitStructure.PeriphInc      = DMA_PERIPH_INC_DISABLE;
    DMA_InitStructure.DMA_MemoryInc  = DMA_MEM_INC_DISABLE;
    DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_HALFWORD;
    DMA_InitStructure.MemDataSize    = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.CircularMode   = DMA_MODE_CIRCULAR;
    DMA_InitStructure.Priority       = DMA_PRIORITY_HIGH;
    DMA_InitStructure.Mem2Mem    = DMA_M2M_DISABLE;
    DMA_Init(DMA1_CH1, &amp;DMA_InitStructure);
    DMA_EnableChannel(DMA1_CH1, ENABLE);
    ADC_InitStructure.WorkMode       = ADC_WORKMODE_INDEPENDENT;
    ADC_InitStructure.MultiChEn      = ENABLE;
    ADC_InitStructure.ContinueConvEn = ENABLE;
    ADC_InitStructure.ExtTrigSelect  = ADC_EXT_TRIGCONV_NONE;
    ADC_InitStructure.DatAlign       = ADC_DAT_ALIGN_R;
    ADC_InitStructure.ChsNumber      = 1;
    ADC_Init(ADC1, &amp;ADC_InitStructure);
    ADC_EnableTempSensorVrefint(ENABLE); 
    ADC_InitStructureEx.VbatMinitEn = ENABLE;
    ADC_InitStructureEx.DeepPowerModEn = DISABLE;
    ADC_InitStructureEx.JendcIntEn = DISABLE;
    ADC_InitStructureEx.EndcIntEn = DISABLE;
    ADC_InitStructureEx.ClkMode = ADC_CTRL3_CKMOD_AHB;
    ADC_InitStructureEx.CalAtuoLoadEn = DISABLE;
    ADC_InitStructureEx.DifModCal = false;
    ADC_InitStructureEx.ResBit = ADC_CTRL3_RES_12BIT;
    ADC_InitStructureEx.SampSecondStyle = false;
    ADC_InitEx(ADC1, &amp;ADC_InitStructureEx);
    ADC_ConfigRegularChannel(ADC1, ADC_CH_16, 1, ADC_SAMP_TIME_239CYCLES5);
    ADC_EnableTempSensorVrefint(ENABLE); 
    ADC_EnableDMA(ADC1, ENABLE);
    ADC_Enable(ADC1, ENABLE);
    while(ADC_GetFlagStatusNew(ADC1,ADC_FLAG_RDY) == RESET) ;
    ADC_StartCalibration(ADC1);
    while (ADC_GetCalibrationStatus(ADC1)) ;
    ADC_EnableSoftwareStartConv(ADC1, ENABLE);
    USART1_Config();
    V30 = *(__IO uint32_t*)((uint32_t)0x1FFFF7D0);
    while (1)
    {
        TempValue = TempCal(ADCConvertedValue);
        printf("\r\n Temperature = %.3f C\r\n",TempValue);
        Delay(500);
    }
}</code></pre>

<p>使用它进行检测的结果如图2所示,不知原因为何?</p>

<p>图2 片内温度检测</p>

lugl4313820 发表于 2022-1-31 08:34

没有做温度传换呀!官方提供有个例程的,对照他的找一下问题,我测出来是正常的!公式为:vol = (float)value*3.3/4096;tempeter= (1.43-vol)/0.0043 + 25;

jinglixixi 发表于 2022-1-31 10:51

lugl4313820 发表于 2022-1-31 08:34
没有做温度传换呀!官方提供有个例程的,对照他的找一下问题,我测出来是正常的!公式为:vol = (float)val ...

<p>好的,感谢!再看一看。</p>

jinglixixi 发表于 2022-1-31 11:00

jinglixixi 发表于 2022-1-31 10:51
好的,感谢!再看一看。

<p>用的是这个:</p>

<p>#define Vc0 &nbsp; &nbsp; &nbsp; &nbsp;0&nbsp;<br />
#define Tc1 &nbsp; &nbsp; &nbsp; &nbsp;1.5f<br />
uint16_t &nbsp;V30 = 0;&nbsp;</p>

<p>float TempCal(uint16_t TempAdVal)<br />
{<br />
&nbsp; &nbsp; float Temperate;<br />
&nbsp; &nbsp; Temperate=((V30+Vc0-TempAdVal)*3.3/4095)/AVG_SLOPE+30.0f-Tc1;<br />
&nbsp; &nbsp; return Temperate;<br />
}</p>

<p>可能是公式有问题。</p>

lugl4313820 发表于 2022-1-31 11:22

jinglixixi 发表于 2022-1-31 11:00
用的是这个:

#define Vc0 &nbsp; &nbsp; &nbsp; &nbsp;0&nbsp;
#define Tc1 &nbsp; &nbsp; &nbsp; &n ...

<p>向你学习呀,我回老家,没空做了!</p>

<p>&nbsp;</p>

fxyc87 发表于 2022-2-10 08:50

楼主你看也我的贴子,也是ADC采集的,后来发现硬件总理 ,板子上硬件参考REF+,REF-默认是悬空的,你要连接到VCC和GND,

fxyc87 发表于 2022-2-10 08:51

<p>楼主你看下我的贴子,也是ADC采集的,后来发现硬件问理 ,</p>

<p>板子上硬件参考REF+,REF-默认是悬空的,你要连接到VCC和GND,</p>

jinglixixi 发表于 2022-2-10 09:00

fxyc87 发表于 2022-2-10 08:51
楼主你看下我的贴子,也是ADC采集的,后来发现硬件问理 ,

板子上硬件参考REF+,REF-默认是悬空的,你要 ...

<p>原来是这样,感谢!</p>
页: [1]
查看完整版本: 【国民技术N32G457评测】ADC数据采集