单总线驱动

  • 单总线传感器,一个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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值