stm32项目:水培检测(1)

main.c、DS18B20、BH1750

要求:

  1. 采集装置水温,联网上传到巴法云。
  2. 获取装置水位高度(AD采集),上传到巴法云。
  3. 采集环境光照(iic),上传到巴法云。
  4. 按键控制水泵开关(这里用继电器代替),按键1按下打开,按键2关闭。
  5. 水位高于某个值时,打开水泵(继电器),低于时不会自动关闭,需要按键来关闭。

main.c

#include "stm32f10x.h"		
#include "Delay.h"				
#include "math.h"
#include "oled.h"					
#include "LED.h"
#include "DS18B20.h"
#include "BH1750.h"
#include "esp8266.h"
#include "AD.h"
#include "JDQ.h"
#include "Water_Sensor.h"
#include "Key.h"

#define Sun_Max 100
#define Water_Max 30

uint8_t buff[128];

float Temp;       //温度
float Sun_Temp;   //光强
float Water_High; //AD转换之后水位

uint16_t Water_AD; //AD检测水位值
uint8_t Key1,Key2;

void ShowData(void);    //数据页面
void GetData(void);			//获取数据
void Menu_key_set(void);//按键扫描
void Key_Mune(void);		//按键切换页面操作
void Get_Key(void);

int main(void)
{	
	SystemInit();  
	Delay_Init();		 //滴答定时器初始化
	OLED_Init();			//OLED屏初始化
	OLED_Clear();//清屏
	OLED_ShowChinese(40,28,"联网中");
	OLED_Update(); //更新数据

	DS18B20_Init();
	BH1750_Init();
	AD_Init();
	JDQ_Init();
	Key_Init();
	

	ESP8266_Config(); //初始化wifi
	//连接网络
	ConnectToHotspot();
	//连接巴法云
	ConnectToBaffServer();

	sprintf((char*)buff,"cmd=1&uid=%s&topic=%s\r\n",PRODUCTID,"DZQ");
	WifiSendStr((char*)buff);
	OLED_Clear();

	while(1)
	{
		if(timekey[0]>=timekey[1]) //10ms扫描一次按键
		{
			Get_Key();
			timekey[0]=0;
		}
		if(timeled[0]>=timeled[1]) //2s进入
		{	
			GetData();  //获取数据
			ShowData(); //显示数据
			
			sprintf((char*)buff,"cmd=2&uid=%s&topic=%s&msg=%.2f\r\n",PRODUCTID,"Temp",Temp);
			WifiSendStr((char*)buff);
			//向巴法云发送温度
			sprintf((char*)buff,"cmd=2&uid=%s&topic=%s&msg=%.2f\r\n",PRODUCTID,"Sun",Sun_Temp);
			WifiSendStr((char*)buff);
			//向巴法云发送光强
			sprintf((char*)buff,"cmd=2&uid=%s&topic=%s&msg=#%.2f\r\n",PRODUCTID,"WaterHigh",Water_High);
			WifiSendStr((char*)buff);
			//向巴法云发送水位
			timeled[0]=0;
		}
	}
}

void ShowData(void)
{
	/*温度*/
	OLED_ShowChinese(0,0,"温度");
	OLED_ShowChar(32,0,':',OLED_8X16);
	OLED_ShowFloatNum(41,0,Temp,2,1,OLED_8X16);
	/*光强*/
	OLED_ShowChinese(0,16,"光强");
	OLED_ShowChar(32,16,':',OLED_8X16);
	OLED_ShowFloatNum(41,17,Sun_Temp,5,0,OLED_8X16);
	/*水位*/
	OLED_ShowChinese(0,32,"水位");
	OLED_ShowChar(32,32,':',OLED_8X16);
	OLED_ShowFloatNum(41,34,Water_High,2,2,OLED_8X16);
	
   	OLED_Update();	
}

