一开始,我打算用一个ADC不同的两个通道收集这两个传感器的数据。然而,在阅读了别人的博客一段时间后,它仍然没有得到解决,只收到一个有用的数据(或者一个传感器的值会受到另一个影响)。最后,我不能直接用两个adc非DMA来进行操作
这个ADC1配置代码引脚是PA1通道也是1。
#include "adc.h" #include "delay.h" //static float shidu1; static float temp_avg; void Adc_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; ADC_InitTypeDef ADC_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE); /*PA_1设置为模拟输入*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz GPIO_Init(GPIOA, &GPIO_InitStructure); RCC_ADCCLKConfig(RCC_PCLK2_Div6);//设置ADC分频因子 ADC_DeInit(ADC1);//复位ADC //初始化ADC参数 ADC_InitStruct.ADC_ContinuousConvMode=DISABLE; ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right; ADC_InitStruct.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None; ADC_InitStruct.ADC_Mode=ADC_Mode_Independent; ADC_InitStruct.ADC_NbrOfChannel=1; ADC_InitStruct.ADC_ScanConvMode=DISABLE; ADC_Init(ADC1, &ADC_InitStruct); ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_239Cycles5); ADC_Cmd(ADC1,ENABLE);//使能ADC1 ADC_ResetCalibration(ADC1); //使能复位校准 while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束 ADC_StartCalibration(ADC1); //开启AD校准 while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束 }
这个ADC2.配置代码。
void Adc_Init2(void) { GPIO_InitTypeDef GPIO_InitStructure; ADC_InitTypeDef ADC_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_ADC2,ENABLE); /*PA_1设置为模拟输入*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; ///模拟输入 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz GPIO_Init(GPIOB, &GPIO_InitStructure); RCC_ADCCLKConfig(RCC_PCLK2_Div6);//设置ADC分频因子 ADC_DeInit(ADC二、//复位ADC //初始化ADC参数 ADC_InitStruct.ADC_ContinuousConvMode=DISABLE; ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right; ADC_InitStruct.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None; ADC_InitStruct.ADC_Mode=ADC_Mode_Independent; ADC_InitStruct.ADC_NbrOfChannel=1; ADC_InitStruct.ADC_ScanConvMode=DISABLE; ADC_Init(ADC2, &ADC_InitStruct); ADC_RegularChannelConfig(ADC2,ADC_Channel_9,1,ADC_SampleTime_239Cycles5); ADC_Cmd(ADC2,ENABLE);//使能ADC1 ADC_ResetCalibration(ADC2); //使能复位校准 while(ADC_GetResetCalibrationStatus(ADC2)); //等待复位校准结束 ADC_StartCalibration(ADC2); //开启AD校准 while(ADC_GetCalibrationStatus(ADC2)); //等待校准结束 }
两者相似。配置完成后转换数据。
u16 Get_Light_Adc(u8 ch) { ADC_RegularChannelConfig(ADC2,ch,2, ADC_SampleTime_239Cycles5); ADC_SoftwareStartConvCmd(ADC2,ENABLE); while(!ADC_GetFlagStatus(ADC2,ADC_FLAG_EOC)); return ADC_GetConversionValue(ADC2); } u16 Get_Light_Adc_Average(u8 ch,u8 times){ u32 temp_val=0; u8 t; for(t=0;t<times;t ) { temp_val =Get_Light_Adc(ch); delay_ms(1); } temp_avg=temp_val/times; return (10240000/(1.1*temp_avg)-2500)/1000; //return temp_avg; } u16 Get_Adc_Average(u8 ch,u8 times) { u32 temp_val=0; u8 t; for(t=0;t<times;t ) { temp_val =Get_Adc(ch); delay_ms(1); } temp_avg=temp_val/times; return (4092-temp_avg)/3300*100; }
应该是两个人不同的ADC因此,转换数据四个函数是两两成对是的。(内附公式为土壤湿度和光强。个人觉得光强有点不准确。我还和队友查了一些光强单位写的。
接下来是main.c
#include "sys.h" #include "delay.h" #include "usart.h" #include "stdio.h" #include "dht11.h" #include "adc.h" unsigned short int shidu; unsigned short int light; float temp_avrg=0; u8 buff[30]; //参数显示缓存数组 u8 DHT11_Temp,DHT11_Hum; //温湿度 int main(void) { delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2)//设置中断优先级分组2:2抢占优先级,二位响应优先级 DHT11_Init(); Adc_Init(); Adc_Init2(); uart_init(115200); while(1) { shidu=Get_Adc_Average(ADC_Channel_1,10); light = Get_Light_Adc_Average(ADC_Channel_9,10); //DHT11_Read_Data(&DHT11_Temp,&DHT11_Hum); printf("当前温度:%:%d度 当前湿度:%:%d 土壤湿度:%:%d 光强:%d\r\n",DHT11_Temp,DHT11_Hum,shidu,light); delay_ms(1000); } }
有朋友给我解释一下订单。ADC为什么多通道数据采集有问题,或者写两个通道对一个通道有用?