2173|0

156

帖子

1

TA的资源

一粒金砂(中级)

楼主
 

【STM32F769Discovery开发板试用】单总线DHT11驱动&ADC光照/接近传感器&串行驱动RGB [复制链接]

 

       本帖使用庆科Arduino扩展板的各个外设,测评STM32F769的单总线/AD/模拟串行总线的通信性能,使用扩展板的外设模块有DHT11模块,光敏电阻,红外接收头,P9813RGB彩灯模块。


       首先是DHT11单总线模块,这个直接参考网上代码即可:

void DHT11_Rst(void)	   
{                 
	DHT11_IO_OUT();
  DHT11_DQ_OUT(0);
  Delay_ms(20);
  DHT11_DQ_OUT(1);
	Delay_us(30);
}

unsigned char DHT11_Check() 	   
{   
	unsigned char retry=0;
	DHT11_IO_IN();
  while (DHT11_DQ_IN&&retry<100)
	{
		retry++;
		Delay_us(1);
	};	 
	if(retry>=100)return 1;
	else retry=0;
    while (!DHT11_DQ_IN&&retry<100)
	{
		retry++;
		Delay_us(1);
	};
	if(retry>=100)return 1;	    
	return 0;
}

unsigned char DHT11_Read_Bit(void) 			 
{
 	unsigned char retry=0;
	while(DHT11_DQ_IN&&retry<100)
	{
		retry++;
		Delay_us(1);
	}
	retry=0;
	while(!DHT11_DQ_IN&&retry<100)
	{
		retry++;
		Delay_us(1);
	}
	Delay_us(40);
	if(DHT11_DQ_IN)return 1;
	else return 0;		   
}

unsigned char DHT11_Read_Byte(void)    
{        
    unsigned char i,dat;
    dat=0;
	for (i=0;i<8;i++) 
	{
   		dat<<=1; 
	    dat|=DHT11_Read_Bit();
    }						    
    return dat;
}

unsigned char DHT11_Read_Data(unsigned char *temp,unsigned char *humi)    
{        
 	unsigned char buf[5];
	unsigned char i;
	DHT11_Rst();
	if(DHT11_Check()==0)
	{
		for(i=0;i<5;i++)
		{
			buf[i]=DHT11_Read_Byte();
		}
		if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
		{
			*humi=buf[0];
			*temp=buf[2];
		}
	}else return 1;
	return 0;	    
}
   	 
unsigned char BSP_DHT11_Init()
{
  GPIO_InitTypeDef GPIO_Initure;
  __HAL_RCC_GPIOJ_CLK_ENABLE();
	
  GPIO_Initure.Pin=GPIO_PIN_4;
  GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;
  GPIO_Initure.Pull=GPIO_PULLUP;
  GPIO_Initure.Speed=GPIO_SPEED_HIGH;
  HAL_GPIO_Init(GPIOJ,&GPIO_Initure);
 
  DHT11_Rst();
	return DHT11_Check();
}


对于DHT11模块,主要评测在200MHz主频下,STM32F769采集一次DHT11温湿度数据所需要的时间间隔:


GPIOJ->BSRR |= 0x00000002;
DHT11_Read_Data(&temp,&humi);
GPIOJ->BSRR |= 0x00020000;
DHT11_Read_Data(&temp,&humi);

可以看出,DHT11这种单总线且延迟较大的器件,采集一次的延时时间还是挺长的,达到了20ms,当项目要求us甚至us级实时的话,DHT11就绝对不是很好的选择。

然后是AD采集,这次我只做了AD常规转换的评测,没有走DMA通道,评测单次AD采集,不同采集节拍下的延时,分别是480节拍和28节拍,两组AD接口分别接了一个光敏电阻和接近传感器:

ADC_HandleTypeDef hadc1,hadc3;

