提示:
本文适用有一定嵌入式基础的人,学习与借鉴
本人大三第一次写csdn,之前在csdn上解决了不少我学习的问题,于是我也尝试的分享一下我的代码以及做过的项目!!!
声明:
本文适用有一定嵌入式基础的人,学习与借鉴
本人大三第一次写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 Collection
currentDataPoint.valueUV = UV;//Add Sensor Data Collection
currentDataPoint.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 Collection
currentDataPoint.valueTVOC = TVOCData;//Add Sensor Data Collection
currentDataPoint.valueCO2 = CO2Data;//Add Sensor Data Collection
currentDataPoint.valueLUX = Lux;//Add Sensor Data Collection
currentDataPoint.valueHarmful = MQ135;
currentDataPoint.valuePM_2_5=PM2_5;
currentDataPoint.valuedB=DB;
currentDataPoint.valueyudi = !yudi;//Add Sensor Data Collection
currentDataPoint.valuerentihongwai = rentihongwai;//Add Sensor Data Collection
currentDataPoint.valuezhendong = zhendong;//Add Sensor Data Collection
currentDataPoint.valuehuoyan =!huoyan ;//Add Sensor Data Collection
currentDataPoint.valueqingxie =!qingxie ;//Add Sensor Data Collection
currentDataPoint.valueKpa = Calibration_BMP180.P/1000.0;//Add Sensor Data Collection
currentDataPoint.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; //MQ2
Environmental_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(); //复位esp8266
Gizwits_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(); //初始化BMP180
IIC_Init(); //ADS1115 IIC通信
Beep_Init(); //beep
BH1750_Init(); //光照传感器BH1750初始化
DHT11_Init(); //温湿度传感器初始化
GP2Y1014AU0F_Init(); //PM2.5
Serial_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; //mv
Serial_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");
}
else
Serial_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 header
uint16_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_H
extern 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_H
void 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_H
float 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");
}
}
else
Serial_Printf("t21.txt=\"没有\"\xFF\xFF\xFF");
if(huoyan==0)
{
Delay_ms(20);
if(huoyan==0)
{
Serial_Printf("t23.txt=\"起火\"\xFF\xFF\xFF");
BEEP_OUT();
}
}
else
Serial_Printf("t23.txt=\"没有\"\xFF\xFF\xFF");
if(zhendong==1)
{
if(zhendong==1)
{
Serial_Printf("t24.txt=\"振动\"\xFF\xFF\xFF");
}
}
else
Serial_Printf("t24.txt=\"没有\"\xFF\xFF\xFF");
if(qingxie==0)
{
Delay_ms(20);
if(qingxie==0)
{
Serial_Printf("t26.txt=\"倾斜\"\xFF\xFF\xFF");
BEEP_OUT();
}
}
else
Serial_Printf("t26.txt=\"没有\"\xFF\xFF\xFF");
if(rentihongwai==1)
{
Delay_ms(20);
if(rentihongwai==1)
{
Serial_Printf("t19.txt=\"有人\"\xFF\xFF\xFF");
}
}
else
Serial_Printf("t19.txt=\"没有\"\xFF\xFF\xFF");
}
h文件:
#ifndef __JIANCE_H
#define __JIANCE_H
void 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 low
Delay_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 high
Delay_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; //ʱÖÓÊä³ö0
return 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;
else
SGP30_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();//·¢ËÍnACK
else
SGP30_IIC_Ack(); //·¢ËÍACK
return 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(); //³õʼ»¯SGP30
Delay_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;
else
Calibration_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 0
typedef 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%10
int32_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 0x46
void 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 header
void 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
#endif
void 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_H
void 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,// 0
0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! 1
0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" 2
0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,
0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# 3
0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,
0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ 4
0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,
0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% 5
0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,
0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& 6
0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//' 7
0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,
0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( 8
0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,
0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) 9
0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,
0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* 10
0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,
0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ 11
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, 12
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- 13
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. 14
0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,
0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// 15
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,
0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 16
0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,
0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 17
0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,
0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 18
0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,
0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 19
0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,
0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 20
0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,
0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 21
0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,
0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 22
0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,
0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 23
0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,
0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 24
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,
0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 25
0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,
0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: 26
0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,
0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,//; 27
0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,
0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< 28
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= 29
0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,
0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> 30
0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,
0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? 31
0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,
0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ 32
0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,
0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A 33
0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,
0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B 34
0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,
0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C 35
0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,
0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D 36
0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,
0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E 37
0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,
0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F 38
0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,
0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G 39
0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,
0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H 40
0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,
0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I 41
0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,
0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J 42
0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,
0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K 43
0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,
0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L 44
0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,
0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M 45
0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,
0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N 46
0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,
0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O 47
0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,
0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P 48
0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,
0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q 49
0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,
0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R 50
0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,
0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S 51
0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,
0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T 52
0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,
0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U 53
0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,
0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V 54
0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,
0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,//W 55
0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,
0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,//X 56
0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,
0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//Y 57
0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,
0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,//Z 58
0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,
0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,//[ 59
0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,//\ 60
0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,
0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,//] 61
0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^ 62
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,//_ 63
0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//` 64
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,
0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a 65
0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,
0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b 66
0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,
0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,//c 67
0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,
0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,//d 68
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,
0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,//e 69
0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,
0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//f 70
0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,
0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,//g 71
0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,
0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//h 72
0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,
0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//i 73
0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,
0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,//j 74
0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,
0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,//k 75
0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,
0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//l 76
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,
0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,//m 77
0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,
0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//n 78
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,
0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//o 79
0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,
0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,//p 80
0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,
0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,//q 81
0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,
0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,//r 82
0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,
0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,//s 83
0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,
0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,//t 84
0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,
0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,//u 85
0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,
0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,//v 86
0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,
0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,//w 87
0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,
0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,//x 88
0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,
0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,//y 89
0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,
0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,//z 90
0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,
0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,//{ 91
0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,//| 92
0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,
0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//} 93
0x00,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 GPIOB
void 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);//等待40us
if(GPIO_ReadInputDataBit(DHT11_PORT,DHT11_IO) == 1) //用于判断高低电平,即数据1或0
return 1;
else
return 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 header
void 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_H
void 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 value
void 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;
else
v=((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μs
int deltaTime = 40;//整个脉冲持续时间为320μs。因此,我们还需再等待40μs
float 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);//置0
Delay_us(9680);//需要脉宽比0.32ms/10ms的PWM信号驱动传感器中的LED
dustVal = (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/m3
return 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;
else
v=((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_H
float MQ135Value(void);
#endif
公式:
电容按键,外部中断:
c文件:
#include "stm32f10x.h" // Device header
uint8_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_H
void 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;
else
v=((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_H
int 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;
// 72MHz
TIM_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 value
BX 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