void GetData(void)
{
    Temp = DS18B20_GetTemperture();
	Sun_Temp = BH1750_GetLightIntensity();
	Water_AD = Get_AD_Average(ADC_Channel_1,10);     //获取通道1的水位AD值
	Water_High = Water_Sensor_Read(ADC_Channel_1,10); //获取通道1水位经过公式转换的具体值
	
	if(Water_High>=Water_Max)
	{
		JDQ_ON();
	}
}

void Get_Key()
{
	Key1=Get_Key_1();
	Key2=Get_Key_2();
	
	if(Key1 == 1)
		JDQ_ON();
	if(Key2 == 2)
		JDQ_OFF();
}

 

 DS18B20.c

#ifndef _DS18B20_H_
#define _DS18B20_H_

#include "stm32f10x.h"
#include "delay.h"
#include "sys.h"

/*  DS18B20时钟端口、引脚定义 */
#define DS18B20_PORT 				GPIOB 
#define DS18B20_PIN 				(GPIO_Pin_9)
#define DS18B20_PORT_RCC			RCC_APB2Periph_GPIOB


IO操作函数											   
#define	DS18B20_DQ_OUT PBout(9) //数据端口	
#define	DS18B20_DQ_IN  PBin(9)  //数据端口	 
   	
u8 DS18B20_Init(void);			//初始化DS18B20
float DS18B20_GetTemperture(void);	//获取温度
void DS18B20_Start(void);		//开始温度转换
void DS18B20_Write_Byte(u8 dat);//写入一个字节
u8 DS18B20_Read_Byte(void);		//读出一个字节
u8 DS18B20_Read_Bit(void);		//读出一个位
u8 DS18B20_Check(void);			//检测是否存在DS18B20
void DS18B20_Reset(void);			//复位DS18B20   

#endif

 BH1750

BH1750.c

#include "stm32f10x.h"                  // Device header
#include "IIC.h"
#include "BH1750.h"

/*
 *==============================================================================
 *函数名称:BH1750_Read_Measure
 *函数功能:读取BH1750测量数据
 *输入参数:无
 *返回值:0:读取失败;其他:光照强度
 *备  注:无
 *==============================================================================
 */
u16 BH1750_Read_Measure (void)
{
	u16 receData = 0;
	
	I2C_Start();
	
	// 发送从设备地址,1:读
	Send_Byte(BH1750_Addr | 1);
	
	if(I2C_WaitAck() == 1)
	{
		return 0;
	}
	
	// 读取高八位
	receData = IIC_Read_Byte();
	IIC_Ack();
	
	// 读取低八位
	receData = (receData << 8) + IIC_Read_Byte();
	IIC_NAck();
	I2C_Stop();
	
	return receData;   // 返回读取到的数据
}

/*
 *==============================================================================
 *函数名称:BH1750_Init
 *函数功能:初始化BH1750
 *输入参数:无
 *返回值:无
 *备  注:无
 *==============================================================================
 */
void BH1750_Init (void)
{
	// 结构体定义
 	GPIO_InitTypeDef  GPIO_InitStructure;
	
	// 开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	// 初始化GPIO结构体
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14;	 
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;   // 开漏输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(GPIOB, &GPIO_InitStructure);

	// 给一个停止信号, 复位I2C总线上的所有设备到待机模式
	I2C_Stop();
	
	// BH1750上电
	BH1750_Byte_Write(POWER_ON);
	
	// 复位BH1750
	BH1750_Byte_Write(MODULE_RESET);
	
	// 写入测量模式
	BH1750_Byte_Write(Measure_Mode);
}

/*
 *==============================================================================
 *函数名称:BH1750_GetLightIntensity
 *函数功能:获取光照强度
 *输入参数:无
 *返回值:光照强度
 *备  注:分辨率	光照强度(单位lx)=(High Byte  + Low Byte)/ 1.2 * 测量精度
 *==============================================================================
 */
float BH1750_GetLightIntensity (void)
{
	return (float)(BH1750_Read_Measure() / 1.1f * Resolution);   //返回测量光照强度
}

BH1750.h

#ifndef __BH1750_H__
#define __BH1750_H__


//测量模式
#define Measure_Mode   CONTINUE_H_MODE

