本文主要是介绍国赛一等奖-“垃圾桶项目”,环境监测系统开源--stm32+esp8266+机智云,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
提示:
本文适用有一定嵌入式基础的人,学习与借鉴
本人大三第一次写csdn,之前在csdn上解决了不少我学习的问题,于是我也尝试的分享一下我的代码以及做过的项目!!!
目录
声明:
演示视频:
第一版环境监测系统
第二版环境监测系统
一、STM32F103系统:
1.准备工作
2.系统整体框图
完整版:
实现过程:
主函数代码:(系统过大,层层嵌套,先放主函数代码)
main.c
先从简单的来 使用stm32 ADC+DMA读取可燃气体浓度+紫外线传感器强度数据:
c文件:
h文件:
MQ-2数据处理
c文件
h文件:
紫外线传感器数据处理
c文件:
h文件:
简单的GPIO检测代码:
c文件:
h文件:
stm32串口的代码,这个很重要
c文件:
h文件:
SGP30,甲醛,CO2浓度检测:
c文件:
h文件:
BMP180大气压强,海拔高度,内部温度读取:
c文件:
h文件:
光照传感器,获取光照强度:
c文件:
h文件:
OLED屏幕代码:
c文件:
h文件:
DHT11代码:
c文件:
h文件:
ADS1115代码:
c文件:
myiic协议c文件:
myiic协议h文件:
adc1115代码c文件:
adc1115代码h文件:
PM2.5浓度读取:(从ADS1115获取电压)
c文件:
h文件:
MQ135浓度获取:(从ADS1115获取电压)
c文件:
h文件:
电容按键,外部中断:
c文件:
h文件:
声音传感器获取DB(本人随便写的,没有依据)(从ADS1115获取电压)
c文件:
h文件:
STM32定时器初始化:
sys文件
不分享了,太多了
下一篇分享esp8266+机智云的代码
声明:
本文适用有一定嵌入式基础的人,学习与借鉴
本人大三第一次写csdn,之前在csdn上解决了不少我学习的问题,于是我也尝试的分享一下我的代码以及做过的项目!!!
演示视频:
环境监测第一版
演示视频1
第一版环境监测系统
第二版环境监测系统
原理图:
提示:以下是本篇文章正文内容,下面案例可供参考
一、STM32F103系统:
1.准备工作
软件:keil5 串口助手 使用stm32标准库开发
硬件: 传感器:人体红外传感器、可燃气体传感器、倾斜、振动传感器、火焰传感器等
2.系统整体框图
完整版:
环境参数监测系统的框架:
- 传感器模块:这个模块包括各种传感器,如可燃气体传感器、PM2.5传感器、紫外线传感器、光照传感器、甲醛传感器、大气压传感器等。这些传感器会探测环境中的相应参数并将其转换成电信号。
- 数据处理模块:这个模块主要负责接收传感器模块的电信号,对其进行处理,如放大、滤波、数字化等,将其转换成可以识别的环境参数。
- 存储模块:这个模块用于存储处理后的环境参数,可以是一个内置的存储器或者是一个与云端服务器相连的存储设备。
- 显示模块:这个模块负责将处理后的环境参数显示出来。
- 报警模块:这个模块在环境参数超过预设的安全范围时会发出警报,可以是声音警报或者灯光警报,甚至可以联动其他的设备如消防系统。
- 通信模块:这个模块负责将环境参数发送到云端服务器或者其他的监测系统。通过esp8266WiFi模块,跟mqtt协议实现数据的上传云端。
- 控制模块:这个模块可以控制整个系统的工作状态,包括传感器的开关、报警系统的开关等。
实现过程:
介绍:
- 使用STM32硬件ADC、DMA模块进行传感器电压检测和环境参数转换:
- 首先,需要为可燃气体传感器和PM2.5传感器配置ADC通道,并设置DMA传输模式。
- 然后,通过DMA将ADC通道的电压值读入到STM32中。
- 根据相应的电压值与传感器特性的映射关系,进行环境参数(如可燃气体浓度和PM2.5颗粒物浓度)的计算或转换。
- 将这些环境参数通过串口发送到串口屏上进行显示。
- 使用I2C协议读取各类传感器数据:
- 通过硬件I2C接口,读取紫外线传感器的数据。
- 通过软件I2C协议,读取光照传感器、甲醛传感器、大气压传感器的数据。
- 同样,需要根据各传感器的特性进行环境参数的计算或转换。
- 将这些环境参数通过串口发送到串口屏上进行显示。
- 人体红外、雨滴、倾斜、火焰传感器的检测及报警:
- 通过初始化STM32的GPIO为上拉输入或下拉输入模式,检测这些传感器的电平变化。
- 当人体红外传感器输出高电平时,说明周围有人,此时可以通过串口屏显示信息。
- 当雨滴传感器为低电平时,说明下雨了,也可以通过串口屏显示信息。
- 当倾斜传感器和火焰传感器输出低电平时,说明发生倾斜和火焰,此时可以触发蜂鸣器报警并通过串口屏显示相应信息。
- DHT11温湿度数据读取:
- 通过单总线协议读取DHT11的温湿度数据。
- 将读取的温湿度数据通过串口发送到串口屏上进行显示。
- 语音模块的数据传输与播报:
- 自定义词条以唤醒语音模块。
- 当语音模块被唤醒后,通过串口接收STM32发送的环境信息数据。
- 根据接收到的数据,语音模块可以播报当前的环境信息、垃圾信息等。
- OLED显示初始化:
- 根据所选OLED屏幕的型号和IIC协议,进行OLED屏幕的初始化配置。
- 在屏幕上显示联网信息等。
- 联网:
1.硬件准备
- ESP8266模块:用于联网和传输数据。
- 传感器:包括可燃气体传感器、PM2.5传感器、紫外线传感器、光照传感器、甲醛传感器、大气压传感器等,根据需要选择和配置。
- 执行器:当环境参数超过一定阈值时,报警。
- 显示屏:用于显示环境参数或其他信息。
- 软件设置
需要使用MQTT协议将环境参数数据发送到云端。以下是实现这一目标的基本步骤:
- 使用Arduino IDE或适当的编程环境编写代码。
- 在代码中,首先配置ESP8266的网络连接和MQTT相关的参数,包括服务器地址、端口号、用户名和密码等。
- 为每个传感器编写读取数据的代码,并根据其特性和协议,将数据转换为适当的数值或状态。
- 使用现有的MQTT库(如Eclipse Paho MQTT C库)将读取的传感器数据发布到云端。可以使用预设的主题(topic)来发布数据。
- 数据传输和云端连接
当ESP8266联网后,它将自动按照在代码中设置的MQTT协议参数连接到MQTT服务器,并将传感器数据发布到相应的主题。
- 选择一个可靠且能够存储这些数据的云平台(例如IoT云平台),并获取相应的服务器地址、端口号、用户名和密码等信息。
- 在ESP8266的代码中,将这些信息设置为MQTT连接的参数。
- 上传代码并启动ESP8266。一旦ESP8266成功连接到MQTT服务器,它将自动发布传感器数据到指定的主题。
- 在云平台上设置一个订阅者(subscriber)来监听这些数据,当有新的数据发布时,云端会接收到这些数据并进行存储、分析和可视化等操作。
- 可以根据需要设置触发器(trigger)和操作(action),当环境参数超过一定阈值时,执行相应的操作。例如,当PM2.5浓度过高时,可以自动发送一个通知到用户的手机提醒注意环境状况。
- 可视化与控制
在云端平台上,可以根据需要设置各种功能来实现对环境参数的监控和控制。例如:
- 可视化界面:在网页上以图形化方式展示环境参数的变化趋势,支持历史数据的查询和对比。
- 数据存储和分析:将收集到的环境参数数据存储在数据库中,并利用各种算法和统计方法进行数据分析,例如异常检测、预测未来趋势等。
- 报警通知:当环境参数超过预设的安全范围时,可以通过邮件、短信、电话等方式发送报警通知给相关人员。
主函数代码:(系统过大,层层嵌套,先放主函数代码)
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.h"
#include "MQ-2.h"
#include "sgp30.h"
#include "Timer.h"
#include "Serial.h"
#include "BMP180.h"
#include "jiance.h"
#include "HT1750.h"
#include "DHT11.h"
#include "MyRTC.h"
#include "PM2_5.h"
#include "MQ135.h"
#include "dB.h"
#include "I2C.h"
#include "CountSensor.h"
#include "Ultraviolet.h"
#include "usart3.h"
#include "LED.h"
#include "gizwits_product.h" //导入各模块头文件extern uint16_t AD_Value[2]; //AD0 MQ2PPM AD1 紫外线强度 ADC采集值
extern u32 CO2Data,TVOCData; //C02、TVOC浓度全局变量
extern float ppm; //AD0 MQ2PPM
extern Initialize_BMP180 Calibration_BMP180; //BMP180 结构体全局变量
extern uint8_t Keynum,Serial_RxData1,Serial_RxFlag1,Serial_RxFlag2,Serial_RxData2; //按键键码 串口0接受数据 串口0接受数据标志位 uint8_t wifi_sta,Wifi_Value=1;
uint8_t Temp,RH,UV,DB; //温度、湿度,紫外线等级 浓度全局变量
uint8_t Flag_Time; //读取时间
extern uint8_t yudi,huoyan,rentihongwai,qingxie,zhendong; //检测传感器是否触发全局变量
uint16_t PM2_5,Ultraviolet_light; //PM2.5浓度 紫外线强度 全局变量
float Lux,MQ135; //光照强度全局变量 MQ135浓度
dataPoint_t currentDataPoint; //用户数据上云结构体uint16_t Environmental_monitoring[6];void IWDG_Init(void) //独立看门狗初始化
{IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);IWDG_SetPrescaler(IWDG_Prescaler_64);IWDG_SetReload(4095); //6秒左右IWDG_ReloadCounter();IWDG_Enable();if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) == SET) //标志位查看是否为看门狗复位{OLED_ShowString(4, 12, " ");OLED_ShowString(4, 12, "IWDG");Delay_ms(500);OLED_ShowString(4, 12, " ");Delay_ms(100);RCC_ClearFlag();}else{OLED_ShowString(4, 12, " ");OLED_ShowString(4, 12, "RST");Delay_ms(500);OLED_ShowString(4, 12, " ");Delay_ms(100);}
}//协议初始化
void Gizwits_Init(void)
{ TIM3_Int_Init(9,7199);usart3_init(9600);memset((uint8_t*)¤tDataPoint, 0, sizeof(dataPoint_t));gizwitsInit();
}void userHandle(void)//用户数据
{currentDataPoint.valueHumi = RH;//Add Sensor Data CollectioncurrentDataPoint.valueUV = UV;//Add Sensor Data CollectioncurrentDataPoint.valueTemp = Calibration_BMP180.Temperature/10+(Calibration_BMP180.Temperature%10)*0.1;//Add Sensor Data Collection
// currentDataPoint.valueTemp =Temp;currentDataPoint.valueMQ_2 = ppm;//Add Sensor Data CollectioncurrentDataPoint.valueTVOC = TVOCData;//Add Sensor Data CollectioncurrentDataPoint.valueCO2 = CO2Data;//Add Sensor Data CollectioncurrentDataPoint.valueLUX = Lux;//Add Sensor Data CollectioncurrentDataPoint.valueHarmful = MQ135;currentDataPoint.valuePM_2_5=PM2_5;currentDataPoint.valuedB=DB;currentDataPoint.valueyudi = !yudi;//Add Sensor Data CollectioncurrentDataPoint.valuerentihongwai = rentihongwai;//Add Sensor Data CollectioncurrentDataPoint.valuezhendong = zhendong;//Add Sensor Data CollectioncurrentDataPoint.valuehuoyan =!huoyan ;//Add Sensor Data CollectioncurrentDataPoint.valueqingxie =!qingxie ;//Add Sensor Data CollectioncurrentDataPoint.valueKpa = Calibration_BMP180.P/1000.0;//Add Sensor Data CollectioncurrentDataPoint.valuem = Calibration_BMP180.Altitude;//Add Sensor Data Collection}
void Data_Integration(void)
{Environmental_monitoring[0]=(uint16_t)TVOCData;Environmental_monitoring[1]=(uint16_t)CO2Data;Environmental_monitoring[2]=PM2_5;Environmental_monitoring[3]=MQ135;Environmental_monitoring[4]=(uint16_t)ppm; //MQ2Environmental_monitoring[5]=(uint16_t)Calibration_BMP180.P/1000.0;
}int main(void)
{uint8_t i;OLED_Init();//OLED初始化 AD_Init(); //ADC+DMA 初始化Serial_Init();//串口初始化
// ESP8266RST_Init(); //复位esp8266初始化 第二代无使用
// ESP8266_RST(); //复位esp8266Gizwits_Init(); //初始化wifi模块 gizwitsSetMode(WIFI_AIRLINK_MODE); //配置模组进入 AirLink 模式Serial_Printf("j0.val=5\xFF\xFF\xFF");OLED_ShowString(2, 3, "loading.....");//OLED加载数值OLED_ShowString(3, 3, "loading.....");MyI2C_Init(); //初始化BMP180 IIC通信BMP180_Init(); //初始化BMP180IIC_Init(); //ADS1115 IIC通信Beep_Init(); //beepBH1750_Init(); //光照传感器BH1750初始化DHT11_Init(); //温湿度传感器初始化GP2Y1014AU0F_Init(); //PM2.5Serial_Printf("j0.val=10\xFF\xFF\xFF"); //串口屏加载数值jiance_Init(); //各D0传感器监测OLED_ShowString(2, 3, "loading.....");//OLED加载数值OLED_ShowString(3, 3, "loading.....");Serial_Printf("j0.val=20\xFF\xFF\xFF");TVOC_Init();//循环很久,sgp30初始化 OLED_ShowString(2, 3, " ");OLED_ShowString(3, 3, " ");Delay_ms(200);Serial_Printf("j0.val=70\xFF\xFF\xFF");OLED_ShowString(1, 1, "Date:XXXX-XX-XX");OLED_ShowString(2, 1, "Time:XX:XX:XX");OLED_ShowString(3,1,"AirLinkMODE");OLED_ShowString(4,1,"Temp:");OLED_ShowString(4,6,"XXC");IWDG_Init();OLED_ShowString(4,10,"RH:");OLED_ShowString(4,13,"XX%");
// Key_Init(); //初始化按键KeyNum_Init(); //初始化按键Timer_Init(); //定时器初始化Serial_Printf("j0.val=100\xFF\xFF\xFF");Serial_Printf("page page0\xFF\xFF\xFF");while (1){if(Flag_Time==1){Flag_Time=0;MQ2_Value(); //MQ2传感器读取BMP180_Result(); //BMP180传感器读取TVOC_DISPLAY(); //sgp30传感器读取Lux=LIght_Intensity();//BH1750传感器读取DHT11_Read_Data(&Temp,&RH);//DHT11传感器读取PM2_5=GetGP2YSingleValue();//PM2.5传感器读取MQ135=MQ135Value(); //MQ135传感器读取Ultraviolet_light=Ultraviolet_light_Value()*1000; //mvSerial_Printf("t50.txt=\"%d.%d\"\xFF\xFF\xFF",Calibration_BMP180.Temperature/10,Calibration_BMP180.Temperature%10);Serial_Printf("t50.txt=\"%d.%d\"\xFF\xFF\xFF",Calibration_BMP180.Temperature/10,Calibration_BMP180.Temperature%10);
// Serial_Printf("t50.txt=\"%d\"\xFF\xFF\xFF",Temp);Serial_Printf("t4.txt=\"%d\"\xFF\xFF\xFF",RH);Serial_Printf("t7.txt=\"%d\"\xFF\xFF\xFF",CO2Data);Serial_Printf("t10.txt=\"%d\"\xFF\xFF\xFF",TVOCData);Serial_Printf("t42.txt=\"%.1lf\"\xFF\xFF\xFF",MQ135);Serial_Printf("t66.txt=\"%.1lf\"\xFF\xFF\xFF",ppm);Serial_Printf("t43.txt=\"%d\"\xFF\xFF\xFF",PM2_5);Serial_Printf("t41.txt=\"%.2lf\"\xFF\xFF\xFF",Calibration_BMP180.P/1000.0);Serial_Printf("t40.txt=\"%.2lf\"\xFF\xFF\xFF",Calibration_BMP180.Altitude);Serial_Printf("t44.txt=\"%.2lf\"\xFF\xFF\xFF",Lux); //光照串口发送Ultraviolet_light_Display(); //紫外线串口发送if(Lux>300){Serial_Printf("t45.txt=\"高光\"\xFF\xFF\xFF");}else if(Lux >100&&Lux <300){Serial_Printf("t45.txt=\"中光\"\xFF\xFF\xFF");}elseSerial_Printf("t45.txt=\"低光\"\xFF\xFF\xFF");}if(Serial_RxFlag2==1){Serial_RxFlag2=0;if(Serial_RxData2==1){Data_Integration();MyUSART_SendArr(Environmental_monitoring,6);}}if(Keynum==1){Keynum=0;gizwitsSetMode(WIFI_AIRLINK_MODE); //配置模组进入 AirLink 模式OLED_ShowString(3,1,"AirLinkMODE");}if(Keynum==2){Keynum=0;gizwitsSetMode(WIFI_SOFTAP_MODE); //配置模组进入 SOFTAP 模式OLED_ShowString(3,1,"SOFTAP_MODE");}if(Keynum==3){Keynum=0;gizwitsSetMode(WIFI_RESET_MODE); //配置模组进入 复位 模式OLED_ShowString(3,1,"RESET_MODE");}if(Serial_RxFlag1==1){Serial_RxFlag1=0;if(Serial_RxData1==1){for(i=0;i<5;i++){BEEP_OUT();}}if(Serial_RxData1==2){gizwitsSetMode(WIFI_AIRLINK_MODE); //配置模组进入 AirLink 模式OLED_ShowString(3,1,"AirLinkMODE");}if(Serial_RxData1==3){gizwitsSetMode(WIFI_SOFTAP_MODE); //配置模组进入 SOFTAP 模式OLED_ShowString(3,1,"SOFTAP_MODE");}if(Serial_RxData1==4){gizwitsSetMode(WIFI_RESET_MODE); //配置模组进入 复位 模式OLED_ShowString(3,1,"RESET_MODE");}}
// MyRTC_ReadTime(); //读取RTC时钟jiance_Scan_Run(); //循环检测传感器userHandle();//数据上行gizwitsHandle((dataPoint_t *)¤tDataPoint);//协议处理gizwitsGetNTP();if(Wifi_Value==1){if(wifi_sta==1||MyRTC_Time[0]!=1970){Wifi_Value=0;OLED_ShowString(3, 13, "wifi");}}
// OLED_ShowNum(4, 1, MQ135,5);OLED_ShowNum(1, 6, MyRTC_Time[0], 4); //RTC OLED显示OLED_ShowNum(1, 11, MyRTC_Time[1], 2);OLED_ShowNum(1, 14, MyRTC_Time[2], 2);OLED_ShowNum(2, 6, MyRTC_Time[3], 2);OLED_ShowNum(2, 9, MyRTC_Time[4], 2);OLED_ShowNum(2, 12, MyRTC_Time[5], 2);OLED_ShowNum(4,6,Temp,2);OLED_ShowNum(4,13,RH,2);IWDG_ReloadCounter(); //喂狗}
}void TIM2_IRQHandler(void)
{if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){Flag_Time=1;TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}
}
先从简单的来 使用stm32 ADC+DMA读取可燃气体浓度+紫外线传感器强度数据:
内容过多直接上代码:
c文件:
#include "stm32f10x.h" // Device headeruint16_t AD_Value[2];void AD_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);RCC_ADCCLKConfig(RCC_PCLK2_Div6);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_55Cycles5);
// ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_55Cycles5);
// ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_55Cycles5);ADC_InitTypeDef ADC_InitStructure;ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;ADC_InitStructure.ADC_ScanConvMode = ENABLE;ADC_InitStructure.ADC_NbrOfChannel = 2;ADC_Init(ADC1, &ADC_InitStructure);DMA_InitTypeDef DMA_InitStructure;DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)AD_Value;DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;DMA_InitStructure.DMA_BufferSize = 2;DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;DMA_Init(DMA1_Channel1, &DMA_InitStructure);DMA_Cmd(DMA1_Channel1, ENABLE);ADC_DMACmd(ADC1, ENABLE);ADC_Cmd(ADC1, ENABLE);ADC_ResetCalibration(ADC1);while (ADC_GetResetCalibrationStatus(ADC1) == SET);ADC_StartCalibration(ADC1);while (ADC_GetCalibrationStatus(ADC1) == SET);ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
这里不懂的可以看看江科大的视频,我的启蒙老师
主要就是开始ADC采集电压+DMA搬运数据
ADC多通道采集 DMA连续搬运 结合起来就是:连续扫描模式
h文件:
#ifndef __AD_H
#define __AD_Hextern uint16_t AD_Value[2];void AD_Init(void);#endif
MQ-2数据处理
c文件
#include "stm32f10x.h" // Device header
#include "math.h"
#include "OLED.h"
#include "Delay.h"extern uint16_t AD_Value[2];
float ppm;//#define CAL_PPM 20 // 校准环境中PPM值
//#define RL 5 // RL阻值
//static float R0=6; // 元件在洁净空气中的阻值传感器校准函数
//void MQ2_PPM_Calibration(float RS)
//{
// R0 = RS / pow(CAL_PPM / 613.9f, 1 / -2.074f);
//}
//
// // MQ2传感器数据处理
//float MQ2_GetPPM(void)
//{
// float Vrl = 3.3f * AD_Value[0] / 4095.f;
// float RS = (3.3f - Vrl) / Vrl * RL;
// if(boot_time_ms < 3000) // 获取系统执行时间,3s前进行校准
// {
// MQ2_PPM_Calibration(RS);
// }
// float ppm = 613.9f * pow(RS/R0, -2.074f);
// OLED_ShowNum(1, 5, ppm, 4);
// return ppm;
//}void MQ2_Value(void)
{uint16_t Value;float temp;Value=AD_Value[0];temp=Value*(3.3/4096);ppm = (temp - 0.4f) / 0.4f * 10000.0f;//使用C标准库函数pow(x,y)求得ppm;//其作用是计算x的y次方。x、y及函数值都是double型//ppm = pow(11.5428 * 35.904 * Vrl/(25.5-5.1* Vrl),0.6549);ppm=pow(11.5428 * 35.904 * temp/(25.5-5.1* temp),1.0/0.6549);
}
公式:
h文件:
#ifndef __MQ2_H
#define __MQ2_Hvoid MQ2_Init(void);
float MQ2_GetPPM(void);
void MQ2_Value(void);#endif
紫外线传感器数据处理
c文件:
#include "stm32f10x.h" // Device header
#include "Serial.h"
extern uint16_t AD_Value[2];
extern uint16_t Ultraviolet_light;
extern uint8_t UV;
float Ultraviolet_light_Value(void) //采集ADC电压,紫外线传感器是依据电压来确定强度的
{float V;V=AD_Value[1]*(3.3/4096);return V;
}void Ultraviolet_light_Display(void) //串口屏显示代码 判断电压大小 mv
{if(Ultraviolet_light<50){Serial_Printf("t46.txt=\"%d\"\xFF\xFF\xFF",0);Serial_Printf("t47.txt=\"低紫\"\xFF\xFF\xFF");UV=0;}else if(Ultraviolet_light>50&&Ultraviolet_light<227){Serial_Printf("t46.txt=\"%d\"\xFF\xFF\xFF",1);Serial_Printf("t47.txt=\"低紫\"\xFF\xFF\xFF");UV=1;}else if(Ultraviolet_light>227&&Ultraviolet_light<318){Serial_Printf("t46.txt=\"%d\"\xFF\xFF\xFF",2);Serial_Printf("t47.txt=\"低紫\"\xFF\xFF\xFF");UV=2;}else if(Ultraviolet_light>318&&Ultraviolet_light<408){Serial_Printf("t46.txt=\"%d\"\xFF\xFF\xFF",3);Serial_Printf("t47.txt=\"低紫\"\xFF\xFF\xFF");UV=3;}else if(Ultraviolet_light>408&&Ultraviolet_light<503){Serial_Printf("t46.txt=\"%d\"\xFF\xFF\xFF",4);Serial_Printf("t47.txt=\"中紫\"\xFF\xFF\xFF");UV=4;}else if(Ultraviolet_light>503&&Ultraviolet_light<606){Serial_Printf("t46.txt=\"%d\"\xFF\xFF\xFF",5);Serial_Printf("t47.txt=\"中紫\"\xFF\xFF\xFF");UV=5;}else if(Ultraviolet_light>606&&Ultraviolet_light<696){Serial_Printf("t46.txt=\"%d\"\xFF\xFF\xFF",6);Serial_Printf("t47.txt=\"中紫\"\xFF\xFF\xFF");UV=6;}else if(Ultraviolet_light>696&&Ultraviolet_light<795){Serial_Printf("t46.txt=\"%d\"\xFF\xFF\xFF",7);Serial_Printf("t47.txt=\"中紫\"\xFF\xFF\xFF");UV=7;}else if(Ultraviolet_light>795&&Ultraviolet_light<881){Serial_Printf("t46.txt=\"%d\"\xFF\xFF\xFF",8);Serial_Printf("t47.txt=\"高紫\"\xFF\xFF\xFF");UV=8;}else if(Ultraviolet_light>881&&Ultraviolet_light<976){Serial_Printf("t46.txt=\"%d\"\xFF\xFF\xFF",9);Serial_Printf("t47.txt=\"高紫\"\xFF\xFF\xFF");UV=9;}else if(Ultraviolet_light>976&&Ultraviolet_light<1097){Serial_Printf("t46.txt=\"%d\"\xFF\xFF\xFF",10);Serial_Printf("t47.txt=\"高紫\"\xFF\xFF\xFF");UV=10;}else if(Ultraviolet_light>1097&&Ultraviolet_light<1170){Serial_Printf("t46.txt=\"%d\"\xFF\xFF\xFF",11);Serial_Printf("t47.txt=\"高紫\"\xFF\xFF\xFF");UV=11;}else{Serial_Printf("t46.txt=\"%d+\"\xFF\xFF\xFF",11);Serial_Printf("t47.txt=\"高紫\"\xFF\xFF\xFF");UV=12;}
}
h文件:
#ifndef __Ultraviolet_H
#define __Ultraviolet_Hfloat Ultraviolet_light_Value(void);
void Ultraviolet_light_Display(void);
#endif
简单的GPIO检测代码:
检测雨滴传感器,火焰传感器,人体红外传感器,倾斜传感器,震动传感器,蜂鸣器驱动,stm32IO口接传感器的DO口,代码很简单我就不用注释了
c文件:
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "Serial.h"
uint8_t yudi,huoyan,rentihongwai,qingxie,zhendong;
void yudi_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);
}void huoyan_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);
}void zhendong_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);
}void qingxie_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);
}void Beep_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_SetBits(GPIOA,GPIO_Pin_11);
}void rentihongwai_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);}void jiance_Init(void)
{yudi_Init();huoyan_Init();zhendong_Init();qingxie_Init();Beep_Init();rentihongwai_Init();}void BEEP_OUT(void)
{GPIO_ResetBits(GPIOA,GPIO_Pin_11);Delay_ms(500);GPIO_SetBits(GPIOA,GPIO_Pin_11);Delay_ms(500);
}void jiance_Scan_Run(void)
{yudi=GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6);huoyan=GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7);rentihongwai=GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4);qingxie=GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5);zhendong=GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_12);if(yudi==0){Delay_ms(20);if(yudi==0){Serial_Printf("t21.txt=\"下雨\"\xFF\xFF\xFF");}}elseSerial_Printf("t21.txt=\"没有\"\xFF\xFF\xFF");if(huoyan==0){Delay_ms(20);if(huoyan==0){Serial_Printf("t23.txt=\"起火\"\xFF\xFF\xFF");BEEP_OUT();}}elseSerial_Printf("t23.txt=\"没有\"\xFF\xFF\xFF");if(zhendong==1){if(zhendong==1){Serial_Printf("t24.txt=\"振动\"\xFF\xFF\xFF");}}elseSerial_Printf("t24.txt=\"没有\"\xFF\xFF\xFF");if(qingxie==0){Delay_ms(20);if(qingxie==0){Serial_Printf("t26.txt=\"倾斜\"\xFF\xFF\xFF");BEEP_OUT();}}elseSerial_Printf("t26.txt=\"没有\"\xFF\xFF\xFF");if(rentihongwai==1){Delay_ms(20);if(rentihongwai==1){Serial_Printf("t19.txt=\"有人\"\xFF\xFF\xFF");} }elseSerial_Printf("t19.txt=\"没有\"\xFF\xFF\xFF");}
h文件:
#ifndef __JIANCE_H
#define __JIANCE_Hvoid yudi_Init(void);void huoyan_Init(void);void zhendong_Init(void);void qingxie_Init(void);void Beep_Init(void);
void jiance_Scan_Run(void);
void BEEP_OUT(void);
void jiance_Init(void);#endif
stm32串口的代码,这个很重要
c文件:
#include "stm32f10x.h" // Device header
#include <stdio.h>
#include <stdarg.h>uint8_t Serial_RxData1,Serial_RxData2;
uint8_t Serial_RxFlag1,Serial_RxFlag2;void Serial_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_2;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_3;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);USART_InitTypeDef USART_InitStructure;USART_InitStructure.USART_BaudRate = 115200;USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;USART_InitStructure.USART_Parity = USART_Parity_No;USART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_Init(USART1, &USART_InitStructure);USART_InitStructure.USART_Mode = USART_Mode_Tx| USART_Mode_Rx;USART_Init(USART2, &USART_InitStructure);USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_Init(&NVIC_InitStructure);NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;NVIC_Init(&NVIC_InitStructure);USART_Cmd(USART1, ENABLE);USART_Cmd(USART2, ENABLE);
}void Serial_SendByte(uint8_t Byte)
{USART_SendData(USART1, Byte);while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}void Serial2_SendByte(uint8_t Byte)
{USART_SendData(USART2, Byte);while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
}void Serial1_SendArray(uint8_t *Array, uint16_t Length)
{uint16_t i;for (i = 0; i < Length; i ++){Serial_SendByte(Array[i]);}
}void Serial2_SendArray(uint8_t *Array, uint16_t Length)
{uint16_t i;for (i = 0; i < Length; i ++){Serial2_SendByte(Array[i]);}
}void Usart_SendHalfWord(USART_TypeDef * pUSARTx, uint16_t ch)
{uint8_t High, Low;High = (ch&0XFF00)>>8;Low = ch&0XFF;USART_SendData(pUSARTx,High); while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);USART_SendData(pUSARTx,Low); while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
}
/***************** ??16Bit????**********************/
void MyUSART_SendArr(uint16_t *str,uint8_t count)
{uint8_t i=0;for(i=0;i<count;i++){Usart_SendHalfWord(USART2,*(str+i));}while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET);
} void Serial_SendString(char *String)
{uint8_t i;for (i = 0; String[i] != '\0'; i ++){Serial_SendByte(String[i]);}
}void Serial2_SendString(char *String)
{uint8_t i;for (i = 0; String[i] != '\0'; i ++){Serial2_SendByte(String[i]);}
}uint32_t Serial_Pow(uint32_t X, uint32_t Y)
{uint32_t Result = 1;while (Y --){Result *= X;}return Result;
}void Serial_SendNumber(uint32_t Number, uint8_t Length)
{uint8_t i;for (i = 0; i < Length; i ++){Serial_SendByte(Number / Serial_Pow(10, Length - i - 1) % 10 + '0');}
}int fputc(int ch, FILE *f)
{Serial_SendByte(ch);return ch;
}void Serial_Printf(char *format, ...)
{char String[100];va_list arg;va_start(arg, format);vsprintf(String, format, arg);va_end(arg);Serial_SendString(String);
}void Serial2_Printf(char *format, ...)
{char String[100];va_list arg;va_start(arg, format);vsprintf(String, format, arg);va_end(arg);Serial2_SendString(String);
}void USART1_IRQHandler(void)
{if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET){Serial_RxData1 = USART_ReceiveData(USART1);Serial_RxFlag1 = 1;USART_ClearITPendingBit(USART1, USART_IT_RXNE);}
}void USART2_IRQHandler(void)
{if (USART_GetITStatus(USART2, USART_IT_RXNE) == SET){Serial_RxData2 = USART_ReceiveData(USART2);Serial_RxFlag2 = 1;USART_ClearITPendingBit(USART2, USART_IT_RXNE);}
}
这里使用的是江科大的串口代码,不会的可以去看视频,主要是Serial_Printf()函数写的很好
初始波特率为115200,8位数据位,1位停止位,无检验位。初始化串口1,2
h文件:
#ifndef __SERIAL_H
#define __SERIAL_H#include <stdio.h>void Serial_Init(void);
void Serial_SendByte(uint8_t Byte);
void Serial_SendArray(uint8_t *Array, uint16_t Length);
void Serial_SendString(char *String);
void Serial2_SendArray(uint8_t *Array, uint16_t Length);
void MyUSART_SendArr(uint16_t *str,uint8_t count);
void Serial_SendNumber(uint32_t Number, uint8_t Length);
void Serial_Printf(char *format, ...);
void Serial2_Printf(char *format, ...);uint8_t Serial_GetRxFlag(void);
uint8_t Serial_GetRxData(void);#endif
SGP30,甲醛,CO2浓度检测:
c文件:
#include "stm32f10x.h" // Device header
#include "sgp30.h"
#include "Delay.h"u32 CO2Data,TVOCData;//¶¨ÒåCO2Ũ¶È±äÁ¿ÓëTVOCŨ¶È±äÁ¿
unsigned long sgp30_dat;void HX711_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(SGP30_SCL_GPIO_CLK | SGP30_SDA_GPIO_SDA, ENABLE);GPIO_InitStructure.GPIO_Pin = SGP30_SCL_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(SGP30_SCL_GPIO_PORT, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = SGP30_SDA_GPIO_PIN;GPIO_Init(SGP30_SDA_GPIO_PORT, &GPIO_InitStructure);
}void SDA_OUT(void)
{GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = SGP30_SDA_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(SGP30_SDA_GPIO_PORT, &GPIO_InitStructure);
}void SDA_IN(void)
{GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = SGP30_SDA_GPIO_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(SGP30_SDA_GPIO_PORT, &GPIO_InitStructure);
}//²úÉúIICÆðʼÐźÅ
void SGP30_IIC_Start(void)
{SDA_OUT();SGP30_SDA = 1;SGP30_SCL = 1;Delay_us(20);SGP30_SDA = 0; //START:when CLK is high,DATA change form high to lowDelay_us(20);SGP30_SCL = 0; //ǯסI2C×ÜÏߣ¬×¼±¸·¢ËÍ»ò½ÓÊÕÊý¾Ý
}//²úÉúIICÍ£Ö¹ÐźÅ
void SGP30_IIC_Stop(void)
{SDA_OUT();SGP30_SCL = 0;SGP30_SDA = 0; //STOP:when CLK is high DATA change form low to highDelay_us(20);SGP30_SCL = 1;SGP30_SDA = 1; //·¢ËÍI2C×ÜÏß½áÊøÐźÅDelay_us(20);
}//µÈ´ýÓ¦´ðÐźŵ½À´
//·µ»ØÖµ£º1£¬½ÓÊÕÓ¦´ðʧ°Ü
// 0£¬½ÓÊÕÓ¦´ð³É¹¦
u8 SGP30_IIC_Wait_Ack(void)
{u8 ucErrTime = 0;SDA_IN();SGP30_SDA = 1;Delay_us(10);SGP30_SCL = 1;Delay_us(10);while(SGP30_SDA_READ()){ucErrTime++;if(ucErrTime > 250){SGP30_IIC_Stop();return 1;}}SGP30_SCL = 0; //ʱÖÓÊä³ö0return 0;
}//²úÉúACKÓ¦´ð
void SGP30_IIC_Ack(void)
{SGP30_SCL = 0;SDA_OUT();SGP30_SDA = 0;Delay_us(20);SGP30_SCL = 1;Delay_us(20);SGP30_SCL = 0;
}//²»²úÉúACKÓ¦´ð
void SGP30_IIC_NAck(void)
{SGP30_SCL = 0;SDA_OUT();SGP30_SDA = 1;Delay_us(20);SGP30_SCL = 1;Delay_us(20);SGP30_SCL = 0;
}//IIC·¢ËÍÒ»¸ö×Ö½Ú
//·µ»Ø´Ó»úÓÐÎÞÓ¦´ð
//1£¬ÓÐÓ¦´ð
//0£¬ÎÞÓ¦´ð
void SGP30_IIC_Send_Byte(u8 txd)
{u8 t;SDA_OUT();SGP30_SCL = 0; //ÀµÍʱÖÓ¿ªÊ¼Êý¾Ý´«Êäfor(t = 0; t < 8; t++){if((txd & 0x80) >> 7)SGP30_SDA = 1;elseSGP30_SDA = 0;txd <<= 1;Delay_us(20);SGP30_SCL = 1;Delay_us(20);SGP30_SCL = 0;Delay_us(20);}Delay_us(20);}//¶Á1¸ö×Ö½Ú£¬ack=1ʱ£¬·¢ËÍACK£¬ack=0£¬·¢ËÍnACK
u16 SGP30_IIC_Read_Byte(u8 ack)
{u8 i;u16 receive = 0;SDA_IN();for(i = 0; i < 8; i++ ){SGP30_SCL = 0;Delay_us(20);SGP30_SCL = 1;receive <<= 1;if(SGP30_SDA_READ())receive++;Delay_us(20);}if (!ack)SGP30_IIC_NAck();//·¢ËÍnACKelseSGP30_IIC_Ack(); //·¢ËÍACKreturn receive;
}//³õʼ»¯IIC½Ó¿Ú
void SGP30_Init(void)
{HX711_GPIO_Init();SGP30_Write(0x20, 0x03);
// SGP30_ad_write(0x20,0x61);
// SGP30_ad_write(0x01,0x00);
}void SGP30_Write(u8 a, u8 b)
{SGP30_IIC_Start();SGP30_IIC_Send_Byte(SGP30_write); //·¢ËÍÆ÷¼þµØÖ·+дָÁîSGP30_IIC_Wait_Ack();SGP30_IIC_Send_Byte(a); //·¢ËÍ¿ØÖÆ×Ö½ÚSGP30_IIC_Wait_Ack();SGP30_IIC_Send_Byte(b);SGP30_IIC_Wait_Ack();SGP30_IIC_Stop();Delay_ms(100);
}u32 SGP30_Read(void)
{u32 dat;u8 crc;SGP30_IIC_Start();SGP30_IIC_Send_Byte(SGP30_read); //·¢ËÍÆ÷¼þµØÖ·+¶ÁÖ¸ÁîSGP30_IIC_Wait_Ack();dat = SGP30_IIC_Read_Byte(1);dat <<= 8;dat += SGP30_IIC_Read_Byte(1);crc = SGP30_IIC_Read_Byte(1); //crcÊý¾Ý£¬ÉáÈ¥crc = crc; //ΪÁ˲»ÈóöÏÖ±àÒ뾯¸ædat <<= 8;dat += SGP30_IIC_Read_Byte(1);dat <<= 8;dat += SGP30_IIC_Read_Byte(0);SGP30_IIC_Stop();return(dat);
}void TVOC_Init(void)
{ SGP30_Init(); //³õʼ»¯SGP30Delay_ms(100);SGP30_Write(0x20,0x08);sgp30_dat = SGP30_Read();//¶ÁÈ¡SGP30µÄÖµCO2Data = (sgp30_dat & 0xffff0000) >> 16;TVOCData = sgp30_dat & 0x0000ffff; //SGP30Ä£¿é¿ª»úÐèÒªÒ»¶¨Ê±¼ä³õʼ»¯£¬ÔÚ³õʼ»¯½×¶Î¶ÁÈ¡µÄCO2Ũ¶ÈΪ400ppm£¬TVOCΪ0ppdÇҺ㶨²»±ä£¬Òò´ËÉϵçºóÿ¸ô500ms¶ÁÈ¡Ò»´Î//SGP30Ä£¿éµÄÖµ£¬Èç¹ûCO2Ũ¶ÈΪ400ppm£¬TVOCΪ0ppd£¬ÔòÆÁÄ»ÉÁ˸ÏÔʾ¡°ÕýÔÚ¼ì²âÖÐ...¡±£¬Ö±µ½SGP30Ä£¿é³õʼ»¯Íê³É¡£while(CO2Data == 400 && TVOCData == 0){SGP30_Write(0x20,0x08);sgp30_dat = SGP30_Read();//¶ÁÈ¡SGP30µÄÖµCO2Data = (sgp30_dat & 0xffff0000) >> 16;//È¡³öCO2Ũ¶ÈÖµTVOCData = sgp30_dat & 0x0000ffff; //È¡³öTVOCÖµ}
}void TVOC_DISPLAY(void)
{SGP30_Write(0x20,0x08);sgp30_dat = SGP30_Read();//¶ÁÈ¡SGP30µÄÖµCO2Data = (sgp30_dat & 0xffff0000) >> 16;//È¡³öCO2Ũ¶ÈÖµTVOCData = sgp30_dat & 0x0000ffff; //È¡³öTVOCÖµ
}
使用软件IIC协议,读取数据函数为:void TVOC_DISPLAY(void) 调用即可,已经封装好了,
使用的是商家的代码,由于年代久远用的是ANSI编码,由于本人第一次写不知道反响如何,如果反响好的话我再回过头加上注释。
h文件:
#ifndef __HX711_H
#define __HX711_H
#include "sys.h"#define SGP30_SCL PBout(13)
#define SGP30_SDA PBout(14)// USART GPIO Òý½Åºê¶¨Òå
#define SGP30_SCL_GPIO_CLK RCC_APB2Periph_GPIOB
#define SGP30_SCL_GPIO_PORT GPIOB
#define SGP30_SCL_GPIO_PIN GPIO_Pin_13#define SGP30_SDA_GPIO_SDA RCC_APB2Periph_GPIOB
#define SGP30_SDA_GPIO_PORT GPIOB
#define SGP30_SDA_GPIO_PIN GPIO_Pin_14#define SGP30_SDA_READ() GPIO_ReadInputDataBit(SGP30_SDA_GPIO_PORT, SGP30_SDA_GPIO_PIN)#define SGP30_read 0xb1 //SGP30µÄ¶ÁµØÖ·
#define SGP30_write 0xb0 //SGP30µÄдµØÖ·void SGP30_IIC_Start(void); //·¢ËÍIIC¿ªÊ¼ÐźÅ
void SGP30_IIC_Stop(void); //·¢ËÍIICÍ£Ö¹ÐźÅ
void SGP30_IIC_Send_Byte(u8 txd); //IIC·¢ËÍÒ»¸ö×Ö½Ú
u16 SGP30_IIC_Read_Byte(unsigned char ack);//IIC¶ÁÈ¡Ò»¸ö×Ö½Ú
u8 SGP30_IIC_Wait_Ack(void); //IICµÈ´ýACKÐźÅ
void SGP30_IIC_Ack(void); //IIC·¢ËÍACKÐźÅ
void SGP30_IIC_NAck(void); //IIC²»·¢ËÍACKÐźÅ
void SGP30_IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
u8 SGP30_IIC_Read_One_Byte(u8 daddr,u8 addr);
void SGP30_Init(void);
void SGP30_Write(u8 a, u8 b);
u32 SGP30_Read(void);
void TVOC_DISPLAY(void);
void TVOC_Init(void);#endif
使用GPIO位带操作读取数据,定义在“sys.h”里。
BMP180大气压强,海拔高度,内部温度读取:
c文件:
#include "stm32f10x.h" // Device header
#include "math.h" //¼ÆËãÃÝÔËËãÐèÒª
#include "Delay.h"
#include "bmp180.h"Initialize_BMP180 Calibration_BMP180;//
// Èí¼þIIC
///**
* @brief ´ÓBMP180¶ÁÈ¡1¸ö×Ö½Ú
* @param ÎÞ
* @retval ¶Áµ½µÄÊý¾Ý
**/
u8 BMP180_Read(u8 Add)
{u8 temp = 0;MyI2C_Start();MyI2C_SendByte(0xEE); //дµØÖ·MyI2C_ReceiveAck();MyI2C_SendByte(Add);MyI2C_ReceiveAck();MyI2C_Stop();MyI2C_Start();MyI2C_SendByte(0xEF); //¶ÁµØÖ·MyI2C_ReceiveAck();temp = MyI2C_ReceiveByte();MyI2C_SendAck(1);MyI2C_Stop();return temp;
}/**
* @brief ´ÓBMP180¶ÁÈ¡2¸ö×Ö½Ú16λÎÞ·ûºÅ
* @param Add¶ÁµÄµØÖ·
* @retval ¶Áµ½µÄÊý¾Ý
**/
uint16_t BMP180_u16_Read(u8 Add)
{u16 temp;MyI2C_Start();MyI2C_SendByte(0xEE); //дµØÖ·MyI2C_ReceiveAck();MyI2C_SendByte(Add);MyI2C_ReceiveAck();MyI2C_Stop();MyI2C_Start();MyI2C_SendByte(0xEF); //¶ÁµØÖ·MyI2C_ReceiveAck();temp = MyI2C_ReceiveByte();MyI2C_SendAck(0);temp <<= 8;temp |= MyI2C_ReceiveByte();MyI2C_SendAck(1);MyI2C_Stop();return temp;
}/**
* @brief ´ÓBMP180¶ÁÈ¡2¸ö×Ö½Ú16λÓзûºÅ
* @param ÎÞ
* @retval ¶Áµ½µÄÊý¾Ý
**/
int16_t BMP180_int16_t_Read(u8 Add)
{int16_t temp;MyI2C_Start();MyI2C_SendByte(0xEE); //дµØÖ·MyI2C_ReceiveAck();MyI2C_SendByte(Add);MyI2C_ReceiveAck();MyI2C_Stop();MyI2C_Start();MyI2C_SendByte(0xEF); //¶ÁµØÖ·MyI2C_ReceiveAck();temp = MyI2C_ReceiveByte();MyI2C_SendAck(0);temp <<= 8;temp |= MyI2C_ReceiveByte();MyI2C_SendAck(1);MyI2C_Stop();return temp;
}/**
* @brief ³õʼ»¯BMP180»ñȡζȺÍѹÁ¦µÄУ׼ֵ
* @param ÎÞ
* @retval ÎÞ
**/
void BMP180_Init(void)
{Calibration_BMP180.AC1 = BMP180_int16_t_Read(0xAA);Calibration_BMP180.AC2 = BMP180_int16_t_Read(0xAC);Calibration_BMP180.AC3 = BMP180_int16_t_Read(0xAE);Calibration_BMP180.AC4 = BMP180_u16_Read(0xB0);Calibration_BMP180.AC5 = BMP180_u16_Read(0xB2);Calibration_BMP180.AC6 = BMP180_u16_Read(0xB4);Calibration_BMP180.B1 = BMP180_int16_t_Read(0xB6);Calibration_BMP180.B2 = BMP180_int16_t_Read(0xB8);Calibration_BMP180.MB = BMP180_int16_t_Read(0xBA);Calibration_BMP180.MC = BMP180_int16_t_Read(0xBC);Calibration_BMP180.MD = BMP180_int16_t_Read(0xBE);// printf("AC1 = %d\r\n",Calibration_BMP180.AC1); //AC1 = 7916
// printf("AC2 = %d\r\n",Calibration_BMP180.AC2); //AC2 = -1058
// printf("AC3 = %d\r\n",Calibration_BMP180.AC3); //AC3 = -14505
// printf("AC4 = %d\r\n",Calibration_BMP180.AC4); //AC4 = 33234
// printf("AC5 = %d\r\n",Calibration_BMP180.AC5); //AC5 = 25160
// printf("AC6 = %d\r\n",Calibration_BMP180.AC6); //AC6 = 18306
// printf("B1 = %d\r\n",Calibration_BMP180.B1); //B1 = 6515
// printf("B2 = %d\r\n",Calibration_BMP180.B2); //B2 = 37
// printf("MB = %d\r\n",Calibration_BMP180.MB); //MB = -32768
// printf("MC = %d\r\n",Calibration_BMP180.MC); //MC = -11786
// printf("MD = %d\r\n",Calibration_BMP180.MD); //MD = 2722
}/**
* @brief ´ÓBMP180¶ÁȡδÐÞÕýµÄÎÂ¶È µØÖ·0xF4дÈë0x2E µÈ´ý5ms ¶ÁÈ¡µØÖ·0xF6µÄÊý¾Ý
* @param ÎÞ
* @retval ¶Áµ½µÄÊý¾Ý
**/
static int32_t BMP180_Read_UT(void)
{int32_t temp_T = 0;MyI2C_Start();MyI2C_SendByte(0xEE);MyI2C_ReceiveAck();MyI2C_SendByte(0xF4);MyI2C_ReceiveAck();MyI2C_SendByte(0x2E);MyI2C_ReceiveAck();MyI2C_Stop();Delay_ms(5);temp_T = (int32_t)BMP180_int16_t_Read(0xF6);return temp_T;
}/**
* @brief ´ÓBMP180¶ÁȡδÐÞÕýµÄ´óÆøѹ µØÖ·0xF4дÈë0x34(×¢Òâoss£¬Èç¹ûΪÆäËûģʽҪ×óÒÆ6λ) µÈ´ý5ms ¶ÁÈ¡µØÖ·0xF6,0xF7,0xF8µÄÊý¾Ý
* @param ÎÞ
* @retval ¶Áµ½µÄÊý¾Ý
**/
static int32_t BMP180_Read_UP(void)
{//int16_t temp = 0;int32_t temp_P = 0;MyI2C_Start();MyI2C_SendByte(0xEE);MyI2C_ReceiveAck();MyI2C_SendByte(0xF4);MyI2C_ReceiveAck();MyI2C_SendByte(0x34);MyI2C_ReceiveAck();MyI2C_Stop();Delay_ms(5);// temp = BMP180_int16_t_Read(0xF6); //°´ÕÕÊý¾ÝÊÖ²áдµÄ²âÊÔ²»ÄÜÓ㬸´ÖÆÍøÂçµÄ´úÂë¿ÉÒÔʹÓÃ
//
// temp_P = ((((int32_t)temp) << 8) | ((int32_t)BMP180_Read(0xF8))) >> (8 - oss);
// return temp_P;temp_P = (int32_t)BMP180_int16_t_Read(0xF6);temp_P &= 0x0000FFFF;return temp_P;
}/**
* @brief ÓûñÈ¡µÄ²ÎÊý¶ÔζȺʹóÆøѹ½øÐÐÐÞÕý£¬²¢¼ÆË㺣°Î
* @param ÎÞ
* @retval Êý¾Ý´æ·ÅÔڽṹÌåÖÐ
**/
void BMP180_Result(void)
{Calibration_BMP180.UT = BMP180_Read_UT();Calibration_BMP180.UP = BMP180_Read_UP();Calibration_BMP180.X1 = ((Calibration_BMP180.UT - Calibration_BMP180.AC6) * Calibration_BMP180.AC5) >> 15;Calibration_BMP180.X2 = (((int32_t)Calibration_BMP180.MC) << 11) / (Calibration_BMP180.X1 + Calibration_BMP180.MD);Calibration_BMP180.B5 = Calibration_BMP180.X1 + Calibration_BMP180.X2;Calibration_BMP180.Temperature = (Calibration_BMP180.B5 + 8) >> 4;Calibration_BMP180.B6 = Calibration_BMP180.B5 - 4000;Calibration_BMP180.X1 = (((int32_t)Calibration_BMP180.B2) * (Calibration_BMP180.B6 * Calibration_BMP180.B6 >> 12)) >> 11;Calibration_BMP180.X2 = (((int32_t)Calibration_BMP180.AC2) * Calibration_BMP180.B6) >>11;Calibration_BMP180.X3 = Calibration_BMP180.X1 + Calibration_BMP180.X2;Calibration_BMP180.B3 = (((((int32_t)Calibration_BMP180.AC1) * 4 + Calibration_BMP180.X3) << oss) + 2) / 4;Calibration_BMP180.X1 = ((int32_t)Calibration_BMP180.AC3) * Calibration_BMP180.B6 >> 13;Calibration_BMP180.X2 = (((int32_t)Calibration_BMP180.B1) * (Calibration_BMP180.B6 * Calibration_BMP180.B6 >> 12)) >> 16;Calibration_BMP180.X3 = ((Calibration_BMP180.X1 + Calibration_BMP180.X2) + 2) >> 2;Calibration_BMP180.B4 = ((int32_t)Calibration_BMP180.AC4) * (uint32_t)(Calibration_BMP180.X3 + 32768) >>15;Calibration_BMP180.B7 = ((uint32_t)Calibration_BMP180.UP - Calibration_BMP180.B3) * (50000 >> oss);if(Calibration_BMP180.B7 < 0x80000000)Calibration_BMP180.P = (Calibration_BMP180.B7 * 2) / Calibration_BMP180.B4;elseCalibration_BMP180.P = (Calibration_BMP180.B7 / Calibration_BMP180.B4) * 2;Calibration_BMP180.X1 = (Calibration_BMP180.P >> 8) * (Calibration_BMP180.P >> 8);Calibration_BMP180.X1 = (((int32_t)Calibration_BMP180.X1) * 3038) >> 16;Calibration_BMP180.X2 = (-7375 * Calibration_BMP180.P) >> 16;Calibration_BMP180.P = Calibration_BMP180.P + ((Calibration_BMP180.X1 + Calibration_BMP180.X2 + 3791) >> 4) - 390; // -390ÊǸù¾ÝÊÖ»úµÄѹǿÊý¾Ý×öµÄÐÞÕýCalibration_BMP180.Altitude = 44330 * (1-pow(((Calibration_BMP180.P) / 101325.0),(1.0/5.255)));
}
使用软件IIC协议,结算过程比较复杂我这里放个公式:
h文件:
#ifndef _BMP180_H_
#define _BMP180_H_#include "stm32f10x.h" // Device header#ifndef __BMP180_H__
#define __BMP180_H__#include "stm32f10x.h"
#include "MyI2C.h"#define oss 0typedef struct
{int16_t AC1;int16_t AC2;int16_t AC3;uint16_t AC4;uint16_t AC5;uint16_t AC6;int16_t B1;int16_t B2;int16_t MB;int16_t MC;int16_t MD;int32_t UT;int32_t UP;int32_t X1;int32_t X2;int32_t X3;int32_t B5;int32_t Temperature; //ÎÂ¶È ÕûÊý²¿·Ö=Temperature/10, СÊý²¿·Ö=Temperature%10int32_t B6;int32_t B3;uint32_t B4;int32_t B7;int32_t P;float Altitude;
}Initialize_BMP180;
extern Initialize_BMP180 Calibration_BMP180;//
// Èí¼þIIC
//void BMP180_Init(void);
u8 BMP180_Read(u8 Add);
void BMP180_Result(void);#endif#endif
光照传感器,获取光照强度:
c文件:
#include "stm32f10x.h" // Device header#include "HT1750.h"
#define BH1750_Addr 0x46void Hardware_IIC_WaitEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT)
{uint32_t Timeout;Timeout = 10000;while (I2C_CheckEvent(I2Cx, I2C_EVENT) != SUCCESS){Timeout --;if (Timeout == 0){break;}}
}void Hardware_IIC_WriteReg(uint8_t Data)
{I2C_GenerateSTART(I2C1, ENABLE);Hardware_IIC_WaitEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT);I2C_Send7bitAddress(I2C1, BH1750_Addr, I2C_Direction_Transmitter);Hardware_IIC_WaitEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);// I2C_SendData(I2C1, RegAddress);
// Hardware_IIC_WaitEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING);I2C_SendData(I2C1, Data);Hardware_IIC_WaitEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED);I2C_GenerateSTOP(I2C1, ENABLE);
}uint16_t Hardware_IIC_ReadReg(void)
{uint16_t Data;I2C_GenerateSTART(I2C1, ENABLE);Hardware_IIC_WaitEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT);I2C_Send7bitAddress(I2C1, BH1750_Addr, I2C_Direction_Receiver);Hardware_IIC_WaitEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED);Hardware_IIC_WaitEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED);Data = I2C_ReceiveData(I2C1);I2C_AcknowledgeConfig(I2C1, DISABLE);I2C_GenerateSTOP(I2C1, ENABLE);Hardware_IIC_WaitEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED);Data = (Data<<8)+I2C_ReceiveData(I2C1);I2C_AcknowledgeConfig(I2C1, ENABLE);return Data;
}void Hardware_IIC_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);I2C_InitTypeDef I2C_InitStructure;I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;I2C_InitStructure.I2C_ClockSpeed = 50000;I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;I2C_InitStructure.I2C_OwnAddress1 = 0x00;I2C_Init(I2C1, &I2C_InitStructure);I2C_Cmd(I2C1, ENABLE);}//BH1750s上电
void BH1750_Power_ON(void)
{Hardware_IIC_WriteReg(POWER_ON);
}//BH1750s断电
void BH1750_Power_OFF(void)
{Hardware_IIC_WriteReg(POWER_OFF);
}//BH1750复位 仅在上电时有效
void BH1750_RESET(void)
{Hardware_IIC_WriteReg(MODULE_RESET);
}//BH1750初始化
void BH1750_Init(void)
{Hardware_IIC_Init();BH1750_Power_ON(); //BH1750s上电//BH1750_RESET(); //BH1750复位Hardware_IIC_WriteReg(Measure_Mode);//SysTick_Delay_ms(120);
}//获取光照强度
float LIght_Intensity(void)
{return (float)(Hardware_IIC_ReadReg()/1.1f*Resolurtion);
}
硬件IIC协议
h文件:
#ifndef __MPU6050_H
#define __MPU6050_H#include "stm32f10x.h" // Device headervoid Hardware_IIC_WriteReg(uint8_t Data);
uint16_t Hardware_IIC_ReadReg(void);void Hardware_IIC_Init(void);//BH1750的地址#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#endifvoid BH1750_Init(void); //未包含IIC初始化float LIght_Intensity(void); //读取光照强度的值uint8_t BH1750_Byte_Write(uint8_t data);uint16_t BH1750_Read_Measure(void);void BH1750_Power_ON(void);void BH1750_Power_OFF(void);void BH1750_RESET(void);#endif
OLED屏幕代码:
c文件:
#include "stm32f10x.h"
#include "OLED_Font.h"/*引脚配置*/
#define OLED_W_SCL(x) GPIO_WriteBit(GPIOB, GPIO_Pin_8, (BitAction)(x))
#define OLED_W_SDA(x) GPIO_WriteBit(GPIOB, GPIO_Pin_9, (BitAction)(x))/*引脚初始化*/
void OLED_I2C_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_Init(GPIOB, &GPIO_InitStructure);OLED_W_SCL(1);OLED_W_SDA(1);
}/*** @brief I2C开始* @param 无* @retval 无*/
void OLED_I2C_Start(void)
{OLED_W_SDA(1);OLED_W_SCL(1);OLED_W_SDA(0);OLED_W_SCL(0);
}/*** @brief I2C停止* @param 无* @retval 无*/
void OLED_I2C_Stop(void)
{OLED_W_SDA(0);OLED_W_SCL(1);OLED_W_SDA(1);
}/*** @brief I2C发送一个字节* @param Byte 要发送的一个字节* @retval 无*/
void OLED_I2C_SendByte(uint8_t Byte)
{uint8_t i;for (i = 0; i < 8; i++){OLED_W_SDA(Byte & (0x80 >> i));OLED_W_SCL(1);OLED_W_SCL(0);}OLED_W_SCL(1); //额外的一个时钟,不处理应答信号OLED_W_SCL(0);
}/*** @brief OLED写命令* @param Command 要写入的命令* @retval 无*/
void OLED_WriteCommand(uint8_t Command)
{OLED_I2C_Start();OLED_I2C_SendByte(0x78); //从机地址OLED_I2C_SendByte(0x00); //写命令OLED_I2C_SendByte(Command); OLED_I2C_Stop();
}/*** @brief OLED写数据* @param Data 要写入的数据* @retval 无*/
void OLED_WriteData(uint8_t Data)
{OLED_I2C_Start();OLED_I2C_SendByte(0x78); //从机地址OLED_I2C_SendByte(0x40); //写数据OLED_I2C_SendByte(Data);OLED_I2C_Stop();
}/*** @brief OLED设置光标位置* @param Y 以左上角为原点,向下方向的坐标,范围:0~7* @param X 以左上角为原点,向右方向的坐标,范围:0~127* @retval 无*/
void OLED_SetCursor(uint8_t Y, uint8_t X)
{OLED_WriteCommand(0xB0 | Y); //设置Y位置OLED_WriteCommand(0x10 | ((X & 0xF0) >> 4)); //设置X位置高4位OLED_WriteCommand(0x00 | (X & 0x0F)); //设置X位置低4位
}/*** @brief OLED清屏* @param 无* @retval 无*/
void OLED_Clear(void)
{ uint8_t i, j;for (j = 0; j < 8; j++){OLED_SetCursor(j, 0);for(i = 0; i < 128; i++){OLED_WriteData(0x00);}}
}/*** @brief OLED显示一个字符* @param Line 行位置,范围:1~4* @param Column 列位置,范围:1~16* @param Char 要显示的一个字符,范围:ASCII可见字符* @retval 无*/
void OLED_ShowChar(uint8_t Line, uint8_t Column, char Char)
{ uint8_t i;OLED_SetCursor((Line - 1) * 2, (Column - 1) * 8); //设置光标位置在上半部分for (i = 0; i < 8; i++){OLED_WriteData(OLED_F8x16[Char - ' '][i]); //显示上半部分内容}OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 8); //设置光标位置在下半部分for (i = 0; i < 8; i++){OLED_WriteData(OLED_F8x16[Char - ' '][i + 8]); //显示下半部分内容}
}/*** @brief OLED显示字符串* @param Line 起始行位置,范围:1~4* @param Column 起始列位置,范围:1~16* @param String 要显示的字符串,范围:ASCII可见字符* @retval 无*/
void OLED_ShowString(uint8_t Line, uint8_t Column, char *String)
{uint8_t i;for (i = 0; String[i] != '\0'; i++){OLED_ShowChar(Line, Column + i, String[i]);}
}/*** @brief OLED次方函数* @retval 返回值等于X的Y次方*/
uint32_t OLED_Pow(uint32_t X, uint32_t Y)
{uint32_t Result = 1;while (Y--){Result *= X;}return Result;
}/*** @brief OLED显示数字(十进制,正数)* @param Line 起始行位置,范围:1~4* @param Column 起始列位置,范围:1~16* @param Number 要显示的数字,范围:0~4294967295* @param Length 要显示数字的长度,范围:1~10* @retval 无*/
void OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
{uint8_t i;for (i = 0; i < Length; i++) {OLED_ShowChar(Line, Column + i, Number / OLED_Pow(10, Length - i - 1) % 10 + '0');}
}/*** @brief OLED显示数字(十进制,带符号数)* @param Line 起始行位置,范围:1~4* @param Column 起始列位置,范围:1~16* @param Number 要显示的数字,范围:-2147483648~2147483647* @param Length 要显示数字的长度,范围:1~10* @retval 无*/
void OLED_ShowSignedNum(uint8_t Line, uint8_t Column, int32_t Number, uint8_t Length)
{uint8_t i;uint32_t Number1;if (Number >= 0){OLED_ShowChar(Line, Column, '+');Number1 = Number;}else{OLED_ShowChar(Line, Column, '-');Number1 = -Number;}for (i = 0; i < Length; i++) {OLED_ShowChar(Line, Column + i + 1, Number1 / OLED_Pow(10, Length - i - 1) % 10 + '0');}
}/*** @brief OLED显示数字(十六进制,正数)* @param Line 起始行位置,范围:1~4* @param Column 起始列位置,范围:1~16* @param Number 要显示的数字,范围:0~0xFFFFFFFF* @param Length 要显示数字的长度,范围:1~8* @retval 无*/
void OLED_ShowHexNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
{uint8_t i, SingleNumber;for (i = 0; i < Length; i++) {SingleNumber = Number / OLED_Pow(16, Length - i - 1) % 16;if (SingleNumber < 10){OLED_ShowChar(Line, Column + i, SingleNumber + '0');}else{OLED_ShowChar(Line, Column + i, SingleNumber - 10 + 'A');}}
}/*** @brief OLED显示数字(二进制,正数)* @param Line 起始行位置,范围:1~4* @param Column 起始列位置,范围:1~16* @param Number 要显示的数字,范围:0~1111 1111 1111 1111* @param Length 要显示数字的长度,范围:1~16* @retval 无*/
void OLED_ShowBinNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
{uint8_t i;for (i = 0; i < Length; i++) {OLED_ShowChar(Line, Column + i, Number / OLED_Pow(2, Length - i - 1) % 2 + '0');}
}/*** @brief OLED初始化* @param 无* @retval 无*/
void OLED_Init(void)
{uint32_t i, j;for (i = 0; i < 1000; i++) //上电延时{for (j = 0; j < 1000; j++);}OLED_I2C_Init(); //端口初始化OLED_WriteCommand(0xAE); //关闭显示OLED_WriteCommand(0xD5); //设置显示时钟分频比/振荡器频率OLED_WriteCommand(0x80);OLED_WriteCommand(0xA8); //设置多路复用率OLED_WriteCommand(0x3F);OLED_WriteCommand(0xD3); //设置显示偏移OLED_WriteCommand(0x00);OLED_WriteCommand(0x40); //设置显示开始行OLED_WriteCommand(0xA1); //设置左右方向,0xA1正常 0xA0左右反置OLED_WriteCommand(0xC8); //设置上下方向,0xC8正常 0xC0上下反置OLED_WriteCommand(0xDA); //设置COM引脚硬件配置OLED_WriteCommand(0x12);OLED_WriteCommand(0x81); //设置对比度控制OLED_WriteCommand(0xCF);OLED_WriteCommand(0xD9); //设置预充电周期OLED_WriteCommand(0xF1);OLED_WriteCommand(0xDB); //设置VCOMH取消选择级别OLED_WriteCommand(0x30);OLED_WriteCommand(0xA4); //设置整个显示打开/关闭OLED_WriteCommand(0xA6); //设置正常/倒转显示OLED_WriteCommand(0x8D); //设置充电泵OLED_WriteCommand(0x14);OLED_WriteCommand(0xAF); //开启显示OLED_Clear(); //OLED清屏
}
h文件:
#ifndef __OLED_H
#define __OLED_Hvoid OLED_Init(void);
void OLED_Clear(void);
void OLED_ShowChar(uint8_t Line, uint8_t Column, char Char);
void OLED_ShowString(uint8_t Line, uint8_t Column, char *String);
void OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length);
void OLED_ShowSignedNum(uint8_t Line, uint8_t Column, int32_t Number, uint8_t Length);
void OLED_ShowHexNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length);
void OLED_ShowBinNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length);#endif//字库
#ifndef __OLED_FONT_H
#define __OLED_FONT_H/*OLED字模库,宽8像素,高16像素*/
const uint8_t OLED_F8x16[][16]=
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 00x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! 10x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" 20x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# 30x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ 40xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% 50x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& 60x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//' 70x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( 80x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) 90x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* 100x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ 110x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, 120x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- 130x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. 140x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// 150x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 160x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 170x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 180x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 190x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 200x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 210x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 220x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 230x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 240x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 250x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: 260x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,//; 270x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< 280x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= 290x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> 300x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? 310xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ 320x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A 330x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B 340xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C 350x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D 360x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E 370x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F 380xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G 390x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H 400x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I 410x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J 420x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K 430x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L 440x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M 450x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N 460xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O 470x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P 480xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q 490x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R 500x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S 510x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T 520x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U 530x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V 540xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,//W 550x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,//X 560x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//Y 570x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,//Z 580x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,//[ 590x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,//\ 600x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,//] 610x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^ 620x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,//_ 630x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//` 640x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a 650x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b 660x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,//c 670x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,//d 680x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,//e 690x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//f 700x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,//g 710x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//h 720x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//i 730x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,//j 740x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,//k 750x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//l 760x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,//m 770x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//n 780x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//o 790x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,//p 800x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,//q 810x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,//r 820x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,//s 830x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,//t 840x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,//u 850x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,//v 860x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,//w 870x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,//x 880x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,//y 890x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,//z 900x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,//{ 910x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,//| 920x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//} 930x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//~ 94
};#endif
DHT11代码:
c文件:
#include "stm32f10x.h" // Device header
#include "DHT11.h"
#include "Delay.h"#define DHT11_IO GPIO_Pin_12
#define DHT11_PORT GPIOBvoid DHT11_IO_OUT (void){ //温湿度模块输出函数GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = DHT11_IO; //选择端口号(0~15或all) GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO接口速度(2/10/50MHz) GPIO_Init(DHT11_PORT, &GPIO_InitStructure);
}void DHT11_IO_IN (void){ //温湿度模块输入函数GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = DHT11_IO; //选择端口号(0~15或all) GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入 GPIO_Init(DHT11_PORT, &GPIO_InitStructure);
}void DHT11_RST (void){ //DHT11端口复位,发出起始信号(IO发送)DHT11_IO_OUT(); //端口为输出GPIO_ResetBits(DHT11_PORT,DHT11_IO); //使总线为低电平Delay_ms(20); //拉低至少18ms GPIO_SetBits(DHT11_PORT,DHT11_IO); //使总线为高电平 Delay_us(30); //主机拉高20~40us
}u8 DHT11_Check(void){ //等待DHT11回应,返回1:未检测到DHT11,返回0:成功(IO接收) u8 retry=0; //定义临时变量DHT11_IO_IN(); //IO到输入状态
//GPIO端口输入时,配置为上拉输入或者浮空输入,因为外接上拉电阻,所以默认为高电平
//如果DHT11的数据线输入为高电平,且 retry 小于100,则将 retry 加1,并延时1微秒,重复这个过程直到 retry 大于等于100 或者DHT11的数据线输入变成低电平。如果 retry 大于等于100,表示检测失败,返回1;否则,将 retry 重置为0。while ((GPIO_ReadInputDataBit(DHT11_PORT,DHT11_IO) == 1) && retry<100) //DHT11会拉低40~80us{retry++;Delay_us(1);}if(retry>=100)return 1; else retry=0;
//如果DHT11的数据线输入为低电平,且 retry 小于100,则将 retry 加1,并延时1微秒,重复这个过程直到 retry 大于等于100 或者DHT11的数据线输入变成高电平。如果 retry 大于等于100,表示检测失败,返回1;否则,返回0,表示检测成功。while ((GPIO_ReadInputDataBit(DHT11_PORT,DHT11_IO) == 0) && retry<100) //DHT11拉低后会再次拉高40~80us{ retry++;Delay_us(1);}if(retry>=100)return 1; return 0;
}u8 DHT11_Init (void){ //DHT11初始化RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //开始DHT11的时钟DHT11_RST(); //DHT11端口复位,发出起始信号return DHT11_Check(); //等待DHT11回应
}//从DHT11读取一个位
//返回值:1/0
u8 DHT11_Read_Bit(void)
{u8 retry = 0;while((GPIO_ReadInputDataBit(DHT11_PORT,DHT11_IO) == 1) && retry < 100) //等待变为低电平{retry++;Delay_us(1);}retry = 0;while((GPIO_ReadInputDataBit(DHT11_PORT,DHT11_IO) == 0) && retry < 100) //等待变高电平{retry++;Delay_us(1);}Delay_us(40);//等待40usif(GPIO_ReadInputDataBit(DHT11_PORT,DHT11_IO) == 1) //用于判断高低电平,即数据1或0return 1;elsereturn 0;
}//从DHT11读取一个字节
//返回值:读到的数据
u8 DHT11_Read_Byte(void)
{u8 i, dat;dat = 0;for (i = 0; i < 8; i++){dat <<= 1; //左移运算符,dat左移1位dat |= DHT11_Read_Bit(); //"|"表示按位或等于}return dat;
}//从DHT11读取一次数据
//temp:温度值(范围:0~50°)
//humi:湿度值(范围:20%~90%)
//返回值:0,正常;1,读取失败
u8 DHT11_Read_Data(u8 *temp, u8 *humi)
{u8 buf[5];u8 i;DHT11_RST(); //DHT11端口复位,发出起始信号if(DHT11_Check() == 0) //等待DHT11回应,0为成功回应{for(i = 0; i < 5; i++) //读取40位数据{buf[i] = DHT11_Read_Byte(); //读出数据}if((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4]) //数据校验{*humi = buf[0]; //将湿度值放入指针humi*temp = buf[2]; //将温度值放入指针temp}}else return 1;return 0;
}
h文件:
#ifndef __DHT11_H
#define __DHT11_H#define uint8_t u8
#include "stm32f10x.h" // Device headervoid DHT11_IO_OUT (void);
u8 DHT11_Read_Data(u8 *temp, u8 *humi);
u8 DHT11_Init (void);#endif
ADS1115代码:
c文件:
myiic协议c文件:
#include "stm32f10x.h" // Device header
#include "Delay.h"void MyI2C_W_SCL(uint8_t BitValue)
{GPIO_WriteBit(GPIOB, GPIO_Pin_0, (BitAction)BitValue);Delay_us(10);
}void MyI2C_W_SDA(uint8_t BitValue)
{GPIO_WriteBit(GPIOB, GPIO_Pin_1, (BitAction)BitValue);Delay_us(10);
}uint8_t MyI2C_R_SDA(void)
{uint8_t BitValue;BitValue = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1);Delay_us(10);return BitValue;
}void MyI2C_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_SetBits(GPIOB, GPIO_Pin_0 | GPIO_Pin_1);
}void MyI2C_Start(void)
{MyI2C_W_SDA(1);MyI2C_W_SCL(1);MyI2C_W_SDA(0);MyI2C_W_SCL(0);
}void MyI2C_Stop(void)
{MyI2C_W_SDA(0);MyI2C_W_SCL(1);MyI2C_W_SDA(1);
}void MyI2C_SendByte(uint8_t Byte)
{uint8_t i;for (i = 0; i < 8; i ++){MyI2C_W_SDA(Byte & (0x80 >> i));MyI2C_W_SCL(1);MyI2C_W_SCL(0);}
}uint8_t MyI2C_ReceiveByte(void)
{uint8_t i, Byte = 0x00;MyI2C_W_SDA(1);for (i = 0; i < 8; i ++){MyI2C_W_SCL(1);if (MyI2C_R_SDA() == 1){Byte |= (0x80 >> i);}MyI2C_W_SCL(0);}return Byte;
}void MyI2C_SendAck(uint8_t AckBit)
{MyI2C_W_SDA(AckBit);MyI2C_W_SCL(1);MyI2C_W_SCL(0);
}uint8_t MyI2C_ReceiveAck(void)
{uint8_t AckBit;MyI2C_W_SDA(1);MyI2C_W_SCL(1);AckBit = MyI2C_R_SDA();MyI2C_W_SCL(0);return AckBit;
}
myiic协议h文件:
#ifndef __MYI2C_H
#define __MYI2C_Hvoid MyI2C_Init(void);
void MyI2C_Start(void);
void MyI2C_Stop(void);
void MyI2C_SendByte(uint8_t Byte);
uint8_t MyI2C_ReceiveByte(void);
void MyI2C_SendAck(uint8_t AckBit);
uint8_t MyI2C_ReceiveAck(void);#endif
adc1115代码c文件:
#include "stm32f10x.h" // Device header
#include "ADC1115.h"
#include "Delay.h"
#include "I2C.h"void ADS1115_Write(unsigned char Reg , unsigned char reg_MSB , unsigned char reg_LSB)
{ uint8_t i,j,k,l;IIC_Start();IIC_SendByte(0x90+0);//0x90地址+0写位i=IIC_ReceiveAck();IIC_SendByte(Reg);j=IIC_ReceiveAck();IIC_SendByte(reg_MSB);k=IIC_ReceiveAck();IIC_SendByte(reg_LSB);l=IIC_ReceiveAck();IIC_Stop();
}
unsigned int ADS1115_ReadAD()
{unsigned int Data;IIC_Start();IIC_SendByte(0x90+0);//0x90地址+0写位IIC_ReceiveAck();IIC_SendByte(REG_Conversion);IIC_ReceiveAck();IIC_Stop();IIC_Start();IIC_SendByte(0x90+1);//0x90地址+1读位IIC_ReceiveAck();Data = IIC_ReceiveByte();Data =(Data<<8)&0xff00;//前8位IIC_SendByte(0);Data+=IIC_ReceiveByte();//后8位IIC_SendByte(1);IIC_Stop();return Data;}void ADS115_config()
{ADS1115_Write(REG_config, config_MSB ,config_LSB);
}void ADS115_config1()
{ADS1115_Write(REG_config, config_MSB1 ,config_LSB);}void ADS115_config2()
{ADS1115_Write(REG_config, config_MSB2 ,config_LSB);
}
主要是为了解决stm32不能采集5v电压
adc1115代码h文件:
//ads1115.h
#ifndef ADS1115_H
#define ADS1115_H
/*******************************************************************************
ADDR--GND
SLAVE ADDRESS 0X90
*******************************************************************************/ /*****************Pointer Register*************/
#define REG_Conversion 0x00
#define REG_config 0x01
#define REG_L_thresh 0x02
#define REG_H_thresh 0x03/*****************Conversion Register**********/
//???16???/*****************Config Register**********/
#define OS 1 //Operational status or single-shot conversion start
#define MUX 0x04 //[2:0]Input multiplexer configuration
#define MUX2 0x06 //[2:0]Input multiplexer configuration
#define MUX1 0x05 //[2:0]Input multiplexer configuration
#define PGA 0x01 //Programmable gain amplifier configuration
#define PGA1 0x02 //Programmable gain amplifier configuration
#define PGA2 0x00 //Programmable gain amplifier configuration
#define MODE 0x00 //Device operating mode#define DR 0x07//Data rate#define COMP_MODE 0 // Comparator mode
#define COMP_POL 0 //Comparator polarity
#define COMP_LAT 0 //Latching comparator
#define COMP_QUE 0x3 //Comparator queue and disable#define config_MSB (OS << 7)|(MUX << 4)|(PGA << 1)|(MODE)//0xC2
#define config_MSB1 (OS << 7)|(MUX1 << 4)|(PGA << 1)|(MODE)
#define config_MSB2 (OS << 7)|(MUX2 << 4)|(PGA2 << 1)|(MODE)
#define config_LSB (DR << 5)|(COMP_MODE << 4)|(COMP_POL << 3)|(COMP_LAT << 2)|(COMP_QUE)//0x83
/*****************Lo_thresh Register**********/
#define Lo_thresh 0x8000 // Low threshold value
#define Hi_thresh 0x7FFF // High threshold valuevoid ADS1115_Write(unsigned char Reg , unsigned char reg_MSB , unsigned char reg_LSB);
unsigned int ADS1115_ReadAD(void);
void ADS115_config(void);
void ADS115_config1(void);
void ADS115_config2(void);
#endif
PM2.5浓度读取:(从ADS1115获取电压)
c文件:
#include "stm32f10x.h" // Device header
#include "ADC1115.h"
#include "Delay.h"
extern uint16_t AD_Value[2];float PM2_5_Value(void)
{float v;unsigned int Data;ADS115_config();Data=ADS1115_ReadAD();if(Data>0x8000)v=((float)(0xffff-Data)/32768.0)*4.096;elsev=((float)Data/32768.0)*4.096;return v;
}void GP2Y1014AU0F_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_SetBits(GPIOB, GPIO_Pin_5);}u16 GetGP2YSingleValue(void)
{uint8_t i;int samplingTime = 280;//等待LED开启的时间是280μsint deltaTime = 40;//整个脉冲持续时间为320μs。因此,我们还需再等待40μsfloat dustVal = 0;float Voltage;
// uint16_t Value;GPIO_ResetBits(GPIOB, GPIO_Pin_5);//置1 开启内部LED ????????Delay_us(samplingTime); // 开启LED后的280us的等待时间
// Voltage=AD_Value[1]*(3.3/4096);for(i=0;i<3;i++){Voltage=PM2_5_Value();}Delay_us(40);GPIO_SetBits(GPIOB, GPIO_Pin_5);//置0Delay_us(9680);//需要脉宽比0.32ms/10ms的PWM信号驱动传感器中的LEDdustVal = (Voltage + 1) * 1000 / 10;//*1000作用是将单位转换为ug/m3
// if(ADCVal > 36.455)
// dustVal = ((float)(ADCVal / 1024.0) - 0.0356) * 120000 * 0.035;
// dustVal = 0.17 * ADCVal - 0.1;
// dustVal = ADCVal;
// return dustVal; // mg/m3return dustVal;
}
h文件:
#ifndef __PM2_5_H
#define __PM2_5_H
#include "stm32f10x.h" // Device header
void GP2Y1014AU0F_Init(void);
u16 GetGP2YSingleValue(void);#endif
MQ135浓度获取:(从ADS1115获取电压)
c文件:
#include "stm32f10x.h" // Device header
#include "ADC1115.h"
#include "Delay.h"
#include <math.h>float MQ135_Value(void)
{float v;unsigned int Data;ADS115_config1();Data=ADS1115_ReadAD();if(Data>0x8000)v=((float)(0xffff-Data)/32768.0)*4.096;elsev=((float)Data/32768.0)*4.096;return v;
}float MQ135Value(void)
{float volt,ppm;uint8_t i;for(i=0;i<3;i++){volt=MQ135_Value();}ppm = pow((3.4880*10*volt)/(5-volt),(1.0/0.3203));return ppm;}
h文件:
#ifndef __MQ135_H
#define __MQ135_Hfloat MQ135Value(void);#endif
公式:
电容按键,外部中断:
c文件:
#include "stm32f10x.h" // Device headeruint8_t Keynum;void KeyNum_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource3);GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource4);GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource15);EXTI_InitTypeDef EXTI_InitStructure;EXTI_InitStructure.EXTI_Line = EXTI_Line3|EXTI_Line4|EXTI_Line15;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;EXTI_Init(&EXTI_InitStructure);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_Init(&NVIC_InitStructure);NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;NVIC_Init(&NVIC_InitStructure);NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;NVIC_Init(&NVIC_InitStructure);GPIO_SetBits(GPIOA,GPIO_Pin_15);GPIO_SetBits(GPIOB,GPIO_Pin_3);GPIO_SetBits(GPIOB,GPIO_Pin_4);
}void EXTI15_10_IRQHandler(void)
{if (EXTI_GetITStatus(EXTI_Line15) == SET){/*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_15) == 0){Keynum=1;}EXTI_ClearITPendingBit(EXTI_Line15);}
}
void EXTI3_IRQHandler(void)
{if (EXTI_GetITStatus(EXTI_Line3) == SET){/*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_3) == 0){Keynum=2;}EXTI_ClearITPendingBit(EXTI_Line3);}
}
void EXTI4_IRQHandler(void)
{if (EXTI_GetITStatus(EXTI_Line4) == SET){/*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_4) == 0){Keynum=3;}EXTI_ClearITPendingBit(EXTI_Line4);}
}
h文件:
#ifndef __KeyNum_H
#define __KeyNum_Hvoid KeyNum_Init(void);#endif
声音传感器获取DB(本人随便写的,没有依据)(从ADS1115获取电压)
c文件:
#include "stm32f10x.h" // Device header
#include "ADC1115.h"
#include "Delay.h"extern uint8_t DB;
float dB_Value(void)
{float v;unsigned int Data;ADS115_config2();Data=ADS1115_ReadAD();if(Data>0x8000)v=((float)(0xffff-Data)/32768.0)*5;elsev=((float)Data/32768.0)*5;return v;
}float dBValue(void)
{float volt;float dB;uint8_t i;for(i=0;i<3;i++){volt=dB_Value();}dB=volt;if(dB<2){DB=0;}else if(dB<=3&&dB>=2){DB=1;}else if(dB<=5&&dB>3){DB=2;}return dB;}
从DAS1115获取电压
h文件:
#ifndef __DB_H
#define __DB_Hint dBValue(void);#endif
STM32定时器初始化:
#include "stm32f10x.h" // Device header
#include "timer.h"
#include "gizwits_product.h"void Timer_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);TIM_InternalClockConfig(TIM2);TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInitStructure.TIM_Period = 2000 - 1;TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1; TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);TIM_ClearFlag(TIM2, TIM_FLAG_Update);TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_Init(&NVIC_InitStructure);TIM_Cmd(TIM2, ENABLE);
}//ͨӃ¶¨ʱƷ3¶ϳõʼ»¯
//բÀ֓ѡԱΪAPB1µIJ±¶£¬¶øAPB1Ϊ36M
//arr£ºה¶¯֘װֵ¡£
//psc£ºʱ֓Ԥ·ֆµʽ
//բÀӃµĊǶ¨ʱƷ3!
void TIM3_Int_Init(u16 arr,u16 psc)
{TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;NVIC_InitTypeDef NVIC_InitStruct;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//³õʼ»¯TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;// 72MHzTIM_TimeBaseInitStruct.TIM_Period=arr;TIM_TimeBaseInitStruct.TIM_Prescaler=psc;TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct);TIM_ClearFlag(TIM3, TIM_IT_Update);TIM_ITConfig(TIM3, TIM_IT_Update,ENABLE);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitStruct.NVIC_IRQChannel=TIM3_IRQn;NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0;NVIC_InitStruct.NVIC_IRQChannelSubPriority=0;NVIC_Init(&NVIC_InitStruct);TIM_Cmd(TIM3, ENABLE); //ʹĜTIMx
}
//¶¨ʱƷ3¶Ϸþα³̐oid TIM3_IRQHandler(void) //TIM3¶ύ
{if(TIM_GetITStatus(TIM3, TIM_IT_Update)){TIM_ClearITPendingBit(TIM3, TIM_IT_Update);gizTimerMs();}
// if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //¼첩TIM3¸üЂ¶Ϸ¢ɺӫ·/ {
// TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //ǥ³ýTIMx¸üЂ¶ϱꖾ
// gizTimerMs();
// }
}
sys文件
//
.c
#include "sys.h"void WFI_SET(void)
{__ASM volatile("wfi");
}
//¹رՋùӐ¶ύ
void INTX_DISABLE(void)
{ __ASM volatile("cpsid i");
}
//¿ªƴ˹Ӑ¶ύ
void INTX_ENABLE(void)
{__ASM volatile("cpsie i");
}
//ɨփջ¶¥µؖ·
//addr:ջ¶¥µؖ·
__asm void MSR_MSP(u32 addr)
{MSR MSP, r0 //set Main Stack valueBX r14
}//
.h
#ifndef __SYS_H
#define __SYS_H
#include "stm32f10x.h"//λ´ø²ٗ÷,ʵϖ51ÀˆµćPIO¿ؖƹ¦Ĝ
//¾ߌ劵ϖ˼ϫ,²ο¼<<CM3Ȩ;ָď>>µڎ啂(87ҳ~92ҳ).
//IO¿ڲٗ÷º궨ҥ
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
//IO¿ڵؖ·ӳɤ
#define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C
#define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C
#define GPIOC_ODR_Addr (GPIOC_BASE+12) //0x4001100C
#define GPIOD_ODR_Addr (GPIOD_BASE+12) //0x4001140C
#define GPIOE_ODR_Addr (GPIOE_BASE+12) //0x4001180C
#define GPIOF_ODR_Addr (GPIOF_BASE+12) //0x40011A0C
#define GPIOG_ODR_Addr (GPIOG_BASE+12) //0x40011E0C #define GPIOA_IDR_Addr (GPIOA_BASE+8) //0x40010808
#define GPIOB_IDR_Addr (GPIOB_BASE+8) //0x40010C08
#define GPIOC_IDR_Addr (GPIOC_BASE+8) //0x40011008
#define GPIOD_IDR_Addr (GPIOD_BASE+8) //0x40011408
#define GPIOE_IDR_Addr (GPIOE_BASE+8) //0x40011808
#define GPIOF_IDR_Addr (GPIOF_BASE+8) //0x40011A08
#define GPIOG_IDR_Addr (GPIOG_BASE+8) //0x40011E08 //IO¿ڲٗ÷,ֻ¶Ե¥һµĉO¿ڡ
//ȷ±£nµĖµСӚ16!
#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //ʤ³ö
#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //ʤȫ #define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //ʤ³ö
#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //ʤȫ #define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //ʤ³ö
#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //ʤȫ #define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //ʤ³ö
#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //ʤȫ #define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //ʤ³ö
#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //ʤȫ#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //ʤ³ö
#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //ʤȫ#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //ʤ³ö
#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //ʤȫ//ҔςΪ»㱠º¯ʽ
void WFI_SET(void); //ִАWFIָÁvoid INTX_DISABLE(void);//¹رՋùӐ¶ύ
void INTX_ENABLE(void); //¿ªƴ˹Ӑ¶ύ
void MSR_MSP(u32 addr); //ɨփ¶ѕ»µؖ·#endif
不分享了,太多了
下一篇分享esp8266+机智云的代码
这篇关于国赛一等奖-“垃圾桶项目”,环境监测系统开源--stm32+esp8266+机智云的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!