【STM32F769Discovery开发板试用】单总线DHT11驱动&ADC光照/接近传感器&串行驱动RGB
<p> 本帖使用庆科Arduino扩展板的各个外设,测评STM32F769的单总线/AD/模拟串行总线的通信性能,使用扩展板的外设模块有DHT11模块,光敏电阻,红外接收头,P9813RGB彩灯模块。</p><p><br />
首先是DHT11单总线模块,这个直接参考网上代码即可:</p>
<pre>
<code>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;
unsigned char i;
DHT11_Rst();
if(DHT11_Check()==0)
{
for(i=0;i<5;i++)
{
buf=DHT11_Read_Byte();
}
if((buf+buf+buf+buf)==buf)
{
*humi=buf;
*temp=buf;
}
}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();
}</code></pre>
<p><br />
对于DHT11模块,主要评测在200MHz主频下,STM32F769采集一次DHT11温湿度数据所需要的时间间隔:</p>
<pre>
<code>
GPIOJ->BSRR |= 0x00000002;
DHT11_Read_Data(&temp,&humi);
GPIOJ->BSRR |= 0x00020000;
DHT11_Read_Data(&temp,&humi);</code></pre>
<p></p>
<p>可以看出,DHT11这种单总线且延迟较大的器件,采集一次的延时时间还是挺长的,达到了20ms,当项目要求us甚至us级实时的话,DHT11就绝对不是很好的选择。</p>
<p>然后是AD采集,这次我只做了AD常规转换的评测,没有走DMA通道,评测单次AD采集,不同采集节拍下的延时,分别是480节拍和28节拍,两组AD接口分别接了一个光敏电阻和接近传感器:</p>
<pre>
<code>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);
}</code></pre>
<pre>
<code>GPIOJ->BSRR |= 0x00000002;
BSP_ADC1_Get(12);
BSP_ADC3_Get(8);
DHT11_Read_Data(&temp,&humi);</code></pre>
<p>可以看出480节拍和28节拍的差异还是很大的,28节拍可以控制在5us左右(两次采集),480节拍则达到了20us:</p>
<p></p>
<p>最后就是RGB彩灯驱动了,这是使用了板上的PB8和PB9的一组I2C接口,走的是模拟I2C总线,给P9813传入32位灰度数据,就可以控制RGB灯三个颜色分量的变化:</p>
<p>利用触摸屏做了个演示Demo:</p>
<pre>
<code> 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;
ty1=tst.touchY;
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);
}
}
</code></pre>
<p></p>
<p>工程文件:</p>
<p></p>
<p> </p>
<p> </p>
页:
[1]