//分辨率	光照强度(单位lx)=(High Byte  + Low Byte)/ 1.2 * 测量精度
#if ((Measure_Mode == CONTINUE_H_MODE2)|(Measure_Mode == ONE_TIME_H_MODE2))
	#define Resolurtion		0.5
#elif ((Measure_Mode == CONTINUE_H_MODE)|(Measure_Mode == ONE_TIME_H_MODE))
	#define Resolution		1
#elif ((Measure_Mode == CONTINUE_L_MODE)|(Measure_Mode == ONE_TIME_L_MODE))
	#define Resolution		4
#endif

// SCL
#define BH1750_SCL_Clr()   GPIO_ResetBits(GPIOB,GPIO_Pin_14)
#define BH1750_SCL_Set()   GPIO_SetBits(GPIOB,GPIO_Pin_14)
// SDA
#define BH1750_SDA_Clr()   GPIO_ResetBits(GPIOB,GPIO_Pin_13)
#define BH1750_SDA_Set()   GPIO_SetBits(GPIOB,GPIO_Pin_13)

// 读取SDA电平
#define BH1750_SDA_DATA()   GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13)


u16 BH1750_Read_Measure (void);
void BH1750_Init (void);
float BH1750_GetLightIntensity (void);


#endif

iic

iic.c

#include "stm32f10x.h"                  // Device header
#include "BH1750.h"
#include "IIC.h"
/*
 *==============================================================================
 *函数名称:IIC_Delay
 *函数功能:IIC延时
 *输入参数:无
 *返回值:无
 *备  注:数据手册提供
 *==============================================================================
 */
void IIC_Delay (void)
{
	u8 t = 10;
	while (t--);
}
/*
 *==============================================================================
 *函数名称:I2C_Start
 *函数功能:IIC起始信号
 *输入参数:无
 *返回值:无
 *备  注:数据手册提供
 *==============================================================================
 */
void I2C_Start (void)
{
	BH1750_SDA_Set();//拉高
	BH1750_SCL_Set();//拉高
	IIC_Delay();
	BH1750_SDA_Clr();//拉低
	IIC_Delay();
	BH1750_SCL_Clr(); //拉低
	IIC_Delay();
}
/*
 *==============================================================================
 *函数名称:I2C_Stop
 *函数功能:IIC终止信号
 *输入参数:无
 *返回值:无
 *备  注:数据手册提供
 *==============================================================================
 */
void I2C_Stop (void)
{
	BH1750_SDA_Clr();
	BH1750_SCL_Set();
	IIC_Delay();
	BH1750_SDA_Set();
}
/*
 *==============================================================================
 *函数名称:IIC_Ack
 *函数功能:CPU产生一个ACK信号
 *输入参数:无
 *返回值:无
 *备  注:无
 *==============================================================================
 */
void IIC_Ack (void)
{
	BH1750_SDA_Clr();
	IIC_Delay();
	BH1750_SCL_Set();
	IIC_Delay();
	BH1750_SCL_Clr();
	IIC_Delay();
	BH1750_SDA_Set();
}
/*
 *==============================================================================
 *函数名称:IIC_NAck
 *函数功能:CPU产生一个NACK信号
 *输入参数:无
 *返回值:无
 *备  注:无
 *==============================================================================
 */
void IIC_NAck (void)
{
	BH1750_SDA_Set();
	IIC_Delay();
	BH1750_SCL_Set();
	IIC_Delay();
	BH1750_SCL_Clr();
	IIC_Delay();	
}
/*
 *==============================================================================
 *函数名称:I2C_WaitAck
 *函数功能:IIC等待应答
 *输入参数:无
 *返回值:0:未收到应答信号;1:收到应答信号
 *备  注:无
 *==============================================================================
 */