void BSP_ADC1_Init()
{ 
    hadc1.Instance=ADC1;
    hadc1.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV4;
    hadc1.Init.Resolution=ADC_RESOLUTION_12B;
    hadc1.Init.DataAlign=ADC_DATAALIGN_RIGHT;             //右对齐
    hadc1.Init.ScanConvMode=DISABLE;                      //非扫描模式
    hadc1.Init.EOCSelection=DISABLE;                      //关闭EOC中断
    hadc1.Init.ContinuousConvMode=DISABLE;                //关闭连续转换
    hadc1.Init.NbrOfConversion=1;                         //1个转换在规则序列中 也就是只转换规则序列1 
    hadc1.Init.DiscontinuousConvMode=DISABLE;             //禁止不连续采样模式
    hadc1.Init.NbrOfDiscConversion=0;                     //不连续采样通道数为0
    hadc1.Init.ExternalTrigConv=ADC_SOFTWARE_START;       //软件触发
    hadc1.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_NONE;//使用软件触发
    hadc1.Init.DMAContinuousRequests=DISABLE;
    HAL_ADC_Init(&hadc1); 
}

void BSP_ADC3_Init()
{ 
    hadc3.Instance=ADC3;
    hadc3.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV4;
    hadc3.Init.Resolution=ADC_RESOLUTION_12B;
    hadc3.Init.DataAlign=ADC_DATAALIGN_RIGHT;             //右对齐
    hadc3.Init.ScanConvMode=DISABLE;                      //非扫描模式
    hadc3.Init.EOCSelection=DISABLE;                      //关闭EOC中断
    hadc3.Init.ContinuousConvMode=DISABLE;                //关闭连续转换
    hadc3.Init.NbrOfConversion=1;                         //1个转换在规则序列中 也就是只转换规则序列1 
    hadc3.Init.DiscontinuousConvMode=DISABLE;             //禁止不连续采样模式
    hadc3.Init.NbrOfDiscConversion=0;                     //不连续采样通道数为0
    hadc3.Init.ExternalTrigConv=ADC_SOFTWARE_START;       //软件触发
    hadc3.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_NONE;//使用软件触发
    hadc3.Init.DMAContinuousRequests=DISABLE;
    HAL_ADC_Init(&hadc3); 
}

void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
    GPIO_InitTypeDef GPIO_Initure;
    __HAL_RCC_ADC1_CLK_ENABLE();
	  __HAL_RCC_ADC3_CLK_ENABLE();
	
    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOF_CLK_ENABLE();
	
    GPIO_Initure.Pin=GPIO_PIN_2;
    GPIO_Initure.Mode=GPIO_MODE_ANALOG;
    GPIO_Initure.Pull=GPIO_NOPULL;
    HAL_GPIO_Init(GPIOC,&GPIO_Initure);
	
	  GPIO_Initure.Pin=GPIO_PIN_10;
    GPIO_Initure.Mode=GPIO_MODE_ANALOG;
    GPIO_Initure.Pull=GPIO_NOPULL;
    HAL_GPIO_Init(GPIOF,&GPIO_Initure);
}

int BSP_ADC1_Get(int ch)   
{
    ADC_ChannelConfTypeDef ADC1_ChanConf;
    
    ADC1_ChanConf.Channel=ch;
    ADC1_ChanConf.Rank=1;
    ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_28CYCLES;
    ADC1_ChanConf.Offset=0;                 
    HAL_ADC_ConfigChannel(&hadc1,&ADC1_ChanConf);
	
    HAL_ADC_Start(&hadc1);
	
//    HAL_ADC_PollForConversion(&hadc1,10);
   
		return (int)HAL_ADC_GetValue(&hadc1);
}

int BSP_ADC3_Get(int ch)   
{
    ADC_ChannelConfTypeDef ADC3_ChanConf;
    
    ADC3_ChanConf.Channel=ch;
    ADC3_ChanConf.Rank=1;
    ADC3_ChanConf.SamplingTime=ADC_SAMPLETIME_28CYCLES;
    ADC3_ChanConf.Offset=0;                 
    HAL_ADC_ConfigChannel(&hadc3,&ADC3_ChanConf);
	
    HAL_ADC_Start(&hadc3);
	
//    HAL_ADC_PollForConversion(&hadc3,10);
   
		return (int)HAL_ADC_GetValue(&hadc3);
}
GPIOJ->BSRR |= 0x00000002;
BSP_ADC1_Get(12);
BSP_ADC3_Get(8);
DHT11_Read_Data(&temp,&humi);

