STM32连YL69土壤湿度传感器以及内部温度传感器采集数据并在LCD上显示

终于把32好好学习了一遍,做了一次以前的项目练手,把土壤湿度与温度采集起来,数据在显示屏上显示。效果如图
在这里插入图片描述
首先硬件连接,就不说了,以前51的项目说过。直接附代码。需要说明的是我用的是STM32F407开发板,ADC1的扫描模式。
首先main.c

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "adc.h"

__IO uint16_t ADC1ConvertedValue[64][2];
__IO uint32_t ADC1ConvertedVoltage[2]; 
		
int main(void)
{
    
     
  u8 i,j;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//ÉèÖÃϵͳÖжÏÓÅÏȼ¶·Ö×é2
	delay_init(168);     //³õʼ»¯ÑÓʱº¯Êý
	uart_init(115200);	 //³õʼ»¯´®¿Ú²¨ÌØÂÊΪ115200

	LED_Init();					//³õʼ»¯LED 
 	LCD_Init();         //Òº¾§³õʼ»¯
	Adc_Init();         //ÄÚ²¿Î¶ȴ«¸ÐÆ÷ADC³õʼ»¯
	POINT_COLOR=RED; 
	LCD_ShowString(30,50,200,16,16,"YL69-data");	
	LCD_ShowString(30,90,200,16,16,"temperature");
	POINT_COLOR=BLUE;//ÉèÖÃ×ÖÌåΪÀ¶É«          
	while(1)
	{
    
     

		for(i = 0;i<2;i++)
		{
    
    
		    ADC1ConvertedVoltage[i] = 0;
    }

        for(i=0;i<2;i++)
        {
    
    
            for(j=0;j<64;j++)
            {
    
    
                ADC1ConvertedVoltage[i] += ADC1ConvertedValue[j][i];
            }            
            ADC1ConvertedVoltage[i] = ADC1ConvertedVoltage[i]/64;
        }

				if(DMA_GetFlagStatus(DMA2_Stream0,DMA_FLAG_TCIF0)!=RESET)
					{
    
    
						
           LCD_ShowxNum(30,70,ADC1ConvertedVoltage[0],8,16,0);	
						LCD_ShowxNum(30,110,ADC1ConvertedVoltage[1],8,16,0);						
					DMA_ClearFlag(DMA2_Stream0,DMA_FLAG_TCIF0);
					}
		     	delay_ms(250);	
	}
		
		
	
	
}

这里的lcd与led两个C文件的代码我就不附上了,太长了,也不重要。
下面是adc.c

#include "adc.h"
#include "delay.h"

#define ADC1_DR_ADDRESS    ((uint32_t)0x4001204C)
extern __IO uint16_t ADC1ConvertedValue[64][2];

void  Adc_Init()
{
    
    
	GPIO_InitTypeDef  GPIO_InitStructure;
	ADC_CommonInitTypeDef ADC_CommonInitStructure;
	ADC_InitTypeDef       ADC_InitStructure;
	DMA_InitTypeDef  DMA_InitStructure;

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//??GPIOA??
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //??ADC1??
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);

	RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);	  //ADC1??
	RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);	//????
	
	ADC_TempSensorVrefintCmd(ENABLE);//ʹÄÜÄÚ²¿Î¶ȴ«¸ÐÆ÷

	DMA_DeInit(DMA2_Stream0);
	while (DMA_GetCmdStatus(DMA2_Stream0) != DISABLE) {
    
    } //??DMA???
	
	DMA_InitStructure.DMA_Channel = DMA_Channel_0;  //????
	DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR;//DMA????
	DMA_InitStructure.DMA_Memory0BaseAddr = (u32)ADC1ConvertedValue;//DMA ???0??
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;//????????
	DMA_InitStructure.DMA_BufferSize = 4;//?????
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//???????
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//???????
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//??????:32?
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//???????:32?
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
	DMA_InitStructure.DMA_Priority = DMA_Priority_High;//?????
	DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
	DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
	DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//?????????
	DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//????????
	DMA_Init(DMA2_Stream0, &DMA_InitStructure);//???DMA Stream
	DMA_Cmd(DMA2_Stream0,ENABLE);

	//????ADC1??5 IO?
	//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_4|GPIO_Pin_3|GPIO_Pin_2|GPIO_Pin_1|GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//????
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//?????
	GPIO_Init(GPIOA, &GPIO_InitStructure);//???

	ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
	ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles;
	ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
	ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;//???4??
	ADC_CommonInit(&ADC_CommonInitStructure);//???

	ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12???
	ADC_InitStructure.ADC_ScanConvMode = ENABLE;
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
	ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//??????,??????
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//???
	ADC_InitStructure.ADC_NbrOfConversion = 2;
	ADC_Init(ADC1, &ADC_InitStructure);//ADC???


	ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_144Cycles );
	ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 2, ADC_SampleTime_144Cycles );
	//ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_144Cycles );
//	ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_144Cycles );
//	ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 5, ADC_SampleTime_144Cycles );
//	ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 6, ADC_SampleTime_144Cycles );

	ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
	ADC_DMACmd(ADC1,ENABLE);
	ADC_Cmd(ADC1, ENABLE);//??AD???

	ADC_SoftwareStartConv(ADC1);
}

唉。。这些个说明全部乱码了,等我有时间再修改吧。
下面是我敲代码时遇到的问题。
1.extern __IO uint16_t ADC1ConvertedValue[64][2];
这个地方用来存储数据,需要在两个.c文件中都要使用,所以需要extern volatile的声明,再在另一个也就是main文件中不加extern声明一次。
2.引入文件,我对32不怎么熟悉,在创建工程时就花费了太多时间了。我明明添加了文件了,但是它一直显示没有,查资料说编译一次就会出现,但是没有引入根本就编译不了,进入了一个死循环,最后重启就行了。。果然,没有什么是重启解决不了的
在这里插入图片描述
3.这个项目完成后其次以后采集数据方便多了,直接修改一点点就好了,很明显修改GPIO引脚,修改ADC_NbrOfConversion,修改ADC_RegularChannelConfig,采集的周期啊,延时函数啊看情况进行修改,最最最不容易想到的(我就栽在这个地方好几天)修改DMA_InitStructure.DMA_BufferSize = 4。这个地方不修改的话你试试,屏幕上啥也没有。

最后说明一点,数据采集到了,关于数据的处理我这个代码并不完善,欢迎大家给出意见和建议

猜你喜欢

转载自blog.csdn.net/weixin_44906810/article/details/110095904