u8 I2C_WaitAck (void)
{
	u8 re;

	BH1750_SDA_Set();
	IIC_Delay();
	BH1750_SCL_Set();
	IIC_Delay();
	if (BH1750_SDA_DATA())
	{
		re = 1;
	}
	else
	{
		re = 0;
	}
	
	BH1750_SCL_Clr();
	IIC_Delay();
	
	return re;
}
/*
 *==============================================================================
 *函数名称:Send_Byte
 *函数功能:写入一个字节
 *输入参数:dat:需要写入的数据
 *返回值:无
 *备  注:数据手册提供
 *==============================================================================
 */
void Send_Byte (u8 dat)
{
	u8 i;

	for (i = 0;i < 8;i ++)
	{
		// 发送数据时,从高位依次写入
		if (dat & 0x80)
		{
			BH1750_SDA_Set();
		}
		else
		{
			BH1750_SDA_Clr();
		}
		IIC_Delay();
		BH1750_SCL_Set();
		IIC_Delay();
		BH1750_SCL_Clr();
		
		// dat左移1位
		dat <<= 1;
	}
}
/*
 *==============================================================================
 *函数名称:IIC_Read_Byte
 *函数功能:IIC读取一个字节数据
 *输入参数:无
 *返回值:无
 *备  注:读取到的一个字节数据
 *==============================================================================
 */
u8 IIC_Read_Byte (void)
{
	u8 i;
	u8 value;
	
	// 高位在前
	value = 0;
	
	// 循环读取8bit数据
	for (i = 0; i < 8; i ++)
	{
		value <<= 1;   // 循环左移一位
		
		BH1750_SCL_Set();
		IIC_Delay();
		
		// 如果是“1”
		if (BH1750_SDA_DATA())
		{
			value ++;
		}
		
		BH1750_SCL_Clr();
		IIC_Delay();
	}
	
	return value;
}
//BH1750写一个字节
//返回值	成功:0		失败:非0 
/*
 *==============================================================================
 *函数名称:BH1750_Byte_Write
 *函数功能:BH1750写一个字节
 *输入参数:data:要写入的数据
 *返回值:0:写入成功;1/2:写入失败
 *备  注:无
 *==============================================================================
 */
u8 BH1750_Byte_Write (u8 data)
{
	I2C_Start();
	
	// 发送从设备地址,0:写
	Send_Byte(BH1750_Addr | 0);
	
	// 收到应答信号
	if(I2C_WaitAck() == 1)
	{
		return 1;
	}
	//发送控制命令
	Send_Byte(data);
	
	// 收到应答信号
	if(I2C_WaitAck() == 1)
	{
		return 2;
	}
	
	I2C_Stop();
	
	return 0;
}

iic.h

#ifndef __IIC_H__
#define __IIC_H__


// BH1750的地址(Addr=“H”)
#define BH1750_Addr         0x46

// BH1750指令
#define POWER_OFF			0x00
#define POWER_ON			0x01
#define MODULE_RESET		0x07
#define	CONTINUE_H_MODE		0x10
#define CONTINUE_H_MODE2	0x11
#define CONTINUE_L_MODE		0x13
#define ONE_TIME_H_MODE		0x20
#define ONE_TIME_H_MODE2	0x21
#define ONE_TIME_L_MODE		0x23

//测量模式
#define Measure_Mode   CONTINUE_H_MODE

//分辨率	光照强度(单位lx)=(High Byte  + Low Byte)/ 1.2 * 测量精度
#if ((Measure_Mode == CONTINUE_H_MODE2)|(Measure_Mode == ONE_TIME_H_MODE2))
	#define Resolurtion		0.5
#elif ((Measure_Mode == CONTINUE_H_MODE)|(Measure_Mode == ONE_TIME_H_MODE))
	#define Resolurtion		1
#elif ((Measure_Mode == CONTINUE_L_MODE)|(Measure_Mode == ONE_TIME_L_MODE))
	#define Resolurtion		4
#endif


void IIC_Delay (void);
void I2C_Start (void);
void I2C_Stop (void);
void IIC_Ack (void);
void IIC_NAck (void);
u8 I2C_WaitAck (void);
void Send_Byte (u8 dat);
u8 IIC_Read_Byte (void);
u8 BH1750_Byte_Write (u8 data);

#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值