可以看出480节拍和28节拍的差异还是很大的,28节拍可以控制在5us左右(两次采集),480节拍则达到了20us:

最后就是RGB彩灯驱动了,这是使用了板上的PB8和PB9的一组I2C接口,走的是模拟I2C总线,给P9813传入32位灰度数据,就可以控制RGB灯三个颜色分量的变化:

利用触摸屏做了个演示Demo:

	while (1)
  {
		DHT11_Read_Data(&temp,&humi);
		adc_value1=BSP_ADC1_Get(12);
		adc_value2=BSP_ADC3_Get(8);
		LCD_Show_Char_1632(96,64,temp/10%10+'0',LCD_COLOR_BLACK,LCD_COLOR_CYAN);
		LCD_Show_Char_1632(112,64,temp%10+'0',LCD_COLOR_BLACK,LCD_COLOR_CYAN);

		LCD_Show_Char_1632(96,96,humi/10%10+'0',LCD_COLOR_BLACK,LCD_COLOR_CYAN);
		LCD_Show_Char_1632(112,96,humi%10+'0',LCD_COLOR_BLACK,LCD_COLOR_CYAN);
		
		LCD_Show_Char_1632(208,128,adc_value1/1000%10+'0',LCD_COLOR_BLACK,LCD_COLOR_CYAN);
		LCD_Show_Char_1632(224,128,adc_value1/100%10+'0',LCD_COLOR_BLACK,LCD_COLOR_CYAN);
		LCD_Show_Char_1632(240,128,adc_value1/10%10+'0',LCD_COLOR_BLACK,LCD_COLOR_CYAN);
		LCD_Show_Char_1632(256,128,adc_value1%10+'0',LCD_COLOR_BLACK,LCD_COLOR_CYAN);
		
		LCD_Show_Char_1632(256,160,adc_value2/1000%10+'0',LCD_COLOR_BLACK,LCD_COLOR_CYAN);
		LCD_Show_Char_1632(272,160,adc_value2/100%10+'0',LCD_COLOR_BLACK,LCD_COLOR_CYAN);
		LCD_Show_Char_1632(288,160,adc_value2/10%10+'0',LCD_COLOR_BLACK,LCD_COLOR_CYAN);
		LCD_Show_Char_1632(304,160,adc_value2%10+'0',LCD_COLOR_BLACK,LCD_COLOR_CYAN);
		
		BSP_TS_GetState(&tst);
		tx1=tst.touchX[0];
		ty1=tst.touchY[0];
		if(tx1>=545)
		{
			if(tx1<565)tx1=545;
			if(tx1>780)tx1=799;
			if(0<=ty1&&ty1<120)
			{
				rtemp=tx1-545;
				BSP_LCD_FillRect(545,0,rtemp,120,LCD_COLOR_RED);
				BSP_LCD_FillRect(tx1,0,255-rtemp,120,LCD_COLOR_CYAN);
			}
			else if(120<=ty1&&ty1<240)
			{
				gtemp=tx1-545;
				BSP_LCD_FillRect(545,120,gtemp,120,LCD_COLOR_GREEN);
				BSP_LCD_FillRect(tx1,120,255-gtemp,120,LCD_COLOR_CYAN);
			}
			else if(240<=ty1&&ty1<360)
			{
				btemp=tx1-545;
				BSP_LCD_FillRect(545,240,btemp,120,LCD_COLOR_BLUE);
				BSP_LCD_FillRect(tx1,240,255-btemp,120,LCD_COLOR_CYAN);
			}
			BSP_LCD_FillRect(545,360,255,120,
			0xff000000|(rtemp<<16)|(gtemp<<8)|btemp);
			RGB_Color_Control(rtemp,gtemp,btemp);
		}			
	}

工程文件:

STM32F769.zip (3.46 MB, 下载次数: 5)

 

 

点赞 关注
 
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表