本帖最后由 jinglixixi 于 2022-1-30 18:32 编辑
由资料可知,在N32G457的片内有4个12bit 5Msps 高速 ADC, 并可配置为 12/10/8/6bit 模式来使用。此外,它有多达 40 路外部单端输入通道,并支持差分输入模式。
单端输入通道。
以采样ADC1的模拟电压为例,可由引脚PC0和 PC1 来提供检测范围内的模拟信号。
进行数据采集的主程序为:
int main(void)
{
RCC_Configuration();
GPIO_Configuration();
ADC_Initial(ADC1);
USART1_Config();
while(1)
{
ADC1ConvertedValue[0]=ADC_GetData(ADC1,ADC1_Channel_06_PC0);
ADC1ConvertedValue[1]=ADC_GetData(ADC1,ADC1_Channel_07_PC1);
printf("\r\n ADC1ConvertedValue = %d \r\n",ADC1ConvertedValue[0]);
printf("\r\n ADC1ConvertedValue = %d \r\n",ADC1ConvertedValue[1]);
Delay(1000000000);
}
}
相应的通道采集函数为:
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;
}
经程序的编译与下载,其采集结果如图1所示:
图1 ADC数据采集
也就是说在PC0接3.3V电源,在 PC1接电源地时就可完成检测的目的,且能观察到检测的最大值和最小值。
以该程序为基础在配接相应模拟传感器的情况下,即可获得外部的状态变化,如使用火焰传感器来感知周围是否有火情发生,用土壤湿度传感器可检测绿植是否缺水等。
稍感意外的是在使用例程进行片内温度检测时,却发现其检测结果并非可信的问题,其程序为:
int main(void)
{
RCC_Configuration();
DMA_DeInit(DMA1_CH1);
DMA_InitStructure.PeriphAddr = (uint32_t)&ADC1->DAT;
DMA_InitStructure.MemAddr = (uint32_t)&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, &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, &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, &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);
}
}
使用它进行检测的结果如图2所示,不知原因为何?
图2 片内温度检测
|