- 单总线传感器,一个io可完成信号采集,缺点速度慢,信号采集过程中不宜有中断产生,容易产生数据获取失败。
- 单总线驱动需要一个us级 的延时函数
dwt_delay.c
/*
* Simple microseconds delay routine, utilizing ARM's DWT
* (Data Watchpoint and Trace Unit) and HAL library.
* Intended to use with gcc compiler, but I hope it can be used
* with any other C compiler across the Universe (provided that
* ARM and CMSIS already invented) :)
* Max K
*
*
* This file is part of DWT_Delay package.
* DWT_Delay is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* us_delay is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
* http://www.gnu.org/licenses/.
*/
#include "stm32f1xx_hal.h" // change to whatever MCU you use
#include "dwt_delay.h"
/**
* Initialization routine.
* You might need to enable access to DWT registers on Cortex-M7
* DWT->LAR = 0xC5ACCE55
*/
void DWT_Init(void)
{
if (!(CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk)) {
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
DWT->CYCCNT = 0;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
}
}
#if DWT_DELAY_NEWBIE
/**
* If you are a newbie and see magic in DWT_Delay, consider this more
* illustrative function, where you explicitly determine a counter
* value when delay should stop while keeping things in bounds of uint32.
*/
void DWT_Delay(uint32_t us) // microseconds
{
uint32_t startTick = DWT->CYCCNT,
targetTick = DWT->CYCCNT + us * (SystemCoreClock/1000000);
// Must check if target tick is out of bounds and overflowed
if (targetTick > startTick) {
// Not overflowed
while (DWT->CYCCNT < targetTick);
} else {
// Overflowed
while (DWT->CYCCNT > startTick || DWT->CYCCNT < targetTick);
}
}
#else
/**
* Delay routine itself.
* Time is in microseconds (1/1000000th of a second), not to be
* confused with millisecond (1/1000th).
*
* No need to check an overflow. Let it just tick :)
*
* @param uint32_t us Number of microseconds to delay for
*/
void DWT_Delay(uint32_t us) // microseconds
{
uint32_t startTick = DWT->CYCCNT,
delayTicks = us * (SystemCoreClock/1000000);
while (DWT->CYCCNT - startTick < delayTicks);
}
#endif
dwt_delay.h
/*
* Simple microseconds delay routine, utilizing ARM's DWT
* (Data Watchpoint and Trace Unit) and HAL library.
* Intended to use with gcc compiler, but I hope it can be used
* with any other C compiler across the Universe (provided that
* ARM and CMSIS already invented) :)
* Max K
*
*
* This file is part of DWT_Delay package.
* DWT_Delay is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* us_delay is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
* http://www.gnu.org/licenses/.
*/
#include <stdint.h>
#ifndef INC_DWT_DELAY_H_
#define INC_DWT_DELAY_H_
#define DWT_DELAY_NEWBIE 0
void DWT_Init(void);
void DWT_Delay(uint32_t us);
#endif /* INC_DWT_DELAY_DWT_DELAY_H_ */
- 需要io口输入输出切换子函数,直接操作寄存器效率最高
- 下面这句执行的作用有两个,等待io口置1,若io口一直为0,防止死循环,cnt累加到u8的256,然后从0开始新的一轮累加,此时退出while循环
u8 cnt;
cnt=1;
while(!DHT11_READ&&cnt++);
dht22.c
#include "dht22.h"
FF32 tem;
u8 crc;
DHT11 dht11;
void dht11_out(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
}
void dht11_in(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
}
/********************
单总线的初始化
********************/
void dht11_inint(void)
{
HAL_Delay(3000);//延时3s,越过不稳定时间
}
/********************
单总线的启动
********************/
void dht11_star(void)
{
u8 cnt;
//u16 cout = 1;//用于保证语句执行的变量
printf("\r\n从机响应判断\r\n");
dht11_out();
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_6, GPIO_PIN_RESET);//拉低
HAL_Delay(20);//,延时20ms
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_6, GPIO_PIN_SET);//释放总线
DWT_Delay(30);
//while(timeout<10)//防止进入死循环
dht11_in();
if(DHT11_READ==0)//判断是否被从机拉低
{
cnt=1;
while(!DHT11_READ&&cnt++);
cnt=1;
while(DHT11_READ&&cnt++);
}
}
/********************
单总线读取一位
********************/
u8 dht11_read_byte(void)
{
u8 dat,i,cnt;
for(i=0;i<8;i++)
{
dat=dat<<1;
cnt=1;
while(!DHT11_READ&&cnt++);
DWT_Delay(30);
if(DHT11_READ==1)
{
dat|=1;
cnt=1;
while(DHT11_READ&&cnt++);
}
}
return dat;
}
/********************
单总线读取一字节
********************/
void dht11_read(void)
{
tem.U8[0]=dht11_read_byte();
tem.U8[1]=dht11_read_byte();
tem.U8[2]=dht11_read_byte();
tem.U8[3]=dht11_read_byte();
crc =dht11_read_byte();
if((tem.U8[0]+tem.U8[1]+tem.U8[2]+tem.U8[3])==crc)
{
dht11.h=(tem.U8[0]+(float)tem.U8[1]/10);
dht11.t=(tem.U8[2]+(float)tem.U8[3]/10);
printf("湿度 %.2f,温度%.2f",dht11.h,dht11.t);
}
}
/********************
单总线读取
********************/
void dht11_run(void)
{
dht11_star();
dht11_read();
}
dht22.h
#ifndef __DHT22_H
#define __DHT22_H
#include "main.h"
#define DHT11_READ HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_6)
typedef u32 U32;
typedef union FF32
{
U32 U32;
U16 U16[2];
U8 U8[4];
} FF32;
void dht11_inint(void);
//u8 dht11_star(void);
//u8 dht11_read_bit(void);
//u8 dht11_read();
void dht11_run(void);
#endif