代码上传

This commit is contained in:
caojinfa 2025-09-24 11:16:14 +08:00
commit 6728aa47ca
17530 changed files with 3643854 additions and 0 deletions

21
README.md Normal file
View File

@ -0,0 +1,21 @@
## 1、下载3.0LTS代码
```
repo init -u git@gitee.com:openharmony/manifest.git -b OpenHarmony-3.0-LTS --no-repo-verify
repo sync -c
repo forall -c 'git lfs pull'
```
## 2、将bossay_release_out中的代码放置与对应目录
其中:
app文件夹放到applications/sample
iot_link放到third_party目录下
vendor和device中的文件夹放置对应目录
## 3、编译
hb set
选择bossay的产品
hb build -f 编译代码

View File

@ -0,0 +1,92 @@
/*
* Copyright (c) 2022 Jinan Bosai Network Technology Co., LTD Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "DOOR.h"
#include "cmsis_os2.h"
#include "ohos_init.h"
#define TASK_STACK_SIZE 1024 * 8
#define TASK_PRIO 25
// #define FLAGS_MSK1 0x00000001U
// osEventFlagsId_t evt_id;
// static void Beep_Alarm(char *arg)
// {
// (void)arg;
// osEventFlagsSet(evt_id, FLAGS_MSK1);
// printf("Beep_Alarm\n");
// }
static void ExampleTask(void)
{
// ST02D_Init();
// Button_Left_Read_Data(Beep_Alarm);
// Button_Right_Read_Data(Beep_Alarm);
// while (1)
// {
// osEventFlagsWait(evt_id, FLAGS_MSK1, osFlagsWaitAny, osWaitForever);
// BeepStatusSet(ON);
// LedWarnStatusSet(ON);
// osDelay(300);
// BeepStatusSet(OFF);
// LedWarnStatusSet(OFF);
// }
BoardInit();
// Button_Left_Read_Data(Beep_Alarm);
// Button_Right_Read_Data(Beep_Alarm);
while (1)
{
if(Door_Read_Data() == 0)
{
BeepStatusSet(ON);
LedWarnStatusSet(ON);
LedSafeStatusSet(OFF);
}
else
{
BeepStatusSet(OFF);
LedWarnStatusSet(OFF);
LedSafeStatusSet(ON);
}
sleep(1);
}
}
static void ExampleEntry(void)
{
osThreadAttr_t attr;
attr.name = "ExampleTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = TASK_STACK_SIZE;
attr.priority = TASK_PRIO;
if (osThreadNew((osThreadFunc_t)ExampleTask, NULL, &attr) == NULL) {
printf("Failed to create ExampleTask!\n");
}
}
APP_FEATURE_INIT(ExampleEntry);

26
app/A01_DOOR/BUILD.gn Normal file
View File

@ -0,0 +1,26 @@
# Copyright (c) 2020  Jinan Bosai Network Technology Co., LTD
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_library("A01_DOOR") {
sources = [
"src/DOOR.c",
"A01_DOOR_example.c"
]
include_dirs = [
"//base/iot_hardware/peripheral/interfaces/kits",
"//device/bossay/hi3861_l0/iot_hardware_hals/include",
"//device/bossay/hi3861_l0/sdk_liteos/include",
"include"
]
}

View File

@ -0,0 +1,23 @@
#ifndef __DOOR_H__
#define __DOOR_H__
#include <stdint.h>
typedef enum
{
OFF = 0,
ON
} SwitchStatus;
void BoardInit(void);
uint8_t Button_Left_Read_Data(void);
void BeepStatusSet(SwitchStatus status);
void LedWarnStatusSet(SwitchStatus status);
void LedSafeStatusSet(SwitchStatus status);
#endif

99
app/A01_DOOR/src/DOOR.c Normal file
View File

@ -0,0 +1,99 @@
#include "DOOR.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#define OUT_GPIO 13
#define LED_SAFE_GPIO 7
#define LED_WARN_GPIO 14
#define BEEP_GPIO 8
uint8_t RxBuffer[3];
void BoardInit(void)
{
IoTGpioInit(OUT_GPIO);
IoTGpioSetFunc(OUT_GPIO, IOT_GPIO_FUNC_GPIO_13_GPIO);
IoTGpioSetDir(OUT_GPIO, IOT_GPIO_DIR_IN); // 设置GPIO_8为输出模式
IoTGpioInit(LED_SAFE_GPIO);
IoTGpioSetFunc(LED_SAFE_GPIO, IOT_GPIO_FUNC_GPIO_7_GPIO);
IoTGpioSetDir(LED_SAFE_GPIO, IOT_GPIO_DIR_OUT); // 设置为输出模式
IoTGpioInit(LED_WARN_GPIO);
IoTGpioSetFunc(LED_WARN_GPIO, IOT_GPIO_FUNC_GPIO_14_GPIO);
IoTGpioSetDir(LED_WARN_GPIO, IOT_GPIO_DIR_OUT); // 设置为输入模式
IoTGpioInit(BEEP_GPIO);
IoTGpioSetFunc(BEEP_GPIO, IOT_GPIO_FUNC_GPIO_8_GPIO);
IoTGpioSetDir(BEEP_GPIO, IOT_GPIO_DIR_OUT); // 设置为输入模式
}
/***************************************************************
* : Door_Read_Data
* :
* :
* :
***************************************************************/
uint8_t Door_Read_Data(void)
{
IotGpioValue temp = {0};
IoTGpioGetInputVal(OUT_GPIO,&temp);
return temp;
}
/***************************************************************
* : BeepStatusSet
* : Beep状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void BeepStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(BEEP_GPIO, 1); // 设置GPIO_7输出高电平点亮灯
}
if (status == OFF) {
IoTGpioSetOutputVal(BEEP_GPIO, 0); // 设置GPIO_7输出低电平关闭灯
}
}
/***************************************************************
* : LedWarnStatusSet
* : LED_Warn状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void LedWarnStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(LED_WARN_GPIO, 1); // 设置输出高电平点亮灯
}
if (status == OFF) {
IoTGpioSetOutputVal(LED_WARN_GPIO, 0); // 设置输出低电平关闭灯
}
}
/***************************************************************
* : LedSafeStatusSet
* : LED_Safe状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void LedSafeStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(LED_SAFE_GPIO, 1); // 设置输出高电平点亮灯
}
if (status == OFF) {
IoTGpioSetOutputVal(LED_SAFE_GPIO, 0); // 设置输出低电平关闭灯
}
}

83
app/A02_MQ5/A02_MQ5.c Normal file
View File

@ -0,0 +1,83 @@
/*
* Copyright (c) 2020  Jinan Bosai Network Technology Co., LTD
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <math.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "MQ5.h"
#define TASK_STACK_SIZE 1024*8
#define TASK_PRIO 25
static void ExampleTask(void)
{
int ret;
float ppm;
BoardInit();
//Sensor calibration
usleep(1000000);
MQ5PPMCalibration();
while (1) {
printf("=======================================\r\n");
printf("*************A02_MQ5_example***********\r\n");
printf("=======================================\r\n");
//get MQ5 ppm
ret = GetMQ5PPM(&ppm);
if (ret != 0) {
printf("ADC Read Fail\n");
return ;
}
printf("ppm:%.3f \n", ppm);
if (ppm > 30) {
BeepStatusSet(ON);
LedStatusSet(ON);
} else {
BeepStatusSet(OFF);
LedStatusSet(OFF);
}
usleep(1000000);
}
}
/**
* @brief Main Entry of the A02_MQ5 Example
*
*/
static void ExampleEntry(void)
{
osThreadAttr_t attr;
attr.name = "ExampleTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = TASK_STACK_SIZE;
attr.priority = TASK_PRIO;
if (osThreadNew((osThreadFunc_t)ExampleTask, NULL, &attr) == NULL) {
printf("Failed to create ExampleTask!\n");
}
}
APP_FEATURE_INIT(ExampleEntry);

25
app/A02_MQ5/BUILD.gn Normal file
View File

@ -0,0 +1,25 @@
# Copyright (c) 2020  Jinan Bosai Network Technology Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_library("A02_MQ5") {
sources = [
"src/MQ5.c",
"A02_MQ5.c"
]
include_dirs = [
"//base/iot_hardware/peripheral/interfaces/kits",
"//device/bossay/hi3861_l0/iot_hardware_hals/include",
"include"
]
}

32
app/A02_MQ5/include/MQ5.h Normal file
View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2022 Jinan Bosai Network Technology Co., LTD Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __E53_SF1_H__
#define __E53_SF1_H__
typedef enum
{
OFF = 0,
ON
} SwitchStatus;
void BoardInit(void);
void MQ2PPMCalibration(void);
int GetMQ2PPM(float *ppm);
void BeepStatusSet(SwitchStatus status);
void LedStatusSet(SwitchStatus status);
#endif /* __E53_SF1_H__ */

144
app/A02_MQ5/src/MQ5.c Normal file
View File

@ -0,0 +1,144 @@
/*
* Copyright (c) 2020  Jinan Bosai Network Technology Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "MQ5.h"
#include "iot_adc.h"
#include "iot_errno.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#include "iot_pwm.h"
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define CAL_PPM 20 //校准环境中PPM值
#define RL 1 // RL阻值
#define WIFI_IOT_IO_NAME_GPIO_8 8
#define WIFI_IOT_PWM_PORT_PWM1 1
#define WIFI_IOT_IO_FUNC_GPIO_8_PWM1_OUT 5
#define LED_GPIO 14
static float R0; //元件在洁净空气中的阻值
/***************************************************************
* : MQ5Init
* : MQ5Init
* :
* :
***************************************************************/
void BoardInit(void)
{
IoTGpioInit(LED_GPIO);
IoTGpioSetFunc(LED_GPIO, IOT_GPIO_FUNC_GPIO_14_GPIO);
IoTGpioSetDir(LED_GPIO, IOT_GPIO_DIR_OUT); //设置GPIO_7为输出模式
IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_8); //初始化GPIO_8
IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_8, WIFI_IOT_IO_FUNC_GPIO_8_PWM1_OUT); //设置GPIO_8引脚复用功能为PWM
IoTGpioSetDir(WIFI_IOT_IO_NAME_GPIO_8, IOT_GPIO_DIR_OUT); //设置GPIO_8引脚为输出模式
IoTPwmInit(WIFI_IOT_PWM_PORT_PWM1); //初始化PWM1端口
}
/***************************************************************
* : GetVoltage
* :
* :
*
* :
***************************************************************/
static float GetVoltage(void)
{
unsigned int ret;
unsigned short data;
ret = IoTAdcRead(6, &data, IOT_ADC_EQU_MODEL_8, IOT_ADC_CUR_BAIS_DEFAULT, 0xff);
if (ret != IOT_SUCCESS)
{
printf("ADC Read Fail\n");
}
return (float)data * 1.8 * 4 / 4096.0;
}
/***************************************************************
* : GetMQ5PPM
* : PPM函数
* : ppm
* : 0 ; -1
***************************************************************/
int GetMQ5PPM(float* ppm)
{
unsigned int ret;
unsigned short data;
float voltage, RS;
ret = IoTAdcRead(5, &data, IOT_ADC_EQU_MODEL_8, IOT_ADC_CUR_BAIS_DEFAULT, 0xff);
if (ret != 0) {
printf("ADC Read Fail\n");
return -1;
}
voltage = (float)data * 1.8 * 4 / 4096.0;
RS = (5 - voltage) / voltage * RL; //计算RS
*ppm = 613.9f * pow(RS / R0, -2.074f); //计算ppm
return 0;
}
/***************************************************************
* : MQ5PPMCalibration
* :
* :
* :
***************************************************************/
void MQ5PPMCalibration(void)
{
float voltage = GetVoltage();
float RS = (5 - voltage) / voltage * RL;
R0 = RS / pow(CAL_PPM / 613.9f, 1 / -2.074f);
}
/***************************************************************
* : BeepStatusSet
* :
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void BeepStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTPwmStart(WIFI_IOT_PWM_PORT_PWM1, 50, 4000); //输出PWM波
}
if (status == OFF) {
IoTPwmStop(WIFI_IOT_PWM_PORT_PWM1);
}
}
/***************************************************************
* : LedStatusSet
* :
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void LedStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(LED_GPIO, 1); //设置GPIO_7输出高电平点亮LED灯
}
if (status == OFF) {
IoTGpioSetOutputVal(LED_GPIO, 0); //设置GPIO_7输出低电平点亮LED灯
}
}

View File

@ -0,0 +1,193 @@
/*
* Copyright (c) 2022 Jinan Bosai Network Technology Co., LTD Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "max30102.h"
#include "algorithm.h"
#include "cmsis_os2.h"
#include "ohos_init.h"
#define TASK_STACK_SIZE 1024 * 8
#define TASK_PRIO 25
uint32_t aun_ir_buffer[500]; //IR LED sensor data
int32_t n_ir_buffer_length; //data length
uint32_t aun_red_buffer[500]; //Red LED sensor data
int32_t n_sp02; //SPO2 value
int8_t ch_spo2_valid; //indicator to show if the SP02 calculation is valid
int32_t n_heart_rate; //heart rate value
int8_t ch_hr_valid; //indicator to show if the heart rate calculation is valid
uint8_t uch_dummy;
#define MAX_BRIGHTNESS 255
static void ExampleTask(void)
{
//variables to calculate the on-board LED brightness that reflects the heartbeats
uint32_t un_min, un_max, un_prev_data;
int i;
int32_t n_brightness;
float f_temp;
uint8_t temp_num=0;
uint8_t temp[6]={0,0,0,0,0,0};
uint8_t str[100];
uint8_t dis_hr=0,dis_spo2=0;
BoardInit();
maxim_max30102_init();
printf("\r\n MAX30102 init \r\n");
un_min=0x3FFFF;
un_max=0;
n_ir_buffer_length=500; //buffer length of 100 stores 5 seconds of samples running at 100sps
//read the first 500 samples, and determine the signal range
for(i=0;i<n_ir_buffer_length;i++)
{
while(GetInit()==1); //wait until the interrupt pin asserts
max30102_FIFO_ReadBytes(REG_FIFO_DATA,temp);
aun_red_buffer[i] = (long)((long)((long)temp[0]&0x03)<<16) | (long)temp[1]<<8 | (long)temp[2]; // Combine values to get the actual number
aun_ir_buffer[i] = (long)((long)((long)temp[3] & 0x03)<<16) |(long)temp[4]<<8 | (long)temp[5]; // Combine values to get the actual number
if(un_min>aun_red_buffer[i])
un_min=aun_red_buffer[i]; //update signal min
if(un_max<aun_red_buffer[i])
un_max=aun_red_buffer[i]; //update signal max
// printf("red=");
// printf("%i", aun_red_buffer[i]);
// printf(", ir=");
// printf("%i\n\r", aun_ir_buffer[i]);
}
un_prev_data=aun_red_buffer[i];
//calculate heart rate and SpO2 after first 500 samples (first 5 seconds of samples)
maxim_heart_rate_and_oxygen_saturation(aun_ir_buffer, n_ir_buffer_length, aun_red_buffer, &n_sp02, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid);
while(1)
{
i=0;
un_min=0x3FFFF;
un_max=0;
//dumping the first 100 sets of samples in the memory and shift the last 400 sets of samples to the top
for(i=100;i<500;i++)
{
aun_red_buffer[i-100]=aun_red_buffer[i];
aun_ir_buffer[i-100]=aun_ir_buffer[i];
//update the signal min and max
if(un_min>aun_red_buffer[i])
un_min=aun_red_buffer[i];
if(un_max<aun_red_buffer[i])
un_max=aun_red_buffer[i];
}
//take 100 sets of samples before calculating the heart rate.
for(i=400;i<500;i++)
{
un_prev_data=aun_red_buffer[i-1];
while(GetInit()==1);
max30102_FIFO_ReadBytes(REG_FIFO_DATA,temp);
aun_red_buffer[i] = (long)((long)((long)temp[0]&0x03)<<16) | (long)temp[1]<<8 | (long)temp[2]; // Combine values to get the actual number
aun_ir_buffer[i] = (long)((long)((long)temp[3] & 0x03)<<16) |(long)temp[4]<<8 | (long)temp[5]; // Combine values to get the actual number
if(aun_red_buffer[i]>un_prev_data)
{
f_temp=aun_red_buffer[i]-un_prev_data;
f_temp/=(un_max-un_min);
f_temp*=MAX_BRIGHTNESS;
n_brightness-=(int)f_temp;
if(n_brightness<0)
n_brightness=0;
}
else
{
f_temp=un_prev_data-aun_red_buffer[i];
f_temp/=(un_max-un_min);
f_temp*=MAX_BRIGHTNESS;
n_brightness+=(int)f_temp;
if(n_brightness>MAX_BRIGHTNESS)
n_brightness=MAX_BRIGHTNESS;
}
//send samples and calculation result to terminal program through UART
if(ch_hr_valid == 1 && n_heart_rate<120)//**/ ch_hr_valid == 1 && ch_spo2_valid ==1 && n_heart_rate<120 && n_sp02<101
{
dis_hr = n_heart_rate;
dis_spo2 = n_sp02;
}
else
{
dis_hr = 0;
dis_spo2 = 0;
}
}
// for(i=0;i<500;i++){
// printf("0x%02x,",aun_ir_buffer[i]);
// }
// printf("\r\n");
// printf("--------0-0-----\r\n");
// for(i=0;i<500;i++){
// printf("0x%02x,",aun_red_buffer[i]);
// }
// printf("\r\n");
// printf("--------0-0-----\r\n");
maxim_heart_rate_and_oxygen_saturation(aun_ir_buffer, n_ir_buffer_length, aun_red_buffer, &n_sp02, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid);
printf("HR=%i, ", n_heart_rate);
printf("HRvalid=%i, ", ch_hr_valid);
// printf("SpO2=%i, ", n_sp02);
// printf("SPO2Valid=%i\r\n", ch_spo2_valid);
sleep(1);
// //显示刷新
// LED0=0;
// if(dis_hr == 0 && dis_spo2 == 0) //**dis_hr == 0 && dis_spo2 == 0
// {
// sprintf((char *)str,"HR:--- SpO2:--- ");//**HR:--- SpO2:---
// }
// else{
// sprintf((char *)str,"HR:%3d SpO2:%3d ",dis_hr,dis_spo2);//**HR:%3d SpO2:%3d
// }
// OLED_ShowString(0,0,str,16);
// OLED_Fill(0,23,127,63,0);
// //红光在上,红外在下
// dis_DrawCurve(aun_red_buffer,20);
// dis_DrawCurve(aun_ir_buffer,0);
// OLED_Refresh_Gram();//更新显示到OLED
}
}
static void ExampleEntry(void)
{
osThreadAttr_t attr;
attr.name = "ExampleTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = TASK_STACK_SIZE;
attr.priority = TASK_PRIO;
if (osThreadNew((osThreadFunc_t)ExampleTask, NULL, &attr) == NULL) {
printf("Failed to create ExampleTask!\n");
}
}
APP_FEATURE_INIT(ExampleEntry);

26
app/A03_MAX30102/BUILD.gn Normal file
View File

@ -0,0 +1,26 @@
# Copyright (c) 2022 Jinan Bosai Network Technology Co., LTD Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_library("A03_MAX30102") {
sources = [
"src/max30102.c",
"src/algorithm.c",
"A03_MAX30102_example.c"
]
include_dirs = [
"//base/iot_hardware/peripheral/interfaces/kits",
"//device/bossay/hi3861_l0/iot_hardware_hals/include",
"include"
]
}

View File

@ -0,0 +1,85 @@
/** \file algorithm.h ******************************************************
*
* Project: MAXREFDES117#
* Filename: algorithm.h
* Description: This module is the heart rate/SpO2 calculation algorithm header file
*
* Revision History:
*\n 1-18-2016 Rev 01.00 SK Initial release.
*\n
*
* --------------------------------------------------------------------
*
* This code follows the following naming conventions:
*
*\n char ch_pmod_value
*\n char (array) s_pmod_s_string[16]
*\n float f_pmod_value
*\n int32_t n_pmod_value
*\n int32_t (array) an_pmod_value[16]
*\n int16_t w_pmod_value
*\n int16_t (array) aw_pmod_value[16]
*\n uint16_t uw_pmod_value
*\n uint16_t (array) auw_pmod_value[16]
*\n uint8_t uch_pmod_value
*\n uint8_t (array) auch_pmod_buffer[16]
*\n uint32_t un_pmod_value
*\n int32_t * pn_pmod_value
*
* ------------------------------------------------------------------------- */
/*******************************************************************************
* Copyright (C) 2015 Maxim Integrated Products, Inc., All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of Maxim Integrated
* Products, Inc. shall not be used except as stated in the Maxim Integrated
* Products, Inc. Branding Policy.
*
* The mere transfer of this software does not imply any licenses
* of trade secrets, proprietary technology, copyrights, patents,
* trademarks, maskwork rights, or any other form of intellectual
* property whatsoever. Maxim Integrated Products, Inc. retains all
* ownership rights.
*******************************************************************************
*/
#ifndef ALGORITHM_H_
#define ALGORITHM_H_
#include <stdint.h>
#define true 1
#define false 0
#define FS 100
#define BUFFER_SIZE (FS* 5)
#define HR_FIFO_SIZE 7
#define MA4_SIZE 4 // DO NOT CHANGE
#define HAMMING_SIZE 5// DO NOT CHANGE
#define min(x,y) ((x) < (y) ? (x) : (y))
void maxim_heart_rate_and_oxygen_saturation(uint32_t *pun_ir_buffer , int32_t n_ir_buffer_length, uint32_t *pun_red_buffer , int32_t *pn_spo2, int8_t *pch_spo2_valid , int32_t *pn_heart_rate , int8_t *pch_hr_valid);
void maxim_find_peaks( int32_t *pn_locs, int32_t *pn_npks, int32_t *pn_x, int32_t n_size, int32_t n_min_height, int32_t n_min_distance, int32_t n_max_num );
void maxim_peaks_above_min_height( int32_t *pn_locs, int32_t *pn_npks, int32_t *pn_x, int32_t n_size, int32_t n_min_height );
void maxim_remove_close_peaks( int32_t *pn_locs, int32_t *pn_npks, int32_t *pn_x, int32_t n_min_distance );
void maxim_sort_ascend( int32_t *pn_x, int32_t n_size );
void maxim_sort_indices_descend( int32_t *pn_x, int32_t *pn_indx, int32_t n_size);
#endif /* ALGORITHM_H_ */

View File

@ -0,0 +1,42 @@
#ifndef MAX30102_H_
#define MAX30102_H_
#include <stdint.h>
#define MAX30102_SLAVE_ADDRESS 0x57
//register addresses
#define REG_INTR_STATUS_1 0x00
#define REG_INTR_STATUS_2 0x01
#define REG_INTR_ENABLE_1 0x02
#define REG_INTR_ENABLE_2 0x03
#define REG_FIFO_WR_PTR 0x04
#define REG_OVF_COUNTER 0x05
#define REG_FIFO_RD_PTR 0x06
#define REG_FIFO_DATA 0x07
#define REG_FIFO_CONFIG 0x08
#define REG_MODE_CONFIG 0x09
#define REG_SPO2_CONFIG 0x0A
#define REG_LED1_PA 0x0C
#define REG_LED2_PA 0x0D
#define REG_PILOT_PA 0x10
#define REG_MULTI_LED_CTRL1 0x11
#define REG_MULTI_LED_CTRL2 0x12
#define REG_TEMP_INTR 0x1F
#define REG_TEMP_FRAC 0x20
#define REG_TEMP_CONFIG 0x21
#define REG_PROX_INT_THRESH 0x30
#define REG_REV_ID 0xFE
#define REG_PART_ID 0xFF
void BoardInit(void);
uint8_t GetInit(void);
uint8_t maxim_max30102_reset();
uint8_t maxim_max30102_init();
uint8_t max30102_FIFO_ReadBytes(uint8_t Register_Address,uint8_t* Data);
uint8_t maxim_max30102_read_fifo(uint32_t *pun_red_led, uint32_t *pun_ir_led);
#endif /* MAX30102_H_ */

View File

@ -0,0 +1,379 @@
/** \file algorithm.cpp ******************************************************
*
* Project: MAXREFDES117#
* Filename: algorithm.cpp
* Description: This module calculates the heart rate/SpO2 level
*
*
* --------------------------------------------------------------------
*
* This code follows the following naming conventions:
*
* char ch_pmod_value
* char (array) s_pmod_s_string[16]
* float f_pmod_value
* int32_t n_pmod_value
* int32_t (array) an_pmod_value[16]
* int16_t w_pmod_value
* int16_t (array) aw_pmod_value[16]
* uint16_t uw_pmod_value
* uint16_t (array) auw_pmod_value[16]
* uint8_t uch_pmod_value
* uint8_t (array) auch_pmod_buffer[16]
* uint32_t un_pmod_value
* int32_t * pn_pmod_value
*
* ------------------------------------------------------------------------- */
/*******************************************************************************
* Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of Maxim Integrated
* Products, Inc. shall not be used except as stated in the Maxim Integrated
* Products, Inc. Branding Policy.
*
* The mere transfer of this software does not imply any licenses
* of trade secrets, proprietary technology, copyrights, patents,
* trademarks, maskwork rights, or any other form of intellectual
* property whatsoever. Maxim Integrated Products, Inc. retains all
* ownership rights.
*******************************************************************************
*/
#include "algorithm.h"
const uint16_t auw_hamm[31]={ 41, 276, 512, 276, 41 }; //Hamm= long16(512* hamming(5)');
//uch_spo2_table is computed as -45.060*ratioAverage* ratioAverage + 30.354 *ratioAverage + 94.845 ;
const uint8_t uch_spo2_table[184]={ 95, 95, 95, 96, 96, 96, 97, 97, 97, 97, 97, 98, 98, 98, 98, 98, 99, 99, 99, 99,
99, 99, 99, 99, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
100, 100, 100, 100, 99, 99, 99, 99, 99, 99, 99, 99, 98, 98, 98, 98, 98, 98, 97, 97,
97, 97, 96, 96, 96, 96, 95, 95, 95, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91, 91,
90, 90, 89, 89, 89, 88, 88, 87, 87, 86, 86, 85, 85, 84, 84, 83, 82, 82, 81, 81,
80, 80, 79, 78, 78, 77, 76, 76, 75, 74, 74, 73, 72, 72, 71, 70, 69, 69, 68, 67,
66, 66, 65, 64, 63, 62, 62, 61, 60, 59, 58, 57, 56, 56, 55, 54, 53, 52, 51, 50,
49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 31, 30, 29,
28, 27, 26, 25, 23, 22, 21, 20, 19, 17, 16, 15, 14, 12, 11, 10, 9, 7, 6, 5,
3, 2, 1 } ;
static int32_t an_dx[ BUFFER_SIZE-MA4_SIZE]; // delta
static int32_t an_x[ BUFFER_SIZE]; //ir
static int32_t an_y[ BUFFER_SIZE]; //red
void maxim_heart_rate_and_oxygen_saturation(uint32_t *pun_ir_buffer, int32_t n_ir_buffer_length, uint32_t *pun_red_buffer, int32_t *pn_spo2, int8_t *pch_spo2_valid,
int32_t *pn_heart_rate, int8_t *pch_hr_valid)
/**
* \brief Calculate the heart rate and SpO2 level
* \par Details
* By detecting peaks of PPG cycle and corresponding AC/DC of red/infra-red signal, the ratio for the SPO2 is computed.
* Since this algorithm is aiming for Arm M0/M3. formaula for SPO2 did not achieve the accuracy due to register overflow.
* Thus, accurate SPO2 is precalculated and save longo uch_spo2_table[] per each ratio.
*
* \param[in] *pun_ir_buffer - IR sensor data buffer
* \param[in] n_ir_buffer_length - IR sensor data buffer length
* \param[in] *pun_red_buffer - Red sensor data buffer
* \param[out] *pn_spo2 - Calculated SpO2 value
* \param[out] *pch_spo2_valid - 1 if the calculated SpO2 value is valid
* \param[out] *pn_heart_rate - Calculated heart rate value
* \param[out] *pch_hr_valid - 1 if the calculated heart rate value is valid
*
* \retval None
*/
{
uint32_t un_ir_mean ,un_only_once ;
int32_t k ,n_i_ratio_count;
int32_t i, s, m, n_exact_ir_valley_locs_count ,n_middle_idx;
int32_t n_th1, n_npks,n_c_min;
int32_t an_ir_valley_locs[15] ;
int32_t an_exact_ir_valley_locs[15] ;
int32_t an_dx_peak_locs[15] ;
int32_t n_peak_interval_sum;
int32_t n_y_ac, n_x_ac;
int32_t n_spo2_calc;
int32_t n_y_dc_max, n_x_dc_max;
int32_t n_y_dc_max_idx, n_x_dc_max_idx;
int32_t an_ratio[5],n_ratio_average;
int32_t n_nume, n_denom ;
// remove DC of ir signal
un_ir_mean =0;
for (k=0 ; k<n_ir_buffer_length ; k++ ) un_ir_mean += pun_ir_buffer[k] ;
un_ir_mean =un_ir_mean/n_ir_buffer_length ;
for (k=0 ; k<n_ir_buffer_length ; k++ ) an_x[k] = pun_ir_buffer[k] - un_ir_mean ;
// 4 pt Moving Average
for(k=0; k< BUFFER_SIZE-MA4_SIZE; k++){
n_denom= ( an_x[k]+an_x[k+1]+ an_x[k+2]+ an_x[k+3]);
an_x[k]= n_denom/(int32_t)4;
}
// get difference of smoothed IR signal
for( k=0; k<BUFFER_SIZE-MA4_SIZE-1; k++)
an_dx[k]= (an_x[k+1]- an_x[k]);
// 2-pt Moving Average to an_dx
for(k=0; k< BUFFER_SIZE-MA4_SIZE-2; k++){
an_dx[k] = ( an_dx[k]+an_dx[k+1])/2 ;
}
// hamming window
// flip wave form so that we can detect valley with peak detector
for ( i=0 ; i<BUFFER_SIZE-HAMMING_SIZE-MA4_SIZE-2 ;i++){
s= 0;
for( k=i; k<i+ HAMMING_SIZE ;k++){
s -= an_dx[k] *auw_hamm[k-i] ;
}
an_dx[i]= s/ (int32_t)1146; // divide by sum of auw_hamm
}
n_th1=0; // threshold calculation
for ( k=0 ; k<BUFFER_SIZE-HAMMING_SIZE ;k++){
n_th1 += ((an_dx[k]>0)? an_dx[k] : ((int32_t)0-an_dx[k])) ;
}
n_th1= n_th1/ ( BUFFER_SIZE-HAMMING_SIZE);
// peak location is acutally index for sharpest location of raw signal since we flipped the signal
maxim_find_peaks( an_dx_peak_locs, &n_npks, an_dx, BUFFER_SIZE-HAMMING_SIZE, n_th1, 8, 5 );//peak_height, peak_distance, max_num_peaks
n_peak_interval_sum =0;
if (n_npks>=2){
for (k=1; k<n_npks; k++)
n_peak_interval_sum += (an_dx_peak_locs[k]-an_dx_peak_locs[k -1]);
n_peak_interval_sum=n_peak_interval_sum/(n_npks-1);
*pn_heart_rate=(int32_t)(6000/n_peak_interval_sum);// beats per minutes
*pch_hr_valid = 1;
}
else {
*pn_heart_rate = -999;
*pch_hr_valid = 0;
}
for ( k=0 ; k<n_npks ;k++)
an_ir_valley_locs[k]=an_dx_peak_locs[k]+HAMMING_SIZE/2;
// raw value : RED(=y) and IR(=X)
// we need to assess DC and AC value of ir and red PPG.
for (k=0 ; k<n_ir_buffer_length ; k++ ) {
an_x[k] = pun_ir_buffer[k] ;
an_y[k] = pun_red_buffer[k] ;
}
// find precise min near an_ir_valley_locs
n_exact_ir_valley_locs_count =0;
for(k=0 ; k<n_npks ;k++){
un_only_once =1;
m=an_ir_valley_locs[k];
n_c_min= 16777216;//2^24;
if (m+5 < BUFFER_SIZE-HAMMING_SIZE && m-5 >0){
for(i= m-5;i<m+5; i++)
if (an_x[i]<n_c_min){
if (un_only_once >0){
un_only_once =0;
}
n_c_min= an_x[i] ;
an_exact_ir_valley_locs[k]=i;
}
if (un_only_once ==0)
n_exact_ir_valley_locs_count ++ ;
}
}
if (n_exact_ir_valley_locs_count <2 ){
*pn_spo2 = -999 ; // do not use SPO2 since signal ratio is out of range
*pch_spo2_valid = 0;
return;
}
// 4 pt MA
for(k=0; k< BUFFER_SIZE-MA4_SIZE; k++){
an_x[k]=( an_x[k]+an_x[k+1]+ an_x[k+2]+ an_x[k+3])/(int32_t)4;
an_y[k]=( an_y[k]+an_y[k+1]+ an_y[k+2]+ an_y[k+3])/(int32_t)4;
}
//using an_exact_ir_valley_locs , find ir-red DC andir-red AC for SPO2 calibration ratio
//finding AC/DC maximum of raw ir * red between two valley locations
n_ratio_average =0;
n_i_ratio_count =0;
for(k=0; k< 5; k++) an_ratio[k]=0;
for (k=0; k< n_exact_ir_valley_locs_count; k++){
if (an_exact_ir_valley_locs[k] > BUFFER_SIZE ){
*pn_spo2 = -999 ; // do not use SPO2 since valley loc is out of range
*pch_spo2_valid = 0;
return;
}
}
// find max between two valley locations
// and use ratio betwen AC compoent of Ir & Red and DC compoent of Ir & Red for SPO2
for (k=0; k< n_exact_ir_valley_locs_count-1; k++){
n_y_dc_max= -16777216 ;
n_x_dc_max= - 16777216;
if (an_exact_ir_valley_locs[k+1]-an_exact_ir_valley_locs[k] >10){
for (i=an_exact_ir_valley_locs[k]; i< an_exact_ir_valley_locs[k+1]; i++){
if (an_x[i]> n_x_dc_max) {n_x_dc_max =an_x[i];n_x_dc_max_idx =i; }
if (an_y[i]> n_y_dc_max) {n_y_dc_max =an_y[i];n_y_dc_max_idx=i;}
}
n_y_ac= (an_y[an_exact_ir_valley_locs[k+1]] - an_y[an_exact_ir_valley_locs[k] ] )*(n_y_dc_max_idx -an_exact_ir_valley_locs[k]); //red
n_y_ac= an_y[an_exact_ir_valley_locs[k]] + n_y_ac/ (an_exact_ir_valley_locs[k+1] - an_exact_ir_valley_locs[k]) ;
n_y_ac= an_y[n_y_dc_max_idx] - n_y_ac; // subracting linear DC compoenents from raw
n_x_ac= (an_x[an_exact_ir_valley_locs[k+1]] - an_x[an_exact_ir_valley_locs[k] ] )*(n_x_dc_max_idx -an_exact_ir_valley_locs[k]); // ir
n_x_ac= an_x[an_exact_ir_valley_locs[k]] + n_x_ac/ (an_exact_ir_valley_locs[k+1] - an_exact_ir_valley_locs[k]);
n_x_ac= an_x[n_y_dc_max_idx] - n_x_ac; // subracting linear DC compoenents from raw
n_nume=( n_y_ac *n_x_dc_max)>>7 ; //prepare X100 to preserve floating value
n_denom= ( n_x_ac *n_y_dc_max)>>7;
if (n_denom>0 && n_i_ratio_count <5 && n_nume != 0)
{
an_ratio[n_i_ratio_count]= (n_nume*20)/n_denom ; //formular is ( n_y_ac *n_x_dc_max) / ( n_x_ac *n_y_dc_max) ;
n_i_ratio_count++;
}
}
}
maxim_sort_ascend(an_ratio, n_i_ratio_count);
n_middle_idx= n_i_ratio_count/2;
if (n_middle_idx >1)
n_ratio_average =( an_ratio[n_middle_idx-1] +an_ratio[n_middle_idx])/2; // use median
else
n_ratio_average = an_ratio[n_middle_idx ];
if( n_ratio_average>2 && n_ratio_average <184){
n_spo2_calc= uch_spo2_table[n_ratio_average] ;
*pn_spo2 = n_spo2_calc ;
*pch_spo2_valid = 1;// float_SPO2 = -45.060*n_ratio_average* n_ratio_average/10000 + 30.354 *n_ratio_average/100 + 94.845 ; // for comparison with table
}
else{
*pn_spo2 = -999 ; // do not use SPO2 since signal ratio is out of range
*pch_spo2_valid = 0;
}
}
void maxim_find_peaks(int32_t *pn_locs, int32_t *pn_npks, int32_t *pn_x, int32_t n_size, int32_t n_min_height, int32_t n_min_distance, int32_t n_max_num)
/**
* \brief Find peaks
* \par Details
* Find at most MAX_NUM peaks above MIN_HEIGHT separated by at least MIN_DISTANCE
*
* \retval None
*/
{
maxim_peaks_above_min_height( pn_locs, pn_npks, pn_x, n_size, n_min_height );
maxim_remove_close_peaks( pn_locs, pn_npks, pn_x, n_min_distance );
*pn_npks = min( *pn_npks, n_max_num );
}
void maxim_peaks_above_min_height(int32_t *pn_locs, int32_t *pn_npks, int32_t *pn_x, int32_t n_size, int32_t n_min_height)
/**
* \brief Find peaks above n_min_height
* \par Details
* Find all peaks above MIN_HEIGHT
*
* \retval None
*/
{
int32_t i = 1, n_width;
*pn_npks = 0;
while (i < n_size-1){
if (pn_x[i] > n_min_height && pn_x[i] > pn_x[i-1]){ // find left edge of potential peaks
n_width = 1;
while (i+n_width < n_size && pn_x[i] == pn_x[i+n_width]) // find flat peaks
n_width++;
if (pn_x[i] > pn_x[i+n_width] && (*pn_npks) < 15 ){ // find right edge of peaks
pn_locs[(*pn_npks)++] = i;
// for flat peaks, peak location is left edge
i += n_width+1;
}
else
i += n_width;
}
else
i++;
}
}
void maxim_remove_close_peaks(int32_t *pn_locs, int32_t *pn_npks, int32_t *pn_x, int32_t n_min_distance)
/**
* \brief Remove peaks
* \par Details
* Remove peaks separated by less than MIN_DISTANCE
*
* \retval None
*/
{
int32_t i, j, n_old_npks, n_dist;
/* Order peaks from large to small */
maxim_sort_indices_descend( pn_x, pn_locs, *pn_npks );
for ( i = -1; i < *pn_npks; i++ ){
n_old_npks = *pn_npks;
*pn_npks = i+1;
for ( j = i+1; j < n_old_npks; j++ ){
n_dist = pn_locs[j] - ( i == -1 ? -1 : pn_locs[i] ); // lag-zero peak of autocorr is at index -1
if ( n_dist > n_min_distance || n_dist < -n_min_distance )
pn_locs[(*pn_npks)++] = pn_locs[j];
}
}
// Resort indices longo ascending order
maxim_sort_ascend( pn_locs, *pn_npks );
}
void maxim_sort_ascend(int32_t *pn_x,int32_t n_size)
/**
* \brief Sort array
* \par Details
* Sort array in ascending order (insertion sort algorithm)
*
* \retval None
*/
{
int32_t i, j, n_temp;
for (i = 1; i < n_size; i++) {
n_temp = pn_x[i];
for (j = i; j > 0 && n_temp < pn_x[j-1]; j--)
pn_x[j] = pn_x[j-1];
pn_x[j] = n_temp;
}
}
void maxim_sort_indices_descend(int32_t *pn_x, int32_t *pn_indx, int32_t n_size)
/**
* \brief Sort indices
* \par Details
* Sort indices according to descending order (insertion sort algorithm)
*
* \retval None
*/
{
int32_t i, j, n_temp;
for (i = 1; i < n_size; i++) {
n_temp = pn_indx[i];
for (j = i; j > 0 && pn_x[n_temp] > pn_x[pn_indx[j-1]]; j--)
pn_indx[j] = pn_indx[j-1];
pn_indx[j] = n_temp;
}
}

View File

@ -0,0 +1,237 @@
#include "max30102.h"
#include "iot_errno.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#include "iot_i2c.h"
#include "iot_i2c_ex.h"
#include <stdio.h>
#define WIFI_IOT_IO_FUNC_GPIO_0_I2C1_SDA 6
#define WIFI_IOT_IO_FUNC_GPIO_1_I2C1_SCL 6
#define WIFI_IOT_I2C_IDX_1 1
#define WIFI_IOT_IO_NAME_GPIO_7 7
#define WIFI_IOT_IO_NAME_GPIO_8 8
#define WIFI_IOT_IO_NAME_GPIO_0 0
#define WIFI_IOT_IO_NAME_GPIO_1 1
#define MAX30102_INIT_GPIO 7
/***************************************************************
* : GpioInit
* : GPIO初始化
* :
* :
***************************************************************/
void BoardInit(void)
{
// IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_8);
// IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_8, WIFI_IOT_IO_FUNC_GPIO_8_GPIO);
// IoTGpioSetDir(WIFI_IOT_IO_NAME_GPIO_8, IOT_GPIO_DIR_OUT); // 设置GPIO_8为输出模式
IoTGpioInit(MAX30102_INIT_GPIO);
IoTGpioSetFunc(MAX30102_INIT_GPIO, IOT_GPIO_FUNC_GPIO_7_GPIO);
IoTGpioSetDir(MAX30102_INIT_GPIO, IOT_GPIO_DIR_IN); // 设置GPIO_7为输出模式
IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_0);
IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_0, WIFI_IOT_IO_FUNC_GPIO_0_I2C1_SDA); // GPIO_0复用为I2C1_SDA
IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_1);
IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_1, WIFI_IOT_IO_FUNC_GPIO_1_I2C1_SCL); // GPIO_1复用为I2C1_SCL
IoTI2cInit(WIFI_IOT_I2C_IDX_1, 400000); /* baudrate: 400kbps */
}
uint8_t GetInit(void)
{
IotGpioValue temp = {0};
IoTGpioGetInputVal(MAX30102_INIT_GPIO,&temp);
return temp;
}
/**
* \brief Write a value to a MAX30102 register
* \par Details
* This function writes a value to a MAX30102 register
*
* \param[in] uch_addr - register address
* \param[in] uch_data - register data
*
* \retval true on success
*/
static int maxim_max30102_write_reg(uint8_t uch_addr, uint8_t uch_data)
{
uint32_t ret;
uint8_t send_data[2] = {uch_addr, uch_data};
ret = IoTI2cWrite(WIFI_IOT_I2C_IDX_1, (MAX30102_SLAVE_ADDRESS << 1) | 0x00, send_data, 2);
if (ret != 0) {
printf("===== Error: I2C write ret = 0x%x! =====\r\n", ret);
return -1;
}
return 0;
}
/**
* \brief Read a MAX30102 register
* \par Details
* This function reads a MAX30102 register
*
* \param[in] uch_addr - register address
* \param[out] puch_data - pointer that stores the register data
*
* \retval true on success
*/
uint8_t maxim_max30102_read_reg(uint8_t uch_addr, uint8_t *puch_data)
{
uint32_t ret = 0;
IotI2cData max30102_i2c_data = {0};
uint8_t buffer[1] = {uch_addr};
max30102_i2c_data.sendBuf = buffer;
max30102_i2c_data.sendLen = 1;
max30102_i2c_data.receiveBuf = puch_data;
max30102_i2c_data.receiveLen = 1;
ret = IoTI2cWriteread(WIFI_IOT_I2C_IDX_1, (MAX30102_SLAVE_ADDRESS << 1) | 0x00, &max30102_i2c_data);
if (ret != 0) {
printf("===== Error: I2C writeread ret = 0x%x! =====\r\n", ret);
return -1;
}
return 0;
}
uint8_t maxim_max30102_init()
{
if(maxim_max30102_write_reg(REG_INTR_ENABLE_1,0xc0)!=IOT_SUCCESS) // INTR setting
return 0;
if(maxim_max30102_write_reg(REG_INTR_ENABLE_2,0x00)!=IOT_SUCCESS)
return 0;
if(maxim_max30102_write_reg(REG_FIFO_WR_PTR,0x00)!=IOT_SUCCESS) //FIFO_WR_PTR[4:0]
return 0;
if(maxim_max30102_write_reg(REG_OVF_COUNTER,0x00)!=IOT_SUCCESS) //OVF_COUNTER[4:0]
return 0;
if(maxim_max30102_write_reg(REG_FIFO_RD_PTR,0x00)!=IOT_SUCCESS) //FIFO_RD_PTR[4:0]
return 0;
if(maxim_max30102_write_reg(REG_FIFO_CONFIG,0x0f)!=IOT_SUCCESS) //sample avg = 1, fifo rollover=false, fifo almost full = 17
return 0;
if(maxim_max30102_write_reg(REG_MODE_CONFIG,0x03)!=IOT_SUCCESS) //0x02 for Red only, 0x03 for SpO2 mode 0x07 multimode LED
return 0;
if(maxim_max30102_write_reg(REG_SPO2_CONFIG,0x27)!=IOT_SUCCESS) // SPO2_ADC range = 4096nA, SPO2 sample rate (100 Hz), LED pulseWidth (400uS)
return 0;
if(maxim_max30102_write_reg(REG_LED1_PA,0x32)!=IOT_SUCCESS) //Choose value for ~ 7mA for LED1
return 0;
if(maxim_max30102_write_reg(REG_LED2_PA,0x32)!=IOT_SUCCESS) // Choose value for ~ 7mA for LED2
return 0;
if(maxim_max30102_write_reg(REG_PILOT_PA,0x7f)!=IOT_SUCCESS) // Choose value for ~ 25mA for Pilot LED
return 0;
return 1;
}
/**
* \brief Reset the MAX30102
* \par Details
* This function resets the MAX30102
*
* \param None
*
* \retval true on success
*/
uint8_t maxim_max30102_reset()
{
if(maxim_max30102_write_reg(REG_MODE_CONFIG,0x40)!=IOT_SUCCESS)
return 0;
else
return 1;
}
/**
* \brief Read a set of samples from the MAX30102 FIFO register
* \par Details
* This function reads a set of samples from the MAX30102 FIFO register
*
* \param[out] *pun_red_led - pointer that stores the red LED reading data
* \param[out] *pun_ir_led - pointer that stores the IR LED reading data
*
* \retval true on success
*/
uint8_t max30102_FIFO_ReadBytes(uint8_t Register_Address,uint8_t* Data)
{
uint32_t un_temp;
unsigned char uch_temp;
//read and clear status register
maxim_max30102_read_reg(REG_INTR_STATUS_1, &uch_temp);
maxim_max30102_read_reg(REG_INTR_STATUS_2, &uch_temp);
// ach_i2c_data[0]=REG_FIFO_DATA;
uint32_t ret = 0;
IotI2cData max30102_i2c_data = {0};
uint8_t buffer[1] = {REG_FIFO_DATA};
max30102_i2c_data.sendBuf = buffer;
max30102_i2c_data.sendLen = 1;
max30102_i2c_data.receiveBuf = Data;
max30102_i2c_data.receiveLen = 6;
ret = IoTI2cWriteread(WIFI_IOT_I2C_IDX_1, (MAX30102_SLAVE_ADDRESS << 1) | 0x00, &max30102_i2c_data);
if (ret != 0) {
printf("===== Error: I2C writeread ret = 0x%x! =====\r\n", ret);
return -1;
}
return 0;
}
/**
* \brief Read a set of samples from the MAX30102 FIFO register
* \par Details
* This function reads a set of samples from the MAX30102 FIFO register
*
* \param[out] *pun_red_led - pointer that stores the red LED reading data
* \param[out] *pun_ir_led - pointer that stores the IR LED reading data
*
* \retval true on success
*/
uint8_t maxim_max30102_read_fifo(uint32_t *pun_red_led, uint32_t *pun_ir_led)
{
uint32_t un_temp;
unsigned char uch_temp;
*pun_red_led=0;
*pun_ir_led=0;
uint8_t ach_i2c_data[6];
//read and clear status register
maxim_max30102_read_reg(REG_INTR_STATUS_1, &uch_temp);
maxim_max30102_read_reg(REG_INTR_STATUS_2, &uch_temp);
// ach_i2c_data[0]=REG_FIFO_DATA;
uint32_t ret = 0;
IotI2cData max30102_i2c_data = {0};
uint8_t buffer[1] = {REG_FIFO_DATA};
max30102_i2c_data.sendBuf = buffer;
max30102_i2c_data.sendLen = 1;
max30102_i2c_data.receiveBuf = ach_i2c_data;
max30102_i2c_data.receiveLen = 6;
ret = IoTI2cWriteread(WIFI_IOT_I2C_IDX_1, (MAX30102_SLAVE_ADDRESS << 1) | 0x00, &max30102_i2c_data);
if (ret != 0) {
printf("===== Error: I2C writeread ret = 0x%x! =====\r\n", ret);
return -1;
}
un_temp=(unsigned char) ach_i2c_data[0];
un_temp<<=16;
*pun_red_led+=un_temp;
un_temp=(unsigned char) ach_i2c_data[1];
un_temp<<=8;
*pun_red_led+=un_temp;
un_temp=(unsigned char) ach_i2c_data[2];
*pun_red_led+=un_temp;
un_temp=(unsigned char) ach_i2c_data[3];
un_temp<<=16;
*pun_ir_led+=un_temp;
un_temp=(unsigned char) ach_i2c_data[4];
un_temp<<=8;
*pun_ir_led+=un_temp;
un_temp=(unsigned char) ach_i2c_data[5];
*pun_ir_led+=un_temp;
*pun_red_led&=0x03FFFF; //Mask MSB [23:18]
*pun_ir_led&=0x03FFFF; //Mask MSB [23:18]
return 1;
}

View File

@ -0,0 +1,193 @@
/*
* Copyright (c) 2020  Jinan Bosai Network Technology Co., LTD
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "max30102.h"
#include "algorithm.h"
#include "cmsis_os2.h"
#include "ohos_init.h"
#define TASK_STACK_SIZE 1024 * 8
#define TASK_PRIO 25
uint32_t aun_ir_buffer[500]; //IR LED sensor data
int32_t n_ir_buffer_length; //data length
uint32_t aun_red_buffer[500]; //Red LED sensor data
int32_t n_sp02; //SPO2 value
int8_t ch_spo2_valid; //indicator to show if the SP02 calculation is valid
int32_t n_heart_rate; //heart rate value
int8_t ch_hr_valid; //indicator to show if the heart rate calculation is valid
uint8_t uch_dummy;
#define MAX_BRIGHTNESS 255
static void ExampleTask(void)
{
//variables to calculate the on-board LED brightness that reflects the heartbeats
uint32_t un_min, un_max, un_prev_data;
int i;
int32_t n_brightness;
float f_temp;
uint8_t temp_num=0;
uint8_t temp[6]={0,0,0,0,0,0};
uint8_t str[100];
uint8_t dis_hr=0,dis_spo2=0;
BoardInit();
maxim_max30102_init();
printf("\r\n MAX30102 init \r\n");
un_min=0x3FFFF;
un_max=0;
n_ir_buffer_length=500; //buffer length of 100 stores 5 seconds of samples running at 100sps
//read the first 500 samples, and determine the signal range
for(i=0;i<n_ir_buffer_length;i++)
{
while(GetInit()==1); //wait until the interrupt pin asserts
max30102_FIFO_ReadBytes(REG_FIFO_DATA,temp);
aun_red_buffer[i] = (long)((long)((long)temp[0]&0x03)<<16) | (long)temp[1]<<8 | (long)temp[2]; // Combine values to get the actual number
aun_ir_buffer[i] = (long)((long)((long)temp[3] & 0x03)<<16) |(long)temp[4]<<8 | (long)temp[5]; // Combine values to get the actual number
if(un_min>aun_red_buffer[i])
un_min=aun_red_buffer[i]; //update signal min
if(un_max<aun_red_buffer[i])
un_max=aun_red_buffer[i]; //update signal max
// printf("red=");
// printf("%i", aun_red_buffer[i]);
// printf(", ir=");
// printf("%i\n\r", aun_ir_buffer[i]);
}
un_prev_data=aun_red_buffer[i];
//calculate heart rate and SpO2 after first 500 samples (first 5 seconds of samples)
maxim_heart_rate_and_oxygen_saturation(aun_ir_buffer, n_ir_buffer_length, aun_red_buffer, &n_sp02, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid);
while(1)
{
i=0;
un_min=0x3FFFF;
un_max=0;
//dumping the first 100 sets of samples in the memory and shift the last 400 sets of samples to the top
for(i=100;i<500;i++)
{
aun_red_buffer[i-100]=aun_red_buffer[i];
aun_ir_buffer[i-100]=aun_ir_buffer[i];
//update the signal min and max
if(un_min>aun_red_buffer[i])
un_min=aun_red_buffer[i];
if(un_max<aun_red_buffer[i])
un_max=aun_red_buffer[i];
}
//take 100 sets of samples before calculating the heart rate.
for(i=400;i<500;i++)
{
un_prev_data=aun_red_buffer[i-1];
while(GetInit()==1);
max30102_FIFO_ReadBytes(REG_FIFO_DATA,temp);
aun_red_buffer[i] = (long)((long)((long)temp[0]&0x03)<<16) | (long)temp[1]<<8 | (long)temp[2]; // Combine values to get the actual number
aun_ir_buffer[i] = (long)((long)((long)temp[3] & 0x03)<<16) |(long)temp[4]<<8 | (long)temp[5]; // Combine values to get the actual number
if(aun_red_buffer[i]>un_prev_data)
{
f_temp=aun_red_buffer[i]-un_prev_data;
f_temp/=(un_max-un_min);
f_temp*=MAX_BRIGHTNESS;
n_brightness-=(int)f_temp;
if(n_brightness<0)
n_brightness=0;
}
else
{
f_temp=un_prev_data-aun_red_buffer[i];
f_temp/=(un_max-un_min);
f_temp*=MAX_BRIGHTNESS;
n_brightness+=(int)f_temp;
if(n_brightness>MAX_BRIGHTNESS)
n_brightness=MAX_BRIGHTNESS;
}
//send samples and calculation result to terminal program through UART
if(ch_hr_valid == 1 && n_heart_rate<120)//**/ ch_hr_valid == 1 && ch_spo2_valid ==1 && n_heart_rate<120 && n_sp02<101
{
dis_hr = n_heart_rate;
dis_spo2 = n_sp02;
}
else
{
dis_hr = 0;
dis_spo2 = 0;
}
}
// for(i=0;i<500;i++){
// printf("0x%02x,",aun_ir_buffer[i]);
// }
// printf("\r\n");
// printf("--------0-0-----\r\n");
// for(i=0;i<500;i++){
// printf("0x%02x,",aun_red_buffer[i]);
// }
// printf("\r\n");
// printf("--------0-0-----\r\n");
maxim_heart_rate_and_oxygen_saturation(aun_ir_buffer, n_ir_buffer_length, aun_red_buffer, &n_sp02, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid);
printf("HR=%i, ", n_heart_rate);
printf("HRvalid=%i, ", ch_hr_valid);
printf("SpO2=%i, ", n_sp02);
printf("SPO2Valid=%i\r\n", ch_spo2_valid);
sleep(1);
// //显示刷新
// LED0=0;
// if(dis_hr == 0 && dis_spo2 == 0) //**dis_hr == 0 && dis_spo2 == 0
// {
// sprintf((char *)str,"HR:--- SpO2:--- ");//**HR:--- SpO2:---
// }
// else{
// sprintf((char *)str,"HR:%3d SpO2:%3d ",dis_hr,dis_spo2);//**HR:%3d SpO2:%3d
// }
// OLED_ShowString(0,0,str,16);
// OLED_Fill(0,23,127,63,0);
// //红光在上,红外在下
// dis_DrawCurve(aun_red_buffer,20);
// dis_DrawCurve(aun_ir_buffer,0);
// OLED_Refresh_Gram();//更新显示到OLED
}
}
static void ExampleEntry(void)
{
osThreadAttr_t attr;
attr.name = "ExampleTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = TASK_STACK_SIZE;
attr.priority = TASK_PRIO;
if (osThreadNew((osThreadFunc_t)ExampleTask, NULL, &attr) == NULL) {
printf("Failed to create ExampleTask!\n");
}
}
APP_FEATURE_INIT(ExampleEntry);

View File

@ -0,0 +1,89 @@
/*
* Copyright (c) 2020  Jinan Bosai Network Technology Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
// #include "max30102.h"
#include "algorithm.h"
#include "cmsis_os2.h"
#include "ohos_init.h"
#include "blood.h"
#define TASK_STACK_SIZE 1024 * 8
#define TASK_PRIO 25
uint32_t aun_ir_buffer[500]; //IR LED sensor data
int32_t n_ir_buffer_length; //data length
uint32_t aun_red_buffer[500]; //Red LED sensor data
int32_t n_sp02; //SPO2 value
int8_t ch_spo2_valid; //indicator to show if the SP02 calculation is valid
int32_t n_heart_rate; //heart rate value
int8_t ch_hr_valid; //indicator to show if the heart rate calculation is valid
uint8_t uch_dummy;
#define MAX_BRIGHTNESS 255
static void ExampleTask(void)
{
//variables to calculate the on-board LED brightness that reflects the heartbeats
uint32_t un_min, un_max, un_prev_data;
int i;
int32_t n_brightness;
float f_temp;
uint8_t temp_num=0;
uint8_t temp[6]={0,0,0,0,0,0};
uint8_t str[100];
uint8_t dis_hr=0,dis_spo2=0;
BoardInit();
maxim_max30102_init();
printf("\r\n MAX30102 init \r\n");
for(i = 0;i < 128;i++)
{
while(GetInit()==0)
{
max30102_read_fifo();
}
}
while(1)
{
// deal_Temp();
blood_Loop();
}
}
static void ExampleEntry(void)
{
osThreadAttr_t attr;
attr.name = "ExampleTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = TASK_STACK_SIZE;
attr.priority = TASK_PRIO;
if (osThreadNew((osThreadFunc_t)ExampleTask, NULL, &attr) == NULL) {
printf("Failed to create ExampleTask!\n");
}
}
APP_FEATURE_INIT(ExampleEntry);

View File

@ -0,0 +1,177 @@
/*
* Copyright (c) 2020  Jinan Bosai Network Technology Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "max30102.h"
#include "algorithm.h"
#include "cmsis_os2.h"
#include "ohos_init.h"
#define TASK_STACK_SIZE 1024 * 8
#define TASK_PRIO 25
uint32_t aun_ir_buffer[500]; //IR LED sensor data
int32_t n_ir_buffer_length; //data length
uint32_t aun_red_buffer[500]; //Red LED sensor data
int32_t n_sp02; //SPO2 value
int8_t ch_spo2_valid; //indicator to show if the SP02 calculation is valid
int32_t n_heart_rate; //heart rate value
int8_t ch_hr_valid; //indicator to show if the heart rate calculation is valid
uint8_t uch_dummy;
#define MAX_BRIGHTNESS 255
static void ExampleTask(void)
{
//variables to calculate the on-board LED brightness that reflects the heartbeats
uint32_t un_min, un_max, un_prev_data;
int i;
int32_t n_brightness;
float f_temp;
uint8_t temp_num=0;
uint8_t temp[6];
uint8_t str[100];
uint8_t dis_hr=0,dis_spo2=0;
BoardInit();
maxim_max30102_init();
printf("\r\n MAX30102 init \r\n");
un_min=0x3FFFF;
un_max=0;
n_ir_buffer_length=500; //buffer length of 100 stores 5 seconds of samples running at 100sps
//read the first 500 samples, and determine the signal range
for(i=0;i<n_ir_buffer_length;i++)
{
while(GetInit()==1); //wait until the interrupt pin asserts
maxim_max30102_read_fifo((aun_red_buffer+i), (aun_ir_buffer+i));
if(un_min>aun_red_buffer[i])
un_min=aun_red_buffer[i]; //update signal min
if(un_max<aun_red_buffer[i])
un_max=aun_red_buffer[i]; //update signal max
printf("red=");
printf("%i", aun_red_buffer[i]);
printf(", ir=");
printf("%i\n\r", aun_ir_buffer[i]);
}
un_prev_data=aun_red_buffer[i];
//calculate heart rate and SpO2 after first 500 samples (first 5 seconds of samples)
maxim_heart_rate_and_oxygen_saturation(aun_ir_buffer, n_ir_buffer_length, aun_red_buffer, &n_sp02, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid);
while(1)
{
i=0;
un_min=0x3FFFF;
un_max=0;
//dumping the first 100 sets of samples in the memory and shift the last 400 sets of samples to the top
for(i=100;i<500;i++)
{
aun_red_buffer[i-100]=aun_red_buffer[i];
aun_ir_buffer[i-100]=aun_ir_buffer[i];
//update the signal min and max
if(un_min>aun_red_buffer[i])
un_min=aun_red_buffer[i];
if(un_max<aun_red_buffer[i])
un_max=aun_red_buffer[i];
}
//take 100 sets of samples before calculating the heart rate.
for(i=400;i<500;i++)
{
un_prev_data=aun_red_buffer[i-1];
while(GetInit()==1);
maxim_max30102_read_fifo((aun_red_buffer+i), (aun_ir_buffer+i));
if(aun_red_buffer[i]>un_prev_data)
{
f_temp=aun_red_buffer[i]-un_prev_data;
f_temp/=(un_max-un_min);
f_temp*=MAX_BRIGHTNESS;
n_brightness-=(int)f_temp;
if(n_brightness<0)
n_brightness=0;
}
else
{
f_temp=un_prev_data-aun_red_buffer[i];
f_temp/=(un_max-un_min);
f_temp*=MAX_BRIGHTNESS;
n_brightness+=(int)f_temp;
if(n_brightness>MAX_BRIGHTNESS)
n_brightness=MAX_BRIGHTNESS;
}
//send samples and calculation result to terminal program through UART
// if(ch_hr_valid == 1 && n_heart_rate<120)//**/ ch_hr_valid == 1 && ch_spo2_valid ==1 && n_heart_rate<120 && n_sp02<101
// {
// dis_hr = n_heart_rate;
// dis_spo2 = n_sp02;
// }
// else
// {
// dis_hr = 0;
// dis_spo2 = 0;
// }
printf("HR=%i, ", n_heart_rate);
printf("HRvalid=%i, ", ch_hr_valid);
printf("SpO2=%i, ", n_sp02);
printf("SPO2Valid=%i\r\n", ch_spo2_valid);
}
maxim_heart_rate_and_oxygen_saturation(aun_ir_buffer, n_ir_buffer_length, aun_red_buffer, &n_sp02, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid);
// //显示刷新
// LED0=0;
// if(dis_hr == 0 && dis_spo2 == 0) //**dis_hr == 0 && dis_spo2 == 0
// {
// sprintf((char *)str,"HR:--- SpO2:--- ");//**HR:--- SpO2:---
// }
// else{
// sprintf((char *)str,"HR:%3d SpO2:%3d ",dis_hr,dis_spo2);//**HR:%3d SpO2:%3d
// }
// OLED_ShowString(0,0,str,16);
// OLED_Fill(0,23,127,63,0);
// //红光在上,红外在下
// dis_DrawCurve(aun_red_buffer,20);
// dis_DrawCurve(aun_ir_buffer,0);
// OLED_Refresh_Gram();//更新显示到OLED
}
}
static void ExampleEntry(void)
{
osThreadAttr_t attr;
attr.name = "ExampleTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = TASK_STACK_SIZE;
attr.priority = TASK_PRIO;
if (osThreadNew((osThreadFunc_t)ExampleTask, NULL, &attr) == NULL) {
printf("Failed to create ExampleTask!\n");
}
}
APP_FEATURE_INIT(ExampleEntry);

View File

@ -0,0 +1,27 @@
# Copyright (c) 2020  Jinan Bosai Network Technology Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_library("A03_MAX30102") {
sources = [
"src/max30102.c",
"src/algorithm.c",
"src/blood.c",
"A03_MAX30102_example.c"
]
include_dirs = [
"//base/iot_hardware/peripheral/interfaces/kits",
"//device/bossay/hi3861_l0/iot_hardware_hals/include",
"include"
]
}

View File

@ -0,0 +1,63 @@
#ifndef __ALGORITHM_H
#define __ALGORITHM_H
#include <stdint.h>
#define FFT_N 512 //定义傅里叶变换的点数
#define START_INDEX 4 //低频过滤阈值
struct compx //定义一个复数结构
{
float real;
float imag;
};
//向下取整
double my_floor(double x);
//求余运算
double my_fmod(double x, double y);
//正弦函数
double XSin( double x );
//余弦函数
double XCos( double x );
//开平方
int qsqrt(int a);
/*******************************************************************
struct compx EE(struct compx b1,struct compx b2)
a,b
a和b的乘积
*******************************************************************/
struct compx EE(struct compx a,struct compx b);
/*****************************************************************
void FFT(struct compx *xin,int N)
FFT
*xin复数结构体组的首地址指针struct型
*****************************************************************/
void FFT(struct compx *xin);
//读取峰值
int find_max_num_index(struct compx *data,int count);
typedef struct
{
float w;
int init;
float a;
}DC_FilterData;
//直流滤波器
int dc_filter(int input,DC_FilterData * df);
typedef struct
{
float v0;
float v1;
}BW_FilterData;
int bw_filter(int input,BW_FilterData * bw);
#endif /*__ALGORITHM_H*/

View File

@ -0,0 +1,99 @@
/** \file algorithm.h ******************************************************
*
* Project: MAXREFDES117#
* Filename: algorithm.h
* Description: This module is the heart rate/SpO2 calculation algorithm header file
*
* Revision History:
*\n 1-18-2016 Rev 01.00 SK Initial release.
*\n
*
* --------------------------------------------------------------------
*
* This code follows the following naming conventions:
*
*\n char ch_pmod_value
*\n char (array) s_pmod_s_string[16]
*\n float f_pmod_value
*\n int32_t n_pmod_value
*\n int32_t (array) an_pmod_value[16]
*\n int16_t w_pmod_value
*\n int16_t (array) aw_pmod_value[16]
*\n uint16_t uw_pmod_value
*\n uint16_t (array) auw_pmod_value[16]
*\n uint8_t uch_pmod_value
*\n uint8_t (array) auch_pmod_buffer[16]
*\n uint32_t un_pmod_value
*\n int32_t * pn_pmod_value
*
* ------------------------------------------------------------------------- */
/*******************************************************************************
* Copyright (C) 2015 Maxim Integrated Products, Inc., All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of Maxim Integrated
* Products, Inc. shall not be used except as stated in the Maxim Integrated
* Products, Inc. Branding Policy.
*
* The mere transfer of this software does not imply any licenses
* of trade secrets, proprietary technology, copyrights, patents,
* trademarks, maskwork rights, or any other form of intellectual
* property whatsoever. Maxim Integrated Products, Inc. retains all
* ownership rights.
*******************************************************************************
*/
#ifndef ALGORITHM_H_
#define ALGORITHM_H_
#include <stdint.h>
#define true 1
#define false 0
#define FS 100
#define BUFFER_SIZE (FS* 5)
#define HR_FIFO_SIZE 7
#define MA4_SIZE 4 // DO NOT CHANGE
#define HAMMING_SIZE 5// DO NOT CHANGE
#define min(x,y) ((x) < (y) ? (x) : (y))
const uint16_t auw_hamm[31]={ 41, 276, 512, 276, 41 }; //Hamm= long16(512* hamming(5)');
//uch_spo2_table is computed as -45.060*ratioAverage* ratioAverage + 30.354 *ratioAverage + 94.845 ;
const uint8_t uch_spo2_table[184]={ 95, 95, 95, 96, 96, 96, 97, 97, 97, 97, 97, 98, 98, 98, 98, 98, 99, 99, 99, 99,
99, 99, 99, 99, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
100, 100, 100, 100, 99, 99, 99, 99, 99, 99, 99, 99, 98, 98, 98, 98, 98, 98, 97, 97,
97, 97, 96, 96, 96, 96, 95, 95, 95, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91, 91,
90, 90, 89, 89, 89, 88, 88, 87, 87, 86, 86, 85, 85, 84, 84, 83, 82, 82, 81, 81,
80, 80, 79, 78, 78, 77, 76, 76, 75, 74, 74, 73, 72, 72, 71, 70, 69, 69, 68, 67,
66, 66, 65, 64, 63, 62, 62, 61, 60, 59, 58, 57, 56, 56, 55, 54, 53, 52, 51, 50,
49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 31, 30, 29,
28, 27, 26, 25, 23, 22, 21, 20, 19, 17, 16, 15, 14, 12, 11, 10, 9, 7, 6, 5,
3, 2, 1 } ;
static int32_t an_dx[ BUFFER_SIZE-MA4_SIZE]; // delta
static int32_t an_x[ BUFFER_SIZE]; //ir
static int32_t an_y[ BUFFER_SIZE]; //red
void maxim_heart_rate_and_oxygen_saturation(uint32_t *pun_ir_buffer , int32_t n_ir_buffer_length, uint32_t *pun_red_buffer , int32_t *pn_spo2, int8_t *pch_spo2_valid , int32_t *pn_heart_rate , int8_t *pch_hr_valid);
void maxim_find_peaks( int32_t *pn_locs, int32_t *pn_npks, int32_t *pn_x, int32_t n_size, int32_t n_min_height, int32_t n_min_distance, int32_t n_max_num );
void maxim_peaks_above_min_height( int32_t *pn_locs, int32_t *pn_npks, int32_t *pn_x, int32_t n_size, int32_t n_min_height );
void maxim_remove_close_peaks( int32_t *pn_locs, int32_t *pn_npks, int32_t *pn_x, int32_t n_min_distance );
void maxim_sort_ascend( int32_t *pn_x, int32_t n_size );
void maxim_sort_indices_descend( int32_t *pn_x, int32_t *pn_indx, int32_t n_size);
#endif /* ALGORITHM_H_ */

View File

@ -0,0 +1,25 @@
#ifndef _BLOOD_H
#define _BLOOD_H
#include "max30102.h"
#include "algorithm.h"
#include "math.h"
typedef enum
{
BLD_NORMAL, //正常
BLD_ERROR, //侦测错误
}BloodState;//血液状态
typedef struct
{
int heart; //心率数据
float SpO2; //血氧数据
}BloodData;
void blood_data_translate(void);
void blood_data_update(void);
void blood_Loop(void);
#endif

View File

@ -0,0 +1,42 @@
#ifndef MAX30102_H_
#define MAX30102_H_
#include <stdint.h>
#define MAX30102_SLAVE_ADDRESS 0x57
//register addresses
#define REG_INTR_STATUS_1 0x00
#define REG_INTR_STATUS_2 0x01
#define REG_INTR_ENABLE_1 0x02
#define REG_INTR_ENABLE_2 0x03
#define REG_FIFO_WR_PTR 0x04
#define REG_OVF_COUNTER 0x05
#define REG_FIFO_RD_PTR 0x06
#define REG_FIFO_DATA 0x07
#define REG_FIFO_CONFIG 0x08
#define REG_MODE_CONFIG 0x09
#define REG_SPO2_CONFIG 0x0A
#define REG_LED1_PA 0x0C
#define REG_LED2_PA 0x0D
#define REG_PILOT_PA 0x10
#define REG_MULTI_LED_CTRL1 0x11
#define REG_MULTI_LED_CTRL2 0x12
#define REG_TEMP_INTR 0x1F
#define REG_TEMP_FRAC 0x20
#define REG_TEMP_CONFIG 0x21
#define REG_PROX_INT_THRESH 0x30
#define REG_REV_ID 0xFE
#define REG_PART_ID 0xFF
void BoardInit(void);
uint8_t GetInit(void);
uint8_t maxim_max30102_reset();
uint8_t maxim_max30102_init();
uint8_t max30102_FIFO_ReadBytes(uint8_t Register_Address,uint8_t* Data);
uint8_t maxim_max30102_read_fifo(uint32_t *pun_red_led, uint32_t *pun_ir_led);
#endif /* MAX30102_H_ */

View File

@ -0,0 +1,46 @@
#ifndef MAX30102_H_
#define MAX30102_H_
#include <stdint.h>
#define MAX30102_SLAVE_ADDRESS 0x57
//register addresses
#define REG_INTR_STATUS_1 0x00
#define REG_INTR_STATUS_2 0x01
#define REG_INTR_ENABLE_1 0x02
#define REG_INTR_ENABLE_2 0x03
#define REG_FIFO_WR_PTR 0x04
#define REG_OVF_COUNTER 0x05
#define REG_FIFO_RD_PTR 0x06
#define REG_FIFO_DATA 0x07
#define REG_FIFO_CONFIG 0x08
#define REG_MODE_CONFIG 0x09
#define REG_SPO2_CONFIG 0x0A
#define REG_LED1_PA 0x0C
#define REG_LED2_PA 0x0D
#define REG_PILOT_PA 0x10
#define REG_MULTI_LED_CTRL1 0x11
#define REG_MULTI_LED_CTRL2 0x12
#define REG_TEMP_INTR 0x1F
#define REG_TEMP_FRAC 0x20
#define REG_TEMP_CONFIG 0x21
#define REG_PROX_INT_THRESH 0x30
#define REG_REV_ID 0xFE
#define REG_PART_ID 0xFF
extern uint16_t fifo_red;
extern uint16_t fifo_ir;
void BoardInit(void);
uint8_t GetInit(void);
uint8_t maxim_max30102_reset();
uint8_t maxim_max30102_init();
uint8_t max30102_FIFO_ReadBytes(uint8_t Register_Address,uint8_t* Data);
void max30102_read_fifo(void);
#endif /* MAX30102_H_ */

View File

@ -0,0 +1,248 @@
/**
******************************************************************************
* @file algorithm.c
* @author
* @version V1.0.0
* @date 2019-12-28
* @brief
******************************************************************************
*/
/*--Include-start-------------------------------------------------------------*/
#include "algorithm.h"
/*base value define-----------------------------------------------------------*/
#define XPI (3.1415926535897932384626433832795)
#define XENTRY (100)
#define XINCL (XPI/2/XENTRY)
#define PI 3.1415926535897932384626433832795028841971 //定义圆周率值
/*Global data space ----------------------------------------------------------*/
//正弦值对应表
static const double XSinTbl[] = {
0.00000000000000000 , 0.015707317311820675 , 0.031410759078128292 , 0.047106450709642665 , 0.062790519529313374 ,
0.078459095727844944 , 0.094108313318514325 , 0.10973431109104528 , 0.12533323356430426 , 0.14090123193758267 ,
0.15643446504023087 , 0.17192910027940955 , 0.18738131458572463 , 0.20278729535651249 , 0.21814324139654256 ,
0.23344536385590542 , 0.24868988716485479 , 0.26387304996537292 , 0.27899110603922928 , 0.29404032523230400 ,
0.30901699437494740 , 0.32391741819814940 , 0.33873792024529142 , 0.35347484377925714 , 0.36812455268467797 ,
0.38268343236508978 , 0.39714789063478062 , 0.41151435860510882 , 0.42577929156507272 , 0.43993916985591514 ,
0.45399049973954680 , 0.46792981426057340 , 0.48175367410171532 , 0.49545866843240760 , 0.50904141575037132 ,
0.52249856471594880 , 0.53582679497899666 , 0.54902281799813180 , 0.56208337785213058 , 0.57500525204327857 ,
0.58778525229247314 , 0.60042022532588402 , 0.61290705365297649 , 0.62524265633570519 , 0.63742398974868975 ,
0.64944804833018377 , 0.66131186532365183 , 0.67301251350977331 , 0.68454710592868873 , 0.69591279659231442 ,
0.70710678118654757 , 0.71812629776318881 , 0.72896862742141155 , 0.73963109497860968 , 0.75011106963045959 ,
0.76040596560003104 , 0.77051324277578925 , 0.78043040733832969 , 0.79015501237569041 , 0.79968465848709058 ,
0.80901699437494745 , 0.81814971742502351 , 0.82708057427456183 , 0.83580736136827027 , 0.84432792550201508 ,
0.85264016435409218 , 0.86074202700394364 , 0.86863151443819120 , 0.87630668004386369 , 0.88376563008869347 ,
0.89100652418836779 , 0.89802757576061565 , 0.90482705246601958 , 0.91140327663544529 , 0.91775462568398114 ,
0.92387953251128674 , 0.92977648588825146 , 0.93544403082986738 , 0.94088076895422557 , 0.94608535882754530 ,
0.95105651629515353 , 0.95579301479833012 , 0.96029368567694307 , 0.96455741845779808 , 0.96858316112863108 ,
0.97236992039767667 , 0.97591676193874743 , 0.97922281062176575 , 0.98228725072868872 , 0.98510932615477398 ,
0.98768834059513777 , 0.99002365771655754 , 0.99211470131447788 , 0.99396095545517971 , 0.99556196460308000 ,
0.99691733373312796 , 0.99802672842827156 , 0.99888987496197001 , 0.99950656036573160 , 0.99987663248166059 ,
1.00000000000000000 };
//向下取整
double my_floor(double x)
{
double y=x;
if( (*( ( (int *) &y)+1) & 0x80000000) != 0) //或者if(x<0)
return (float)((int)x)-1;
else
return (float)((int)x);
}
//求余运算
double my_fmod(double x, double y)
{
double temp, ret;
if (y == 0.0)
return 0.0;
temp = my_floor(x/y);
ret = x - temp * y;
if ((x < 0.0) != (y < 0.0))
ret = ret - y;
return ret;
}
//正弦函数
double XSin( double x )
{
int s = 0 , n;
double dx , sx , cx;
if( x < 0 )
s = 1 , x = -x;
x = my_fmod( x , 2 * XPI );
if( x > XPI )
s = !s , x -= XPI;
if( x > XPI / 2 )
x = XPI - x;
n = (int)( x / XINCL );
dx = x - n * XINCL;
if( dx > XINCL / 2 )
++n , dx -= XINCL;
sx = XSinTbl[n];
cx = XSinTbl[XENTRY-n];
x = sx + dx*cx - (dx*dx)*sx/2
- (dx*dx*dx)*cx/6
+ (dx*dx*dx*dx)*sx/24;
return s ? -x : x;
}
//余弦函数
double XCos( double x )
{
return XSin( x + XPI/2 );
}
//开平方
int qsqrt(int a)
{
uint32_t rem = 0, root = 0, divisor = 0;
uint16_t i;
for(i=0; i<16; i++)
{
root <<= 1;
rem = ((rem << 2) + (a>>30));
a <<= 2;
divisor = (root << 1) + 1;
if(divisor <= rem)
{
rem -= divisor;
root++;
}
}
return root;
}
/*********************************FFT*********************************
C函数
C语言函数
0FFT变换的自然顺序的
使使FFT_N的值即可实现点数的改变FFT_N的
2N次方0
FFT(s);
2010-2-20
Ver1.0
**********************************************************************/
/*******************************************************************
struct compx EE(struct compx b1,struct compx b2)
a,b
a和b的乘积
*******************************************************************/
struct compx EE(struct compx a,struct compx b)
{
struct compx c;
c.real=a.real*b.real-a.imag*b.imag;
c.imag=a.real*b.imag+a.imag*b.real;
return(c);
}
/*****************************************************************
void FFT(struct compx *xin,int N)
FFT
*xin复数结构体组的首地址指针struct型
*****************************************************************/
void FFT(struct compx *xin)
{
int f,m,nv2,nm1,i,k,l,j=0;
struct compx u,w,t;
nv2=FFT_N/2; //变址运算,即把自然顺序变成倒位序,采用雷德算法
nm1=FFT_N-1;
for(i=0;i<nm1;i++)
{
if(i<j) //如果i<j,即进行变址
{
t=xin[j];
xin[j]=xin[i];
xin[i]=t;
}
k=nv2; //求j的下一个倒位序
while(k<=j) //如果k<=j,表示j的最高位为1
{
j=j-k; //把最高位变成0
k=k/2; //k/2比较次高位依次类推逐个比较直到某个位为0
}
j=j+k; //把0改为1
}
{ //FFT运算核使用蝶形运算完成FFT运算
int le,lei,ip;
f=FFT_N;
for(l=1;(f=f/2)!=1;l++) //计算l的值即计算蝶形级数
;
for(m=1;m<=l;m++) // 控制蝶形结级数
{ //m表示第m级蝶形l为蝶形级总数l=log2N
le=2<<(m-1); //le蝶形结距离即第m级蝶形的蝶形结相距le点
lei=le/2; //同一蝶形结中参加运算的两点的距离
u.real=1.0; //u为蝶形结运算系数初始值为1
u.imag=0.0;
w.real=XCos(PI/lei); //w为系数商即当前系数与前一个系数的商
w.imag=-XSin(PI/lei);
for(j=0;j<=lei-1;j++) //控制计算不同种蝶形结,即计算系数不同的蝶形结
{
for(i=j;i<=FFT_N-1;i=i+le) //控制同一蝶形结运算,即计算系数相同蝶形结
{
ip=i+lei; //iip分别表示参加蝶形运算的两个节点
t=EE(xin[ip],u); //蝶形运算,详见公式
xin[ip].real=xin[i].real-t.real;
xin[ip].imag=xin[i].imag-t.imag;
xin[i].real=xin[i].real+t.real;
xin[i].imag=xin[i].imag+t.imag;
}
u=EE(u,w); //改变系数,进行下一个蝶形运算
}
}
}
}
//读取峰值
int find_max_num_index(struct compx *data,int count)
{
int i=START_INDEX;
int max_num_index = i;
//struct compx temp=data[i];
float temp = data[i].real;
for(i=START_INDEX;i<count;i++)
{
if(temp < data[i].real)
{
temp = data[i].real;
max_num_index = i;
}
}
//printf("max_num_index=%d\r\n",max_num_index);
return max_num_index;
}
//直流滤波器
int dc_filter(int input,DC_FilterData * df)
{
float new_w = input + df->w * df->a;
int16_t result = 5*(new_w - df->w);
df->w = new_w;
return result;
}
int bw_filter(int input,BW_FilterData * bw) {
bw->v0 = bw->v1;
// v1 = (3.04687470e-2 * input) + (0.9390625058 * v0);
bw->v1 = (1.241106190967544882e-2*input)+(0.97517787618064910582 * bw->v0);
return bw->v0 + bw->v1;
}

View File

@ -0,0 +1,363 @@
/** \file algorithm.cpp ******************************************************
*
* Project: MAXREFDES117#
* Filename: algorithm.cpp
* Description: This module calculates the heart rate/SpO2 level
*
*
* --------------------------------------------------------------------
*
* This code follows the following naming conventions:
*
* char ch_pmod_value
* char (array) s_pmod_s_string[16]
* float f_pmod_value
* int32_t n_pmod_value
* int32_t (array) an_pmod_value[16]
* int16_t w_pmod_value
* int16_t (array) aw_pmod_value[16]
* uint16_t uw_pmod_value
* uint16_t (array) auw_pmod_value[16]
* uint8_t uch_pmod_value
* uint8_t (array) auch_pmod_buffer[16]
* uint32_t un_pmod_value
* int32_t * pn_pmod_value
*
* ------------------------------------------------------------------------- */
/*******************************************************************************
* Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of Maxim Integrated
* Products, Inc. shall not be used except as stated in the Maxim Integrated
* Products, Inc. Branding Policy.
*
* The mere transfer of this software does not imply any licenses
* of trade secrets, proprietary technology, copyrights, patents,
* trademarks, maskwork rights, or any other form of intellectual
* property whatsoever. Maxim Integrated Products, Inc. retains all
* ownership rights.
*******************************************************************************
*/
#include "algorithm.h"
void maxim_heart_rate_and_oxygen_saturation(uint32_t *pun_ir_buffer, int32_t n_ir_buffer_length, uint32_t *pun_red_buffer, int32_t *pn_spo2, int8_t *pch_spo2_valid,
int32_t *pn_heart_rate, int8_t *pch_hr_valid)
/**
* \brief Calculate the heart rate and SpO2 level
* \par Details
* By detecting peaks of PPG cycle and corresponding AC/DC of red/infra-red signal, the ratio for the SPO2 is computed.
* Since this algorithm is aiming for Arm M0/M3. formaula for SPO2 did not achieve the accuracy due to register overflow.
* Thus, accurate SPO2 is precalculated and save longo uch_spo2_table[] per each ratio.
*
* \param[in] *pun_ir_buffer - IR sensor data buffer
* \param[in] n_ir_buffer_length - IR sensor data buffer length
* \param[in] *pun_red_buffer - Red sensor data buffer
* \param[out] *pn_spo2 - Calculated SpO2 value
* \param[out] *pch_spo2_valid - 1 if the calculated SpO2 value is valid
* \param[out] *pn_heart_rate - Calculated heart rate value
* \param[out] *pch_hr_valid - 1 if the calculated heart rate value is valid
*
* \retval None
*/
{
uint32_t un_ir_mean ,un_only_once ;
int32_t k ,n_i_ratio_count;
int32_t i, s, m, n_exact_ir_valley_locs_count ,n_middle_idx;
int32_t n_th1, n_npks,n_c_min;
int32_t an_ir_valley_locs[15] ;
int32_t an_exact_ir_valley_locs[15] ;
int32_t an_dx_peak_locs[15] ;
int32_t n_peak_interval_sum;
int32_t n_y_ac, n_x_ac;
int32_t n_spo2_calc;
int32_t n_y_dc_max, n_x_dc_max;
int32_t n_y_dc_max_idx, n_x_dc_max_idx;
int32_t an_ratio[5],n_ratio_average;
int32_t n_nume, n_denom ;
// remove DC of ir signal
un_ir_mean =0;
for (k=0 ; k<n_ir_buffer_length ; k++ ) un_ir_mean += pun_ir_buffer[k] ;
un_ir_mean =un_ir_mean/n_ir_buffer_length ;
for (k=0 ; k<n_ir_buffer_length ; k++ ) an_x[k] = pun_ir_buffer[k] - un_ir_mean ;
// 4 pt Moving Average
for(k=0; k< BUFFER_SIZE-MA4_SIZE; k++){
n_denom= ( an_x[k]+an_x[k+1]+ an_x[k+2]+ an_x[k+3]);
an_x[k]= n_denom/(int32_t)4;
}
// get difference of smoothed IR signal
for( k=0; k<BUFFER_SIZE-MA4_SIZE-1; k++)
an_dx[k]= (an_x[k+1]- an_x[k]);
// 2-pt Moving Average to an_dx
for(k=0; k< BUFFER_SIZE-MA4_SIZE-2; k++){
an_dx[k] = ( an_dx[k]+an_dx[k+1])/2 ;
}
// hamming window
// flip wave form so that we can detect valley with peak detector
for ( i=0 ; i<BUFFER_SIZE-HAMMING_SIZE-MA4_SIZE-2 ;i++){
s= 0;
for( k=i; k<i+ HAMMING_SIZE ;k++){
s -= an_dx[k] *auw_hamm[k-i] ;
}
an_dx[i]= s/ (int32_t)1146; // divide by sum of auw_hamm
}
n_th1=0; // threshold calculation
for ( k=0 ; k<BUFFER_SIZE-HAMMING_SIZE ;k++){
n_th1 += ((an_dx[k]>0)? an_dx[k] : ((int32_t)0-an_dx[k])) ;
}
n_th1= n_th1/ ( BUFFER_SIZE-HAMMING_SIZE);
// peak location is acutally index for sharpest location of raw signal since we flipped the signal
maxim_find_peaks( an_dx_peak_locs, &n_npks, an_dx, BUFFER_SIZE-HAMMING_SIZE, n_th1, 8, 5 );//peak_height, peak_distance, max_num_peaks
n_peak_interval_sum =0;
if (n_npks>=2){
for (k=1; k<n_npks; k++)
n_peak_interval_sum += (an_dx_peak_locs[k]-an_dx_peak_locs[k -1]);
n_peak_interval_sum=n_peak_interval_sum/(n_npks-1);
*pn_heart_rate=(int32_t)(6000/n_peak_interval_sum);// beats per minutes
*pch_hr_valid = 1;
}
else {
*pn_heart_rate = -999;
*pch_hr_valid = 0;
}
for ( k=0 ; k<n_npks ;k++)
an_ir_valley_locs[k]=an_dx_peak_locs[k]+HAMMING_SIZE/2;
// raw value : RED(=y) and IR(=X)
// we need to assess DC and AC value of ir and red PPG.
for (k=0 ; k<n_ir_buffer_length ; k++ ) {
an_x[k] = pun_ir_buffer[k] ;
an_y[k] = pun_red_buffer[k] ;
}
// find precise min near an_ir_valley_locs
n_exact_ir_valley_locs_count =0;
for(k=0 ; k<n_npks ;k++){
un_only_once =1;
m=an_ir_valley_locs[k];
n_c_min= 16777216;//2^24;
if (m+5 < BUFFER_SIZE-HAMMING_SIZE && m-5 >0){
for(i= m-5;i<m+5; i++)
if (an_x[i]<n_c_min){
if (un_only_once >0){
un_only_once =0;
}
n_c_min= an_x[i] ;
an_exact_ir_valley_locs[k]=i;
}
if (un_only_once ==0)
n_exact_ir_valley_locs_count ++ ;
}
}
if (n_exact_ir_valley_locs_count <2 ){
*pn_spo2 = -999 ; // do not use SPO2 since signal ratio is out of range
*pch_spo2_valid = 0;
return;
}
// 4 pt MA
for(k=0; k< BUFFER_SIZE-MA4_SIZE; k++){
an_x[k]=( an_x[k]+an_x[k+1]+ an_x[k+2]+ an_x[k+3])/(int32_t)4;
an_y[k]=( an_y[k]+an_y[k+1]+ an_y[k+2]+ an_y[k+3])/(int32_t)4;
}
//using an_exact_ir_valley_locs , find ir-red DC andir-red AC for SPO2 calibration ratio
//finding AC/DC maximum of raw ir * red between two valley locations
n_ratio_average =0;
n_i_ratio_count =0;
for(k=0; k< 5; k++) an_ratio[k]=0;
for (k=0; k< n_exact_ir_valley_locs_count; k++){
if (an_exact_ir_valley_locs[k] > BUFFER_SIZE ){
*pn_spo2 = -999 ; // do not use SPO2 since valley loc is out of range
*pch_spo2_valid = 0;
return;
}
}
// find max between two valley locations
// and use ratio betwen AC compoent of Ir & Red and DC compoent of Ir & Red for SPO2
for (k=0; k< n_exact_ir_valley_locs_count-1; k++){
n_y_dc_max= -16777216 ;
n_x_dc_max= - 16777216;
if (an_exact_ir_valley_locs[k+1]-an_exact_ir_valley_locs[k] >10){
for (i=an_exact_ir_valley_locs[k]; i< an_exact_ir_valley_locs[k+1]; i++){
if (an_x[i]> n_x_dc_max) {n_x_dc_max =an_x[i];n_x_dc_max_idx =i; }
if (an_y[i]> n_y_dc_max) {n_y_dc_max =an_y[i];n_y_dc_max_idx=i;}
}
n_y_ac= (an_y[an_exact_ir_valley_locs[k+1]] - an_y[an_exact_ir_valley_locs[k] ] )*(n_y_dc_max_idx -an_exact_ir_valley_locs[k]); //red
n_y_ac= an_y[an_exact_ir_valley_locs[k]] + n_y_ac/ (an_exact_ir_valley_locs[k+1] - an_exact_ir_valley_locs[k]) ;
n_y_ac= an_y[n_y_dc_max_idx] - n_y_ac; // subracting linear DC compoenents from raw
n_x_ac= (an_x[an_exact_ir_valley_locs[k+1]] - an_x[an_exact_ir_valley_locs[k] ] )*(n_x_dc_max_idx -an_exact_ir_valley_locs[k]); // ir
n_x_ac= an_x[an_exact_ir_valley_locs[k]] + n_x_ac/ (an_exact_ir_valley_locs[k+1] - an_exact_ir_valley_locs[k]);
n_x_ac= an_x[n_y_dc_max_idx] - n_x_ac; // subracting linear DC compoenents from raw
n_nume=( n_y_ac *n_x_dc_max)>>7 ; //prepare X100 to preserve floating value
n_denom= ( n_x_ac *n_y_dc_max)>>7;
if (n_denom>0 && n_i_ratio_count <5 && n_nume != 0)
{
an_ratio[n_i_ratio_count]= (n_nume*20)/n_denom ; //formular is ( n_y_ac *n_x_dc_max) / ( n_x_ac *n_y_dc_max) ;
n_i_ratio_count++;
}
}
}
maxim_sort_ascend(an_ratio, n_i_ratio_count);
n_middle_idx= n_i_ratio_count/2;
if (n_middle_idx >1)
n_ratio_average =( an_ratio[n_middle_idx-1] +an_ratio[n_middle_idx])/2; // use median
else
n_ratio_average = an_ratio[n_middle_idx ];
if( n_ratio_average>2 && n_ratio_average <184){
n_spo2_calc= uch_spo2_table[n_ratio_average] ;
*pn_spo2 = n_spo2_calc ;
*pch_spo2_valid = 1;// float_SPO2 = -45.060*n_ratio_average* n_ratio_average/10000 + 30.354 *n_ratio_average/100 + 94.845 ; // for comparison with table
}
else{
*pn_spo2 = -999 ; // do not use SPO2 since signal ratio is out of range
*pch_spo2_valid = 0;
}
}
void maxim_find_peaks(int32_t *pn_locs, int32_t *pn_npks, int32_t *pn_x, int32_t n_size, int32_t n_min_height, int32_t n_min_distance, int32_t n_max_num)
/**
* \brief Find peaks
* \par Details
* Find at most MAX_NUM peaks above MIN_HEIGHT separated by at least MIN_DISTANCE
*
* \retval None
*/
{
maxim_peaks_above_min_height( pn_locs, pn_npks, pn_x, n_size, n_min_height );
maxim_remove_close_peaks( pn_locs, pn_npks, pn_x, n_min_distance );
*pn_npks = min( *pn_npks, n_max_num );
}
void maxim_peaks_above_min_height(int32_t *pn_locs, int32_t *pn_npks, int32_t *pn_x, int32_t n_size, int32_t n_min_height)
/**
* \brief Find peaks above n_min_height
* \par Details
* Find all peaks above MIN_HEIGHT
*
* \retval None
*/
{
int32_t i = 1, n_width;
*pn_npks = 0;
while (i < n_size-1){
if (pn_x[i] > n_min_height && pn_x[i] > pn_x[i-1]){ // find left edge of potential peaks
n_width = 1;
while (i+n_width < n_size && pn_x[i] == pn_x[i+n_width]) // find flat peaks
n_width++;
if (pn_x[i] > pn_x[i+n_width] && (*pn_npks) < 15 ){ // find right edge of peaks
pn_locs[(*pn_npks)++] = i;
// for flat peaks, peak location is left edge
i += n_width+1;
}
else
i += n_width;
}
else
i++;
}
}
void maxim_remove_close_peaks(int32_t *pn_locs, int32_t *pn_npks, int32_t *pn_x, int32_t n_min_distance)
/**
* \brief Remove peaks
* \par Details
* Remove peaks separated by less than MIN_DISTANCE
*
* \retval None
*/
{
int32_t i, j, n_old_npks, n_dist;
/* Order peaks from large to small */
maxim_sort_indices_descend( pn_x, pn_locs, *pn_npks );
for ( i = -1; i < *pn_npks; i++ ){
n_old_npks = *pn_npks;
*pn_npks = i+1;
for ( j = i+1; j < n_old_npks; j++ ){
n_dist = pn_locs[j] - ( i == -1 ? -1 : pn_locs[i] ); // lag-zero peak of autocorr is at index -1
if ( n_dist > n_min_distance || n_dist < -n_min_distance )
pn_locs[(*pn_npks)++] = pn_locs[j];
}
}
// Resort indices longo ascending order
maxim_sort_ascend( pn_locs, *pn_npks );
}
void maxim_sort_ascend(int32_t *pn_x,int32_t n_size)
/**
* \brief Sort array
* \par Details
* Sort array in ascending order (insertion sort algorithm)
*
* \retval None
*/
{
int32_t i, j, n_temp;
for (i = 1; i < n_size; i++) {
n_temp = pn_x[i];
for (j = i; j > 0 && n_temp < pn_x[j-1]; j--)
pn_x[j] = pn_x[j-1];
pn_x[j] = n_temp;
}
}
void maxim_sort_indices_descend(int32_t *pn_x, int32_t *pn_indx, int32_t n_size)
/**
* \brief Sort indices
* \par Details
* Sort indices according to descending order (insertion sort algorithm)
*
* \retval None
*/
{
int32_t i, j, n_temp;
for (i = 1; i < n_size; i++) {
n_temp = pn_indx[i];
for (j = i; j > 0 && pn_x[n_temp] > pn_x[pn_indx[j-1]]; j--)
pn_indx[j] = pn_indx[j-1];
pn_indx[j] = n_temp;
}
}

View File

@ -0,0 +1,246 @@
#include "blood.h"
uint16_t g_fft_index = 0; //fft输入输出下标
struct compx s1[FFT_N+16]; //FFT输入和输出从S[1]开始存放,根据大小自己定义
struct compx s2[FFT_N+16]; //FFT输入和输出从S[1]开始存放,根据大小自己定义
struct
{
float Hp ; //血红蛋白
float HpO2; //氧合血红蛋白
}g_BloodWave;//血液波形数据
BloodData g_blooddata = {0}; //血液数据存储
#define CORRECTED_VALUE 47 //标定血液氧气含量
#define asuint(f) ((union{float _f; uint32_t _i;}){f})._i
#define asfloat(i) ((union{uint32_t _i; float _f;}){i})._f
#define GET_FLOAT_WORD(w,d) \
do { \
(w) = asuint(d); \
} while (0)
#define SET_FLOAT_WORD(d,w) \
do { \
(d) = asfloat(w); \
} while (0)
static const float tiny = 1.0e-30;
float sqrtf(float x)
{
float z;
int32_t sign = (int)0x80000000;
int32_t ix,s,q,m,t,i;
uint32_t r;
GET_FLOAT_WORD(ix, x);
/* take care of Inf and NaN */
if ((ix&0x7f800000) == 0x7f800000)
return x*x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf, sqrt(-inf)=sNaN */
/* take care of zero */
if (ix <= 0) {
if ((ix&~sign) == 0)
return x; /* sqrt(+-0) = +-0 */
if (ix < 0)
return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
}
/* normalize x */
m = ix>>23;
if (m == 0) { /* subnormal x */
for (i = 0; (ix&0x00800000) == 0; i++)
ix<<=1;
m -= i - 1;
}
m -= 127; /* unbias exponent */
ix = (ix&0x007fffff)|0x00800000;
if (m&1) /* odd m, double x to make it even */
ix += ix;
m >>= 1; /* m = [m/2] */
/* generate sqrt(x) bit by bit */
ix += ix;
q = s = 0; /* q = sqrt(x) */
r = 0x01000000; /* r = moving bit from right to left */
while (r != 0) {
t = s + r;
if (t <= ix) {
s = t+r;
ix -= t;
q += r;
}
ix += ix;
r >>= 1;
}
/* use floating add to find out rounding direction */
if (ix != 0) {
z = 1.0f - tiny; /* raise inexact flag */
if (z >= 1.0f) {
z = 1.0f + tiny;
if (z > 1.0f)
q += 2;
else
q += q & 1;
}
}
ix = (q>>1) + 0x3f000000;
SET_FLOAT_WORD(z, ix + ((uint32_t)m << 23));
return z;
}
/*funcation start ------------------------------------------------------------*/
//血液检测信息更新
void blood_data_update(void)
{
//标志位被使能时 读取FIFO
g_fft_index=0;
while(g_fft_index < FFT_N)
{
while(GetInit()==0)
{
//读取FIFO
max30102_read_fifo(); //read from MAX30102 FIFO2
//将数据写入fft输入并清除输出
if(g_fft_index < FFT_N)
{
//将数据写入fft输入并清除输出
s1[g_fft_index].real = fifo_red;
s1[g_fft_index].imag= 0;
s2[g_fft_index].real = fifo_ir;
s2[g_fft_index].imag= 0;
g_fft_index++;
}
}
}
}
//血液信息转换
void blood_data_translate(void)
{
float n_denom;
uint16_t i;
//直流滤波
float dc_red =0;
float dc_ir =0;
float ac_red =0;
float ac_ir =0;
for (i=0 ; i<FFT_N ; i++ )
{
dc_red += s1[i].real ;
dc_ir += s2[i].real ;
}
dc_red =dc_red/FFT_N ;
dc_ir =dc_ir/FFT_N ;
for (i=0 ; i<FFT_N ; i++ )
{
s1[i].real = s1[i].real - dc_red ;
s2[i].real = s2[i].real - dc_ir ;
}
//移动平均滤波
printf("***********8 pt Moving Average red******************************************************\r\n");
for(i = 1;i < FFT_N-1;i++)
{
n_denom= ( s1[i-1].real + 2*s1[i].real + s1[i+1].real);
s1[i].real= n_denom/4.00;
n_denom= ( s2[i-1].real + 2*s2[i].real + s2[i+1].real);
s2[i].real= n_denom/4.00;
}
//八点平均滤波
for(i = 0;i < FFT_N-8;i++)
{
n_denom= ( s1[i].real+s1[i+1].real+ s1[i+2].real+ s1[i+3].real+ s1[i+4].real+ s1[i+5].real+ s1[i+6].real+ s1[i+7].real);
s1[i].real= n_denom/8.00;
n_denom= ( s2[i].real+s2[i+1].real+ s2[i+2].real+ s2[i+3].real+ s2[i+4].real+ s2[i+5].real+ s2[i+6].real+ s2[i+7].real);
s2[i].real= n_denom/8.00;
printf("%f\r\n",s1[i].real);
}
printf("************8 pt Moving Average ir*************************************************************\r\n");
for(i = 0;i < FFT_N;i++)
{
printf("%f\r\n",s2[i].real);
}
printf("**************************************************************************************************\r\n");
//开始变换显示
g_fft_index = 0;
//快速傅里叶变换
FFT(s1);
FFT(s2);
//解平方
printf("开始FFT算法****************************************************************************************************\r\n");
for(i = 0;i < FFT_N;i++)
{
s1[i].real=sqrtf(s1[i].real*s1[i].real+s1[i].imag*s1[i].imag);
s1[i].real=sqrtf(s2[i].real*s2[i].real+s2[i].imag*s2[i].imag);
}
//计算交流分量
for (i=1 ; i<FFT_N ; i++ )
{
ac_red += s1[i].real ;
ac_ir += s2[i].real ;
}
for(i = 0;i < FFT_N/2;i++)
{
printf("%f\r\n",s1[i].real);
}
printf("****************************************************************************************\r\n");
for(i = 0;i < FFT_N/2;i++)
{
printf("%f\r\n",s2[i].real);
}
printf("结束FFT算法***************************************************************************************************************\r\n");
//读取峰值点的横坐标 结果的物理意义为
int s1_max_index = find_max_num_index(s1, 30);
int s2_max_index = find_max_num_index(s2, 30);
printf("%d\r\n",s1_max_index);
printf("%d\r\n",s2_max_index);
//检查HbO2和Hb的变化频率是否一致
float Heart_Rate = 60.00 * ((100.0 * s1_max_index )/ 512.00);
g_blooddata.heart = Heart_Rate;
float R = (ac_ir*dc_red)/(ac_red*dc_ir);
float sp02_num =-45.060*R*R+ 30.354 *R + 94.845;
g_blooddata.SpO2 = sp02_num;
}
void blood_Loop(void)
{
//血液信息获取
blood_data_update();
//血液信息转换
blood_data_translate();
//显示血液状态信息
// OLED_Printf_EN(2,0,"heart:%3d/min ",g_blooddata.heart);
g_blooddata.SpO2 = (g_blooddata.SpO2 > 99.99) ? 99.99:g_blooddata.SpO2;
// OLED_Printf_EN(4,0,"SpO2:%2.2f%% ",g_blooddata.SpO2);
printf("指令心率%3d",g_blooddata.heart);
osDelay(10);
printf("指令血氧%0.2f",g_blooddata.SpO2);
//tft显示刷新
//LED 蜂鸣器信息更新
}

View File

@ -0,0 +1,237 @@
#include "max30102.h"
#include "iot_errno.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#include "iot_i2c.h"
#include "iot_i2c_ex.h"
#include <stdio.h>
#define WIFI_IOT_IO_FUNC_GPIO_0_I2C1_SDA 6
#define WIFI_IOT_IO_FUNC_GPIO_1_I2C1_SCL 6
#define WIFI_IOT_I2C_IDX_1 1
#define WIFI_IOT_IO_NAME_GPIO_7 7
#define WIFI_IOT_IO_NAME_GPIO_8 8
#define WIFI_IOT_IO_NAME_GPIO_0 0
#define WIFI_IOT_IO_NAME_GPIO_1 1
#define MAX30102_INIT_GPIO 7
/***************************************************************
* : GpioInit
* : GPIO初始化
* :
* :
***************************************************************/
void BoardInit(void)
{
// IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_8);
// IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_8, WIFI_IOT_IO_FUNC_GPIO_8_GPIO);
// IoTGpioSetDir(WIFI_IOT_IO_NAME_GPIO_8, IOT_GPIO_DIR_OUT); // 设置GPIO_8为输出模式
IoTGpioInit(MAX30102_INIT_GPIO);
IoTGpioSetFunc(MAX30102_INIT_GPIO, IOT_GPIO_FUNC_GPIO_7_GPIO);
IoTGpioSetDir(MAX30102_INIT_GPIO, IOT_GPIO_DIR_IN); // 设置GPIO_7为输出模式
IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_0);
IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_0, WIFI_IOT_IO_FUNC_GPIO_0_I2C1_SDA); // GPIO_0复用为I2C1_SDA
IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_1);
IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_1, WIFI_IOT_IO_FUNC_GPIO_1_I2C1_SCL); // GPIO_1复用为I2C1_SCL
IoTI2cInit(WIFI_IOT_I2C_IDX_1, 400000); /* baudrate: 400kbps */
}
uint8_t GetInit(void)
{
IotGpioValue temp = {0};
IoTGpioGetInputVal(MAX30102_INIT_GPIO,&temp);
return temp;
}
/**
* \brief Write a value to a MAX30102 register
* \par Details
* This function writes a value to a MAX30102 register
*
* \param[in] uch_addr - register address
* \param[in] uch_data - register data
*
* \retval true on success
*/
static int maxim_max30102_write_reg(uint8_t uch_addr, uint8_t uch_data)
{
uint32_t ret;
uint8_t send_data[2] = {uch_addr, uch_data};
ret = IoTI2cWrite(WIFI_IOT_I2C_IDX_1, (MAX30102_SLAVE_ADDRESS << 1) | 0x00, send_data, 2);
if (ret != 0) {
printf("===== Error: I2C write ret = 0x%x! =====\r\n", ret);
return -1;
}
return 0;
}
/**
* \brief Read a MAX30102 register
* \par Details
* This function reads a MAX30102 register
*
* \param[in] uch_addr - register address
* \param[out] puch_data - pointer that stores the register data
*
* \retval true on success
*/
uint8_t maxim_max30102_read_reg(uint8_t uch_addr, uint8_t *puch_data)
{
uint32_t ret = 0;
IotI2cData max30102_i2c_data = {0};
uint8_t buffer[1] = {uch_addr};
max30102_i2c_data.sendBuf = buffer;
max30102_i2c_data.sendLen = 1;
max30102_i2c_data.receiveBuf = puch_data;
max30102_i2c_data.receiveLen = 1;
ret = IoTI2cWriteread(WIFI_IOT_I2C_IDX_1, (MAX30102_SLAVE_ADDRESS << 1) | 0x00, &max30102_i2c_data);
if (ret != 0) {
printf("===== Error: I2C writeread ret = 0x%x! =====\r\n", ret);
return -1;
}
return 0;
}
uint8_t maxim_max30102_init()
{
if(maxim_max30102_write_reg(REG_INTR_ENABLE_1,0xc0)!=IOT_SUCCESS) // INTR setting
return 0;
if(maxim_max30102_write_reg(REG_INTR_ENABLE_2,0x00)!=IOT_SUCCESS)
return 0;
if(maxim_max30102_write_reg(REG_FIFO_WR_PTR,0x00)!=IOT_SUCCESS) //FIFO_WR_PTR[4:0]
return 0;
if(maxim_max30102_write_reg(REG_OVF_COUNTER,0x00)!=IOT_SUCCESS) //OVF_COUNTER[4:0]
return 0;
if(maxim_max30102_write_reg(REG_FIFO_RD_PTR,0x00)!=IOT_SUCCESS) //FIFO_RD_PTR[4:0]
return 0;
if(maxim_max30102_write_reg(REG_FIFO_CONFIG,0x0f)!=IOT_SUCCESS) //sample avg = 1, fifo rollover=false, fifo almost full = 17
return 0;
if(maxim_max30102_write_reg(REG_MODE_CONFIG,0x03)!=IOT_SUCCESS) //0x02 for Red only, 0x03 for SpO2 mode 0x07 multimode LED
return 0;
if(maxim_max30102_write_reg(REG_SPO2_CONFIG,0x27)!=IOT_SUCCESS) // SPO2_ADC range = 4096nA, SPO2 sample rate (100 Hz), LED pulseWidth (400uS)
return 0;
if(maxim_max30102_write_reg(REG_LED1_PA,0x32)!=IOT_SUCCESS) //Choose value for ~ 7mA for LED1
return 0;
if(maxim_max30102_write_reg(REG_LED2_PA,0x32)!=IOT_SUCCESS) // Choose value for ~ 7mA for LED2
return 0;
if(maxim_max30102_write_reg(REG_PILOT_PA,0x7f)!=IOT_SUCCESS) // Choose value for ~ 25mA for Pilot LED
return 0;
return 1;
}
/**
* \brief Reset the MAX30102
* \par Details
* This function resets the MAX30102
*
* \param None
*
* \retval true on success
*/
uint8_t maxim_max30102_reset()
{
if(maxim_max30102_write_reg(REG_MODE_CONFIG,0x40)!=IOT_SUCCESS)
return 0;
else
return 1;
}
/**
* \brief Read a set of samples from the MAX30102 FIFO register
* \par Details
* This function reads a set of samples from the MAX30102 FIFO register
*
* \param[out] *pun_red_led - pointer that stores the red LED reading data
* \param[out] *pun_ir_led - pointer that stores the IR LED reading data
*
* \retval true on success
*/
uint8_t max30102_FIFO_ReadBytes(uint8_t Register_Address,uint8_t* Data)
{
uint32_t un_temp;
unsigned char uch_temp;
//read and clear status register
maxim_max30102_read_reg(REG_INTR_STATUS_1, &uch_temp);
maxim_max30102_read_reg(REG_INTR_STATUS_2, &uch_temp);
// ach_i2c_data[0]=REG_FIFO_DATA;
uint32_t ret = 0;
IotI2cData max30102_i2c_data = {0};
uint8_t buffer[1] = {REG_FIFO_DATA};
max30102_i2c_data.sendBuf = buffer;
max30102_i2c_data.sendLen = 1;
max30102_i2c_data.receiveBuf = Data;
max30102_i2c_data.receiveLen = 6;
ret = IoTI2cWriteread(WIFI_IOT_I2C_IDX_1, (MAX30102_SLAVE_ADDRESS << 1) | 0x00, &max30102_i2c_data);
if (ret != 0) {
printf("===== Error: I2C writeread ret = 0x%x! =====\r\n", ret);
return -1;
}
return 0;
}
/**
* \brief Read a set of samples from the MAX30102 FIFO register
* \par Details
* This function reads a set of samples from the MAX30102 FIFO register
*
* \param[out] *pun_red_led - pointer that stores the red LED reading data
* \param[out] *pun_ir_led - pointer that stores the IR LED reading data
*
* \retval true on success
*/
uint8_t maxim_max30102_read_fifo(uint32_t *pun_red_led, uint32_t *pun_ir_led)
{
uint32_t un_temp;
unsigned char uch_temp;
*pun_red_led=0;
*pun_ir_led=0;
uint8_t ach_i2c_data[6];
//read and clear status register
maxim_max30102_read_reg(REG_INTR_STATUS_1, &uch_temp);
maxim_max30102_read_reg(REG_INTR_STATUS_2, &uch_temp);
// ach_i2c_data[0]=REG_FIFO_DATA;
uint32_t ret = 0;
IotI2cData max30102_i2c_data = {0};
uint8_t buffer[1] = {REG_FIFO_DATA};
max30102_i2c_data.sendBuf = buffer;
max30102_i2c_data.sendLen = 1;
max30102_i2c_data.receiveBuf = ach_i2c_data;
max30102_i2c_data.receiveLen = 6;
ret = IoTI2cWriteread(WIFI_IOT_I2C_IDX_1, (MAX30102_SLAVE_ADDRESS << 1) | 0x00, &max30102_i2c_data);
if (ret != 0) {
printf("===== Error: I2C writeread ret = 0x%x! =====\r\n", ret);
return -1;
}
un_temp=(unsigned char) ach_i2c_data[0];
un_temp<<=16;
*pun_red_led+=un_temp;
un_temp=(unsigned char) ach_i2c_data[1];
un_temp<<=8;
*pun_red_led+=un_temp;
un_temp=(unsigned char) ach_i2c_data[2];
*pun_red_led+=un_temp;
un_temp=(unsigned char) ach_i2c_data[3];
un_temp<<=16;
*pun_ir_led+=un_temp;
un_temp=(unsigned char) ach_i2c_data[4];
un_temp<<=8;
*pun_ir_led+=un_temp;
un_temp=(unsigned char) ach_i2c_data[5];
*pun_ir_led+=un_temp;
*pun_red_led&=0x03FFFF; //Mask MSB [23:18]
*pun_ir_led&=0x03FFFF; //Mask MSB [23:18]
return 1;
}

View File

@ -0,0 +1,249 @@
#include "max30102.h"
#include "iot_errno.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#include "iot_i2c.h"
#include "iot_i2c_ex.h"
#include <stdio.h>
#define WIFI_IOT_IO_FUNC_GPIO_0_I2C1_SDA 6
#define WIFI_IOT_IO_FUNC_GPIO_1_I2C1_SCL 6
#define WIFI_IOT_I2C_IDX_1 1
#define WIFI_IOT_IO_NAME_GPIO_7 7
#define WIFI_IOT_IO_NAME_GPIO_8 8
#define WIFI_IOT_IO_NAME_GPIO_0 0
#define WIFI_IOT_IO_NAME_GPIO_1 1
#define MAX30102_INIT_GPIO 7
/***************************************************************
* : GpioInit
* : GPIO初始化
* :
* :
***************************************************************/
void BoardInit(void)
{
// IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_8);
// IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_8, WIFI_IOT_IO_FUNC_GPIO_8_GPIO);
// IoTGpioSetDir(WIFI_IOT_IO_NAME_GPIO_8, IOT_GPIO_DIR_OUT); // 设置GPIO_8为输出模式
IoTGpioInit(MAX30102_INIT_GPIO);
IoTGpioSetFunc(MAX30102_INIT_GPIO, IOT_GPIO_FUNC_GPIO_7_GPIO);
IoTGpioSetDir(MAX30102_INIT_GPIO, IOT_GPIO_DIR_IN); // 设置GPIO_7为输出模式
IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_0);
IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_0, WIFI_IOT_IO_FUNC_GPIO_0_I2C1_SDA); // GPIO_0复用为I2C1_SDA
IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_1);
IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_1, WIFI_IOT_IO_FUNC_GPIO_1_I2C1_SCL); // GPIO_1复用为I2C1_SCL
IoTI2cInit(WIFI_IOT_I2C_IDX_1, 400000); /* baudrate: 400kbps */
}
uint8_t GetInit(void)
{
IotGpioValue temp = {0};
IoTGpioGetInputVal(MAX30102_INIT_GPIO,&temp);
return temp;
}
/**
* \brief Write a value to a MAX30102 register
* \par Details
* This function writes a value to a MAX30102 register
*
* \param[in] uch_addr - register address
* \param[in] uch_data - register data
*
* \retval true on success
*/
static int maxim_max30102_write_reg(uint8_t uch_addr, uint8_t uch_data)
{
uint32_t ret;
uint8_t send_data[2] = {uch_addr, uch_data};
ret = IoTI2cWrite(WIFI_IOT_I2C_IDX_1, (MAX30102_SLAVE_ADDRESS << 1) | 0x00, send_data, 2);
if (ret != 0) {
printf("===== Error: I2C write ret = 0x%x! =====\r\n", ret);
return -1;
}
return 0;
}
/**
* \brief Read a MAX30102 register
* \par Details
* This function reads a MAX30102 register
*
* \param[in] uch_addr - register address
* \param[out] puch_data - pointer that stores the register data
*
* \retval true on success
*/
uint8_t maxim_max30102_read_reg(uint8_t uch_addr, uint8_t *puch_data)
{
uint32_t ret = 0;
IotI2cData max30102_i2c_data = {0};
uint8_t buffer[1] = {uch_addr};
max30102_i2c_data.sendBuf = buffer;
max30102_i2c_data.sendLen = 1;
max30102_i2c_data.receiveBuf = puch_data;
max30102_i2c_data.receiveLen = 1;
ret = IoTI2cWriteread(WIFI_IOT_I2C_IDX_1, (MAX30102_SLAVE_ADDRESS << 1) | 0x00, &max30102_i2c_data);
if (ret != 0) {
printf("===== Error: I2C writeread ret = 0x%x! =====\r\n", ret);
return -1;
}
return 0;
}
uint8_t maxim_max30102_init()
{
if(maxim_max30102_write_reg(REG_INTR_ENABLE_1,0xc0)!=IOT_SUCCESS) // INTR setting
return 0;
if(maxim_max30102_write_reg(REG_INTR_ENABLE_2,0x00)!=IOT_SUCCESS)
return 0;
if(maxim_max30102_write_reg(REG_FIFO_WR_PTR,0x00)!=IOT_SUCCESS) //FIFO_WR_PTR[4:0]
return 0;
if(maxim_max30102_write_reg(REG_OVF_COUNTER,0x00)!=IOT_SUCCESS) //OVF_COUNTER[4:0]
return 0;
if(maxim_max30102_write_reg(REG_FIFO_RD_PTR,0x00)!=IOT_SUCCESS) //FIFO_RD_PTR[4:0]
return 0;
if(maxim_max30102_write_reg(REG_FIFO_CONFIG,0x0f)!=IOT_SUCCESS) //sample avg = 1, fifo rollover=false, fifo almost full = 17
return 0;
if(maxim_max30102_write_reg(REG_MODE_CONFIG,0x03)!=IOT_SUCCESS) //0x02 for Red only, 0x03 for SpO2 mode 0x07 multimode LED
return 0;
if(maxim_max30102_write_reg(REG_SPO2_CONFIG,0x27)!=IOT_SUCCESS) // SPO2_ADC range = 4096nA, SPO2 sample rate (100 Hz), LED pulseWidth (400uS)
return 0;
if(maxim_max30102_write_reg(REG_LED1_PA,0x32)!=IOT_SUCCESS) //Choose value for ~ 7mA for LED1
return 0;
if(maxim_max30102_write_reg(REG_LED2_PA,0x32)!=IOT_SUCCESS) // Choose value for ~ 7mA for LED2
return 0;
if(maxim_max30102_write_reg(REG_PILOT_PA,0x7f)!=IOT_SUCCESS) // Choose value for ~ 25mA for Pilot LED
return 0;
return 1;
}
/**
* \brief Reset the MAX30102
* \par Details
* This function resets the MAX30102
*
* \param None
*
* \retval true on success
*/
uint8_t maxim_max30102_reset()
{
if(maxim_max30102_write_reg(REG_MODE_CONFIG,0x40)!=IOT_SUCCESS)
return 0;
else
return 1;
}
/**
* \brief Read a set of samples from the MAX30102 FIFO register
* \par Details
* This function reads a set of samples from the MAX30102 FIFO register
*
* \param[out] *pun_red_led - pointer that stores the red LED reading data
* \param[out] *pun_ir_led - pointer that stores the IR LED reading data
*
* \retval true on success
*/
uint8_t max30102_FIFO_ReadBytes(uint8_t Register_Address,uint8_t* Data)
{
uint32_t un_temp;
unsigned char uch_temp;
//read and clear status register
maxim_max30102_read_reg(REG_INTR_STATUS_1, &uch_temp);
maxim_max30102_read_reg(REG_INTR_STATUS_2, &uch_temp);
// ach_i2c_data[0]=REG_FIFO_DATA;
uint32_t ret = 0;
IotI2cData max30102_i2c_data = {0};
uint8_t buffer[1] = {REG_FIFO_DATA};
max30102_i2c_data.sendBuf = buffer;
max30102_i2c_data.sendLen = 1;
max30102_i2c_data.receiveBuf = Data;
max30102_i2c_data.receiveLen = 6;
ret = IoTI2cWriteread(WIFI_IOT_I2C_IDX_1, (MAX30102_SLAVE_ADDRESS << 1) | 0x00, &max30102_i2c_data);
if (ret != 0) {
printf("===== Error: I2C writeread ret = 0x%x! =====\r\n", ret);
return -1;
}
return 0;
}
uint16_t fifo_red;
uint16_t fifo_ir;
/**
* \brief Read a set of samples from the MAX30102 FIFO register
* \par Details
* This function reads a set of samples from the MAX30102 FIFO register
*
* \param[out] *pun_red_led - pointer that stores the red LED reading data
* \param[out] *pun_ir_led - pointer that stores the IR LED reading data
*
* \retval true on success
*/
void max30102_read_fifo(void)
{
uint32_t un_temp;
unsigned char uch_temp;
fifo_red=0;
fifo_ir=0;
uint8_t ach_i2c_data[6];
//read and clear status register
maxim_max30102_read_reg(REG_INTR_STATUS_1, &uch_temp);
maxim_max30102_read_reg(REG_INTR_STATUS_2, &uch_temp);
// ach_i2c_data[0]=REG_FIFO_DATA;
uint32_t ret = 0;
IotI2cData max30102_i2c_data = {0};
uint8_t buffer[1] = {REG_FIFO_DATA};
max30102_i2c_data.sendBuf = buffer;
max30102_i2c_data.sendLen = 1;
max30102_i2c_data.receiveBuf = ach_i2c_data;
max30102_i2c_data.receiveLen = 6;
ret = IoTI2cWriteread(WIFI_IOT_I2C_IDX_1, (MAX30102_SLAVE_ADDRESS << 1) | 0x00, &max30102_i2c_data);
if (ret != 0) {
printf("===== Error: I2C writeread ret = 0x%x! =====\r\n", ret);
return -1;
}
un_temp=(unsigned char) ach_i2c_data[0];
un_temp<<=14;
fifo_red+=un_temp;
un_temp=(unsigned char) ach_i2c_data[1];
un_temp<<=8;
fifo_red+=un_temp;
un_temp=(unsigned char) ach_i2c_data[2];
un_temp>>=2;
fifo_red+=un_temp;
un_temp=(unsigned char) ach_i2c_data[3];
un_temp<<=16;
fifo_ir+=un_temp;
un_temp=(unsigned char) ach_i2c_data[4];
un_temp<<=8;
fifo_ir+=un_temp;
un_temp=(unsigned char) ach_i2c_data[5];
un_temp>>=2;
fifo_ir+=un_temp;
if(fifo_ir<=10000)
{
fifo_ir=0;
}
if(fifo_red<=10000)
{
fifo_red=0;
}
return 1;
}

View File

@ -0,0 +1,71 @@
/*
* Copyright (c) 2020  Jinan Bosai Network Technology Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "noise.h"
#include "cmsis_os2.h"
#include "ohos_init.h"
#define TASK_STACK_SIZE 1024 * 8
#define TASK_PRIO 25
static void ExampleTask(void)
{
float ad_value;
BoardInit();
usleep(1000000);
while (1)
{
ad_value = GetVoltage();
if(NoiseReadData() == 0)
{
printf("Near the noise!\n");
printf("ad_value:%2.2fV\n",ad_value);
LedWarnStatusSet(ON);
}
else{
printf("Far the noise!\n");
printf("ad_value:%2.2fV\n",ad_value);
LedWarnStatusSet(OFF);
}
sleep(1);
}
}
static void ExampleEntry(void)
{
osThreadAttr_t attr;
attr.name = "ExampleTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = TASK_STACK_SIZE;
attr.priority = TASK_PRIO;
if (osThreadNew((osThreadFunc_t)ExampleTask, NULL, &attr) == NULL) {
printf("Failed to create ExampleTask!\n");
}
}
APP_FEATURE_INIT(ExampleEntry);

26
app/A04_NOISE/BUILD.gn Normal file
View File

@ -0,0 +1,26 @@
# Copyright (c) 2020  Jinan Bosai Network Technology Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_library("A04_NOISE") {
sources = [
"src/noise.c",
"A04_NOISE_example.c"
]
include_dirs = [
"//base/iot_hardware/peripheral/interfaces/kits",
"//device/bossay/hi3861_l0/iot_hardware_hals/include",
"//device/bossay/hi3861_l0/sdk_liteos/include",
"include"
]
}

View File

@ -0,0 +1,23 @@
#ifndef __FLAME_H__
#define __FLAME_H__
#include <stdint.h>
typedef enum
{
OFF = 0,
ON
} SwitchStatus;
void BoardInit(void);
float GetVoltage(void);
uint8_t NoiseReadData(void);
// void BeepStatusSet(SwitchStatus status);
void LedWarnStatusSet(SwitchStatus status);
#endif

103
app/A04_NOISE/src/noise.c Normal file
View File

@ -0,0 +1,103 @@
#include "noise.h"
#include "iot_adc.h"
#include "iot_errno.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#define WIFI_IOT_IO_NAME_GPIO_8 8
#define WIFI_IOT_IO_NAME_GPIO_14 14
#define OUT_GPIO 12
void BoardInit(void)
{
IoTGpioInit(OUT_GPIO);
IoTGpioSetFunc(OUT_GPIO, IOT_GPIO_FUNC_GPIO_12_GPIO);
IoTGpioSetDir(OUT_GPIO, IOT_GPIO_DIR_IN); // 设置GPIO_8为输出模式
// IoTGpioInit(13);
// IoTGpioSetFunc(13, IOT_GPIO_FUNC_GPIO_13_GPIO);
// IoTGpioSetDir(13, IOT_GPIO_DIR_IN); // 设置GPIO_8为输出模式
IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_14);
IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_14, IOT_GPIO_FUNC_GPIO_14_GPIO);
IoTGpioSetDir(WIFI_IOT_IO_NAME_GPIO_14, IOT_GPIO_DIR_OUT);
// IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_8);
// IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_8, IOT_GPIO_FUNC_GPIO_8_GPIO);
// IoTGpioSetDir(WIFI_IOT_IO_NAME_GPIO_8, IOT_GPIO_DIR_OUT);
}
/***************************************************************
* : GetVoltage
* :
* :
*
* :
***************************************************************/
float GetVoltage(void)
{
unsigned int ret;
unsigned short data;
ret = IoTAdcRead(6, &data, IOT_ADC_EQU_MODEL_8, IOT_ADC_CUR_BAIS_DEFAULT, 0xff);
if (ret != IOT_SUCCESS)
{
printf("ADC Read Fail\n");
}
return (float)data * 1.8 * 4 / 4096.0;
}
/***************************************************************
* : NoiseReadData
* :
* :
* :
***************************************************************/
uint8_t NoiseReadData(void)
{
IotGpioValue temp = {0};
IoTGpioGetInputVal(OUT_GPIO,&temp);
return temp;
}
/***************************************************************
* : BeepStatusSet
* : Beep状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
// void BeepStatusSet(SwitchStatus status)
// {
// if (status == ON) {
// IoTGpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, 1); // 设置GPIO_7输出高电平点亮灯
// }
// if (status == OFF) {
// IoTGpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, 0); // 设置GPIO_7输出低电平关闭灯
// }
// }
/***************************************************************
* : LedWarnStatusSet
* : LED_Warn状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void LedWarnStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_14, 1); // 设置GPIO_14输出高电平点亮灯
}
if (status == OFF) {
IoTGpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_14, 0); // 设置GPIO_14输出低电平关闭灯
}
}

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2020  Jinan Bosai Network Technology Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "WATER.h"
#include "cmsis_os2.h"
#include "ohos_init.h"
#define TASK_STACK_SIZE 1024 * 8
#define TASK_PRIO 25
static void ExampleTask(void)
{
float ad_value;
BoardInit();
while (1)
{
ad_value = GetVoltage();
if(WaterReadData() == 0)
{
printf("Near the water!\n");
printf("ad_value:%2.2fV\n",ad_value);
BeepStatusSet(ON);
LedWarnStatusSet(ON);
}
else
{
printf("Far the water!\n");
printf("ad_value:%2.2fV\n",ad_value);
BeepStatusSet(OFF);
LedWarnStatusSet(OFF);
}
sleep(1);
}
}
static void ExampleEntry(void)
{
osThreadAttr_t attr;
attr.name = "ExampleTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = TASK_STACK_SIZE;
attr.priority = TASK_PRIO;
if (osThreadNew((osThreadFunc_t)ExampleTask, NULL, &attr) == NULL) {
printf("Failed to create ExampleTask!\n");
}
}
APP_FEATURE_INIT(ExampleEntry);

26
app/A05_WATER/BUILD.gn Normal file
View File

@ -0,0 +1,26 @@
# Copyright (c) 2020  Jinan Bosai Network Technology Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_library("A05_WATER") {
sources = [
"src/WATER.c",
"A02_WATER_example.c"
]
include_dirs = [
"//base/iot_hardware/peripheral/interfaces/kits",
"//device/bossay/hi3861_l0/iot_hardware_hals/include",
"//device/bossay/hi3861_l0/sdk_liteos/include",
"include"
]
}

View File

@ -0,0 +1,23 @@
#ifndef __WATER_H__
#define __WATER_H__
#include <stdint.h>
typedef enum
{
OFF = 0,
ON
} SwitchStatus;
void BoardInit(void);
float GetVoltage(void);
uint8_t WaterReadData(void);
void BeepStatusSet(SwitchStatus status);
void LedWarnStatusSet(SwitchStatus status);
#endif

100
app/A05_WATER/src/WATER.c Normal file
View File

@ -0,0 +1,100 @@
#include "WATER.h"
#include "iot_adc.h"
#include "iot_errno.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#define WIFI_IOT_IO_NAME_GPIO_8 8
#define WIFI_IOT_IO_NAME_GPIO_14 14
#define OUT_GPIO 7
void BoardInit(void)
{
IoTGpioInit(OUT_GPIO);
IoTGpioSetFunc(OUT_GPIO, IOT_GPIO_FUNC_GPIO_7_GPIO);
IoTGpioSetDir(OUT_GPIO, IOT_GPIO_DIR_IN); // 设置为输入模式
IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_14);
IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_14, IOT_GPIO_FUNC_GPIO_14_GPIO);
IoTGpioSetDir(WIFI_IOT_IO_NAME_GPIO_14, IOT_GPIO_DIR_OUT); // 设置为输出模式
IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_8);
IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_8, IOT_GPIO_FUNC_GPIO_8_GPIO);
IoTGpioSetDir(WIFI_IOT_IO_NAME_GPIO_8, IOT_GPIO_DIR_OUT); // 设置为输出模式
}
/***************************************************************
* : GetVoltage
* :
* :
*
* :
***************************************************************/
float GetVoltage(void)
{
unsigned int ret;
unsigned short data;
ret = IoTAdcRead(6, &data, IOT_ADC_EQU_MODEL_8, IOT_ADC_CUR_BAIS_DEFAULT, 0xff);
if (ret != IOT_SUCCESS)
{
printf("ADC Read Fail\n");
}
return (float)data * 1.8 * 4 / 4096.0;
}
/***************************************************************
* : WaterReadData
* :
* :
* :
***************************************************************/
uint8_t WaterReadData(void)
{
IotGpioValue temp = {0};
IoTGpioGetInputVal(OUT_GPIO,&temp);
return temp;
}
/***************************************************************
* : BeepStatusSet
* : Beep状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void BeepStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, 1); // 设置输出高电平打开蜂鸣器
}
if (status == OFF) {
IoTGpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, 0); // 设置输出低电平关闭蜂鸣器
}
}
/***************************************************************
* : LedWarnStatusSet
* : LED_Warn状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void LedWarnStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_14, 1); // 设置GPIO_14输出高电平点亮灯
}
if (status == OFF) {
IoTGpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_14, 0); // 设置GPIO_14输出低电平关闭灯
}
}

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2020  Jinan Bosai Network Technology Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "PM2_5.h"
#include "cmsis_os2.h"
#include "ohos_init.h"
#define TASK_STACK_SIZE 1024 * 8
#define TASK_PRIO 25
static void ExampleTask(void)
{
PM2D5Data data;
BoardInit();
while (1) {
PM2DReadData(&data);
// printf("\r\n******************************PM1.0 is %d\r\n", data.pm1_0);
// printf("\r\n******************************PM2.5 is %d\r\n", data.pm2_5);
// printf("\r\n******************************PM10 is %d\r\n", data.pm10);
// sleep(1);
RelayStatusSet(ON);
osDelay(200);
RelayStatusSet(OFF);
osDelay(200);
}
}
static void ExampleEntry(void)
{
osThreadAttr_t attr;
attr.name = "ExampleTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = TASK_STACK_SIZE;
attr.priority = TASK_PRIO;
if (osThreadNew((osThreadFunc_t)ExampleTask, NULL, &attr) == NULL) {
printf("Failed to create ExampleTask!\n");
}
}
APP_FEATURE_INIT(ExampleEntry);

View File

@ -0,0 +1,26 @@
# Copyright (c) 2020  Jinan Bosai Network Technology Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_library("A6_VOICE_SWITCH") {
sources = [
"src/PM2_5.c",
"A11_PM2_5_example.c"
]
include_dirs = [
"//base/iot_hardware/peripheral/interfaces/kits",
"//device/bossay/hi3861_l0/iot_hardware_hals/include",
"//device/bossay/hi3861_l0/sdk_liteos/include",
"include"
]
}

View File

@ -0,0 +1,29 @@
#ifndef __PM_2_5_H__
#define __PM_2_5_H__
#include <stdint.h>
typedef enum
{
OFF = 0,
ON
} SwitchStatus;
typedef struct
{
uint32_t pm1_0;
uint32_t pm2_5;
uint32_t pm10;
} PM2D5Data;
void BoardInit(void);
uint8_t Button_Left_Read_Data(void);
void PM2DReadData(PM2D5Data* ReadData);
void RelayStatusSet(SwitchStatus status);
#endif

View File

@ -0,0 +1,89 @@
#include "PM2_5.h"
#include "iot_errno.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#include "iot_uart.h"
#include "stdio.h"
#define RESET_GPIO 7
#define LED_SAFE_GPIO 8
#define LED_WARN_GPIO 14
#define SET_GPIO 13
#define WIFI_IOT_UART_IDX_1 1
uint8_t RxBuffer[3];
#define RELAY_GPIO 14
void BoardInit(void)
{
IoTGpioInit(RELAY_GPIO);
IoTGpioSetFunc(RELAY_GPIO, IOT_GPIO_FUNC_GPIO_14_GPIO);
IoTGpioSetDir(RELAY_GPIO, IOT_GPIO_DIR_OUT); //设置为输出模式
uint32_t ret;
IotUartAttribute uart_attr = {
// baud_rate: 9600
.baudRate = 9600,
// data_bits: 8bits
.dataBits = 8,
.stopBits = 1,
.parity = 0,
};
// Initialize uart driver
ret = IoTUartInit(WIFI_IOT_UART_IDX_1, &uart_attr);
if (ret != IOT_SUCCESS) {
printf("Failed to init uart! Err code = %d\n", ret);
return;
}
}
static unsigned char read_date[32];
/***************************************************************
* : PM2DReadData
* : GPS经纬度信息
* :
* :
***************************************************************/
void PM2DReadData(PM2D5Data* ReadData)
{
//通过串口1接收数据
IoTUartRead(WIFI_IOT_UART_IDX_1, read_date, 200);
for(int i = 0; i<200; i++)
{
printf("%d------%x\r\n",i,read_date[i]);
}
// if(read_date[0]== 0x42 && read_date[1]== 0x4d)
// {
// ReadData->pm1_0=read_date[2]<<8|read_date[3];
// ReadData->pm2_5=read_date[4]<<8|read_date[5];
// ReadData->pm10=read_date[6]<<8|read_date[7];
// }
}
/***************************************************************
* : RelayStatusSet
* :
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void RelayStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(RELAY_GPIO, 1); //设置输出高电平点亮LED灯
}
if (status == OFF) {
IoTGpioSetOutputVal(RELAY_GPIO, 0); //设置输出低电平点亮LED灯
}
}

View File

@ -0,0 +1,85 @@
/*
* Copyright (c) 2020  Jinan Bosai Network Technology Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "cmsis_os2.h"
#include "ohos_init.h"
#include "WATHER.h"
#define TASK_STACK_SIZE 1024 * 8
#define TASK_PRIO 25
BMP280_HandleTypedef bmp280;
float pressure, temperature, asl,humidity;
static void ExampleTask(void)
{
uint16_t dht_temperature;
uint16_t dht_humidity;
BoardInit();
bmp280_init_default_params(&bmp280.params);
while (!bmp280_init(&bmp280, &bmp280.params)) {
printf("BMP280 initialization failed\n");
}
DHT21_Init();
while (1)
{
printf("=======================================\r\n");
printf("*************A07_WATHER_example***********\r\n");
printf("=======================================\r\n");
DHT21_onewire(&dht_temperature,&dht_humidity);
humidity = (float)dht_humidity/10;
if(humidity>80){
BeepStatusSet(ON);
}
else{
BeepStatusSet(OFF);
}
// printf("temperature=%d \r\n",dht_temperature);
// printf("humidity=%d %%\r\n",dht_humidity);
//读取温度、气压、海拔数据,学员自行补充
while (!bmp280_read_float(&bmp280, &temperature, &pressure, &asl)) {
printf("Temperature/pressure reading failed\n");
}
printf("Temperature: %.2f C\r\nHumidity: %.2f %%\r\nPressure: %.2f hPa\r\nAltiude: %.2f m\r\n",temperature,humidity, pressure,asl);
sleep(3);
}
}
static void ExampleEntry(void)
{
osThreadAttr_t attr;
attr.name = "ExampleTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = TASK_STACK_SIZE;
attr.priority = TASK_PRIO;
if (osThreadNew((osThreadFunc_t)ExampleTask, NULL, &attr) == NULL) {
printf("Failed to create ExampleTask!\n");
}
}
APP_FEATURE_INIT(ExampleEntry);

28
app/A07_WATHER/BUILD.gn Normal file
View File

@ -0,0 +1,28 @@
# Copyright (c) 2022 Jinan Bosai Network Technology Co., LTD Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_library("A07_WATHER") {
sources = [
"src/dht21.c",
"src/bmp280.c",
"src/WATHER.c",
"A07_WATHER_example.c"
]
include_dirs = [
"//base/iot_hardware/peripheral/interfaces/kits",
"//device/bossay/hi3861_l0/iot_hardware_hals/include",
"//device/bossay/hi3861_l0/sdk_liteos/include",
"include"
]
}

View File

@ -0,0 +1,21 @@
#ifndef __WATER_H__
#define __WATER_H__
#include <stdint.h>
#include "bmp280.h"
#include "dht21.h"
typedef enum
{
OFF = 0,
ON
} SwitchStatus;
void BoardInit(void);
void BeepStatusSet(SwitchStatus status);
#endif

View File

@ -0,0 +1,172 @@
/**
* Ciastkolog.pl (https://github.com/ciastkolog)
*
*/
/**
* The MIT License (MIT)
* Copyright (c) 2016 sheinz (https://github.com/sheinz)
* Copyright (c) 2020  Jinan Bosai Network Technology Co., Ltd.
*/
#ifndef __BMP280_H__
#define __BMP280_H__
// #include "stm32f0xx_hal.h"
#include <stdint.h>
#include <stdbool.h>
/**
* BMP280 or BME280 address is 0x77 if SDO pin is high, and is 0x76 if
* SDO pin is low.
*/
#define BMP280_I2C_ADDRESS_0 0x76
#define BMP280_I2C_ADDRESS_1 0x77
#define BMP280_CHIP_ID 0x58 /* BMP280 has chip-id 0x58 */
#define BME280_CHIP_ID 0x60 /* BME280 has chip-id 0x60 */
/**
* Mode of BMP280 module operation.
* Forced - Measurement is initiated by user.
* Normal - Continues measurement.
*/
typedef enum {
BMP280_MODE_SLEEP = 0,
BMP280_MODE_FORCED = 1,
BMP280_MODE_NORMAL = 3
} BMP280_Mode;
typedef enum {
BMP280_FILTER_OFF = 0,
BMP280_FILTER_2 = 1,
BMP280_FILTER_4 = 2,
BMP280_FILTER_8 = 3,
BMP280_FILTER_16 = 4
} BMP280_Filter;
/**
* Pressure oversampling settings
*/
typedef enum {
BMP280_SKIPPED = 0, /* no measurement */
BMP280_ULTRA_LOW_POWER = 1, /* oversampling x1 */
BMP280_LOW_POWER = 2, /* oversampling x2 */
BMP280_STANDARD = 3, /* oversampling x4 */
BMP280_HIGH_RES = 4, /* oversampling x8 */
BMP280_ULTRA_HIGH_RES = 5 /* oversampling x16 */
} BMP280_Oversampling;
/**
* Stand by time between measurements in normal mode
*/
typedef enum {
BMP280_STANDBY_05 = 0, /* stand by time 0.5ms */
BMP280_STANDBY_62 = 1, /* stand by time 62.5ms */
BMP280_STANDBY_125 = 2, /* stand by time 125ms */
BMP280_STANDBY_250 = 3, /* stand by time 250ms */
BMP280_STANDBY_500 = 4, /* stand by time 500ms */
BMP280_STANDBY_1000 = 5, /* stand by time 1s */
BMP280_STANDBY_2000 = 6, /* stand by time 2s BMP280, 10ms BME280 */
BMP280_STANDBY_4000 = 7, /* stand by time 4s BMP280, 20ms BME280 */
} BMP280_StandbyTime;
/**
* Configuration parameters for BMP280 module.
* Use function bmp280_init_default_params to use default configuration.
*/
typedef struct {
BMP280_Mode mode;
BMP280_Filter filter;
BMP280_Oversampling oversampling_pressure;
BMP280_Oversampling oversampling_temperature;
BMP280_StandbyTime standby;
} bmp280_params_t;
typedef struct {
uint16_t dig_T1;
int16_t dig_T2;
int16_t dig_T3;
uint16_t dig_P1;
int16_t dig_P2;
int16_t dig_P3;
int16_t dig_P4;
int16_t dig_P5;
int16_t dig_P6;
int16_t dig_P7;
int16_t dig_P8;
int16_t dig_P9;
/* Humidity compensation for BME280 */
uint8_t dig_H1;
int16_t dig_H2;
uint8_t dig_H3;
int16_t dig_H4;
int16_t dig_H5;
int8_t dig_H6;
bmp280_params_t params;
uint8_t id; /* Chip ID */
} BMP280_HandleTypedef;
/**
* Initialize default parameters.
* Default configuration:
* mode: NORAML
* filter: OFF
* oversampling: x4
* standby time: 250ms
*/
void bmp280_init_default_params(bmp280_params_t *params);
/**
* Initialize BMP280 module, probes for the device, soft resets the device,
* reads the calibration constants, and configures the device using the supplied
* parameters. Returns true on success otherwise false.
*
* The I2C address is assumed to have been initialized in the dev, and
* may be either BMP280_I2C_ADDRESS_0 or BMP280_I2C_ADDRESS_1. If the I2C
* address is unknown then try initializing each in turn.
*
* This may be called again to soft reset the device and initialize it again.
*/
bool bmp280_init(BMP280_HandleTypedef *dev, bmp280_params_t *params);
/**
* Start measurement in forced mode.
* The module remains in forced mode after this call.
* Do not call this method in normal mode.
*/
bool bmp280_force_measurement(void);
/**
* Check if BMP280 is busy with measuring temperature/pressure.
* Return true if BMP280 is busy.
*/
bool bmp280_is_measuring(void);
/**
* Read compensated temperature and pressure data:
*
* Temperature in degrees Celsius times 100.
*
* Pressure in Pascals in fixed point 24 bit integer 8 bit fraction format.
*
* Humidity is optional and only read for the BME280, in percent relative
* humidity as a fixed point 22 bit interger and 10 bit fraction format.
*/
bool bmp280_read_fixed(BMP280_HandleTypedef *dev, int32_t *temperature,
uint32_t *pressure);
/**
* Read compensated temperature and pressure data:
* Temperature in degrees Celsius.
* Pressure in Pascals.
* Humidity is optional and only read for the BME280, in percent relative
* humidity.
*/
bool bmp280_read_float(BMP280_HandleTypedef *dev, float *temperature,
float *pressure, float* asl);
#endif // __BMP280_H__

View File

@ -0,0 +1,19 @@
#ifndef __DHT21_H_
#define __DHT21_H_
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#include <stdint.h>
#define DHT11_DQ_GPIO 13
#define DHT11_DQ_OUT_OFF IoTGpioSetOutputVal(DHT11_DQ_GPIO, 0);
#define DHT11_DQ_OUT_ON IoTGpioSetOutputVal(DHT11_DQ_GPIO, 1);
void DHT21_Init(void);
uint8_t DHT21_onewire(uint16_t *tem,uint16_t *hum);
#endif

View File

@ -0,0 +1,53 @@
#include "WATHER.h"
#include "iot_adc.h"
#include "iot_errno.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#include "iot_i2c.h"
#define I2C1_SDA_GPIO 0
#define I2C1_SCL_GPIO 1
#define IOT_GPIO_FUNC_GPIO_0_I2C1_SDA 6
#define IOT_GPIO_FUNC_GPIO_1_I2C1_SCL 6
#define WIFI_IOT_I2C_IDX_1 1
#define BEEP_GPIO 8
void BoardInit(void)
{
IoTGpioInit(BEEP_GPIO);
IoTGpioSetFunc(BEEP_GPIO, IOT_GPIO_FUNC_GPIO_8_GPIO);
IoTGpioSetDir(BEEP_GPIO, IOT_GPIO_DIR_OUT); // 设置GPIO_14为输出模式
//GPIO_0复用为I2C1_SDA
IoTGpioInit(I2C1_SDA_GPIO);
IoTGpioSetFunc(I2C1_SDA_GPIO, IOT_GPIO_FUNC_GPIO_0_I2C1_SDA);
//GPIO_1复用为I2C1_SCL
IoTGpioInit(I2C1_SCL_GPIO);
IoTGpioSetFunc(I2C1_SCL_GPIO, IOT_GPIO_FUNC_GPIO_1_I2C1_SCL);
//baudrate: 400kbps
IoTI2cInit(WIFI_IOT_I2C_IDX_1, 400000);
}
/***************************************************************
* : BeepStatusSet
* : Beep状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void BeepStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(BEEP_GPIO, 1); // 设置输出高电平打开蜂鸣器
}
if (status == OFF) {
IoTGpioSetOutputVal(BEEP_GPIO, 0); // 设置输出低电平关闭蜂鸣器
}
}

307
app/A07_WATHER/src/bmp280.c Normal file
View File

@ -0,0 +1,307 @@
/**
* Ciastkolog.pl (https://github.com/ciastkolog)
*
*/
/**
* The MIT License (MIT)
*
* Copyright (c) 2016 sheinz (https://github.com/sheinz)
* Copyright (c) 2020 Jinan Bosai Network Technology Co., Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "bmp280.h"
#include <stdio.h>
#include <math.h>
#include "iot_i2c.h"
#include "iot_i2c_ex.h"
/**
* BMP280 registers
*/
#define BMP280_REG_TEMP_XLSB 0xFC /* bits: 7-4 */
#define BMP280_REG_TEMP_LSB 0xFB
#define BMP280_REG_TEMP_MSB 0xFA
#define BMP280_REG_TEMP (BMP280_REG_TEMP_MSB)
#define BMP280_REG_PRESS_XLSB 0xF9 /* bits: 7-4 */
#define BMP280_REG_PRESS_LSB 0xF8
#define BMP280_REG_PRESS_MSB 0xF7
#define BMP280_REG_PRESSURE (BMP280_REG_PRESS_MSB)
#define BMP280_REG_CONFIG 0xF5 /* bits: 7-5 t_sb; 4-2 filter; 0 spi3w_en */
#define BMP280_REG_CTRL 0xF4 /* bits: 7-5 osrs_t; 4-2 osrs_p; 1-0 mode */
#define BMP280_REG_STATUS 0xF3 /* bits: 3 measuring; 0 im_update */
#define BMP280_REG_RESET 0xE0
#define BMP280_REG_ID 0xD0
#define BMP280_REG_CALIB 0x88
#define BMP280_RESET_VALUE 0xB6
#define WIFI_IOT_I2C_IDX_1 1
void bmp280_init_default_params(bmp280_params_t *params) {
params->mode = BMP280_MODE_NORMAL;
params->filter = BMP280_FILTER_OFF;
params->oversampling_pressure = BMP280_STANDARD;
params->oversampling_temperature = BMP280_STANDARD;
params->standby = BMP280_STANDBY_250;
}
static uint8_t read_register16(uint8_t reg, uint16_t *value) {
uint8_t rx_buff[2];
uint32_t status = 0;
IotI2cData bmp280_i2c_data = {0};
uint8_t buffer[1] = {reg};
bmp280_i2c_data.sendBuf = buffer;
bmp280_i2c_data.sendLen = 1;
bmp280_i2c_data.receiveBuf = rx_buff;
bmp280_i2c_data.receiveLen = 2;
status = IoTI2cWriteread(WIFI_IOT_I2C_IDX_1, (BMP280_I2C_ADDRESS_0<<1)|0x00, &bmp280_i2c_data);
if (status != 0)
{
printf("===== Error: I2C write status = 0x%x! =====\r\n", status);
return false;
}
*value = (uint16_t) ((rx_buff[1] << 8) | rx_buff[0]);
return true;
}
static uint8_t read_data( uint8_t reg, uint8_t *value,uint8_t len) {
uint32_t status = 0;
IotI2cData bmp280_i2c_data = {0};
uint8_t buffer[1] = {reg};
bmp280_i2c_data.sendBuf = buffer;
bmp280_i2c_data.sendLen = 1;
bmp280_i2c_data.receiveBuf = value;
bmp280_i2c_data.receiveLen = len;
status = IoTI2cWriteread(WIFI_IOT_I2C_IDX_1, (BMP280_I2C_ADDRESS_0<<1)|0x00, &bmp280_i2c_data);
if (status != 0)
{
printf("===== Error: I2C write status = 0x%x! =====\r\n", status);
return 1;
}
return 0;
}
static bool read_calibration_data(BMP280_HandleTypedef *dev) {
if (read_register16(0x88, &dev->dig_T1)
&& read_register16(0x8a, (uint16_t *) &dev->dig_T2)
&& read_register16(0x8c, (uint16_t *) &dev->dig_T3)
&& read_register16(0x8e, &dev->dig_P1)
&& read_register16(0x90, (uint16_t *) &dev->dig_P2)
&& read_register16(0x92, (uint16_t *) &dev->dig_P3)
&& read_register16(0x94, (uint16_t *) &dev->dig_P4)
&& read_register16(0x96, (uint16_t *) &dev->dig_P5)
&& read_register16(0x98, (uint16_t *) &dev->dig_P6)
&& read_register16(0x9a, (uint16_t *) &dev->dig_P7)
&& read_register16(0x9c, (uint16_t *) &dev->dig_P8)
&& read_register16(0x9e,(uint16_t *) &dev->dig_P9)) {
return true;
}
return false;
}
static int write_register8(uint8_t reg, uint8_t value) {
uint32_t status = 0;
uint8_t send_data[2] = { reg,value };
status = IoTI2cWrite(WIFI_IOT_I2C_IDX_1,(BMP280_I2C_ADDRESS_0<<1)|0x00,send_data,2);
if (status != 0)
{
printf("===== Error: I2C write status = 0x%x! =====\r\n", status);
return status;
}
return 0;
}
bool bmp280_init(BMP280_HandleTypedef *dev, bmp280_params_t *params) {
if (read_data(BMP280_REG_ID, &dev->id, 1)) {
return false;
}
if (dev->id != BMP280_CHIP_ID && dev->id != BME280_CHIP_ID) {
return false;
}
// Soft reset.
if (write_register8(BMP280_REG_RESET, BMP280_RESET_VALUE)) {
return false;
}
// Wait until finished copying over the NVP data.
while (1) {
uint8_t status;
if (!read_data(BMP280_REG_STATUS, &status, 1)
&& (status & 1) == 0)
break;
}
if (!read_calibration_data(dev)) {
return false;
}
uint8_t config = (params->standby << 5) | (params->filter << 2);
if (write_register8(BMP280_REG_CONFIG, config)) {
return false;
}
if (params->mode == BMP280_MODE_FORCED) {
params->mode = BMP280_MODE_SLEEP; // initial mode for forced is sleep
}
uint8_t ctrl = (params->oversampling_temperature << 5)
| (params->oversampling_pressure << 2) | (params->mode);
if (write_register8(BMP280_REG_CTRL, ctrl)) {
return false;
}
return true;
}
bool bmp280_force_measurement(void) {
uint8_t ctrl;
if (read_data(BMP280_REG_CTRL, &ctrl, 1))
return false;
ctrl &= ~0b11; // clear two lower bits
ctrl |= BMP280_MODE_FORCED;
if (write_register8(BMP280_REG_CTRL, ctrl)) {
return false;
}
return true;
}
bool bmp280_is_measuring(void) {
uint8_t status;
if (read_data(BMP280_REG_STATUS, &status, 1))
return false;
if (status & (1 << 3)) {
return true;
}
return false;
}
/**
* Compensation algorithm is taken from BMP280 datasheet.
*
* Return value is in degrees Celsius.
*/
static inline int32_t compensate_temperature(BMP280_HandleTypedef *dev, int32_t adc_temp,
int32_t *fine_temp) {
int32_t var1, var2;
var1 = ((((adc_temp >> 3) - ((int32_t) dev->dig_T1 << 1)))
* (int32_t) dev->dig_T2) >> 11;
var2 = (((((adc_temp >> 4) - (int32_t) dev->dig_T1)
* ((adc_temp >> 4) - (int32_t) dev->dig_T1)) >> 12)
* (int32_t) dev->dig_T3) >> 14;
*fine_temp = var1 + var2;
return (*fine_temp * 5 + 128) >> 8;
}
/**
* Compensation algorithm is taken from BMP280 datasheet.
*
* Return value is in Pa, 24 integer bits and 8 fractional bits.
*/
static inline uint32_t compensate_pressure(BMP280_HandleTypedef *dev, int32_t adc_press,
int32_t fine_temp) {
int64_t var1, var2, p;
var1 = (int64_t) fine_temp - 128000;
var2 = var1 * var1 * (int64_t) dev->dig_P6;
var2 = var2 + ((var1 * (int64_t) dev->dig_P5) << 17);
var2 = var2 + (((int64_t) dev->dig_P4) << 35);
var1 = ((var1 * var1 * (int64_t) dev->dig_P3) >> 8)
+ ((var1 * (int64_t) dev->dig_P2) << 12);
var1 = (((int64_t) 1 << 47) + var1) * ((int64_t) dev->dig_P1) >> 33;
if (var1 == 0) {
return 0; // avoid exception caused by division by zero
}
p = 1048576 - adc_press;
p = (((p << 31) - var2) * 3125) / var1;
var1 = ((int64_t) dev->dig_P9 * (p >> 13) * (p >> 13)) >> 25;
var2 = ((int64_t) dev->dig_P8 * p) >> 19;
p = ((p + var1 + var2) >> 8) + ((int64_t) dev->dig_P7 << 4);
return p;
}
#define CONST_PF 0.1902630958 //(1/5.25588f) Pressure factor
#define FIX_TEMP 25 // Fixed Temperature. ASL is a function of pressure and temperature, but as the temperature changes so much (blow a little towards the flie and watch it drop 5 degrees) it corrupts the ASL estimates.
// TLDR: Adjusting for temp changes does more harm than good.
/*
* Converts pressure to altitude above sea level (ASL) in meters
*/
static float bme280PressureToAltitude(float* pressure/*, float* groundPressure, float* groundTemp*/)
{
if (*pressure>0)
{
return((1.0f-pow((*pressure/1010),CONST_PF))*(25+273.15f))/0.0065f;
}
else
{
return 0;
}
}
bool bmp280_read_fixed(BMP280_HandleTypedef *dev, int32_t *temperature, uint32_t *pressure) {
int32_t adc_pressure;
int32_t adc_temp;
uint8_t data[8];
// Need to read in one sequence to ensure they match.
size_t size = 6;
if (read_data(0xf7, data, size)) {
return false;
}
adc_pressure = data[0] << 12 | data[1] << 4 | data[2] >> 4;
adc_temp = data[3] << 12 | data[4] << 4 | data[5] >> 4;
int32_t fine_temp;
*temperature = compensate_temperature(dev, adc_temp, &fine_temp);
*pressure = compensate_pressure(dev, adc_pressure, fine_temp);
return true;
}
bool bmp280_read_float(BMP280_HandleTypedef *dev, float *temperature, float *pressure, float* asl) {
int32_t fixed_temperature;
uint32_t fixed_pressure;
if (bmp280_read_fixed(dev, &fixed_temperature, &fixed_pressure)) {
*temperature = (float) fixed_temperature / 100;
*pressure = (float) fixed_pressure / 25600;
*asl = (float)bme280PressureToAltitude(pressure);
return true;
}
return false;
}

245
app/A07_WATHER/src/dht21.c Normal file
View File

@ -0,0 +1,245 @@
#include "dht21.h"
#include "hi_time.h"
static void SDA_Output(void)
{
IoTGpioInit(DHT11_DQ_GPIO);
IoTGpioSetFunc(DHT11_DQ_GPIO, IOT_GPIO_FUNC_GPIO_13_GPIO);
IoTGpioSetDir(DHT11_DQ_GPIO, IOT_GPIO_DIR_OUT); // 设置为输出模式
}
static void SDA_Input(void)
{
IoTGpioInit(DHT11_DQ_GPIO);
IoTGpioSetFunc(DHT11_DQ_GPIO, IOT_GPIO_FUNC_GPIO_13_GPIO);
IoTGpioSetDir(DHT11_DQ_GPIO, IOT_GPIO_DIR_IN); // 设置为输入模式
}
static uint8_t Get_SDA(void)
{
IotGpioValue temp = {0};
IoTGpioGetInputVal(DHT11_DQ_GPIO,&temp);
return temp;
}
static void DQ_Rst(void)
{
SDA_Output();
hi_udelay(5);
DHT11_DQ_OUT_OFF;
hi_udelay(480);;
DHT11_DQ_OUT_ON;
hi_udelay(8);
}
static uint8_t DQ_Presence(void)
{
uint8_t pulse_time = 0;
SDA_Input();
hi_udelay(5);
while(Get_SDA() && pulse_time<100 )
{
pulse_time++;
hi_udelay(10);//>6us
}
if( pulse_time >=20 )
return 0x01;
else
pulse_time = 0;
while((Get_SDA()==0) && (pulse_time<240 ))
{
pulse_time++;
hi_udelay(5);//1~5us
}
if( pulse_time >=10 )
{
return 0x01;
}
else
return 0x0;
}
//拉低最少1us 后延时一小段时间如6us后再15us内读取完。 后延时45us以上 即一个周期是60us
//tINIT+tRC+tSample < 15us
//tINIT+tRC+tSample+tDelay>60us
static uint8_t DQ_Read_Bit(void)
{
uint8_t dat;
SDA_Output();
DHT11_DQ_OUT_OFF
hi_udelay(5); //tINIT>1us 典型5us <15us
DHT11_DQ_OUT_ON
SDA_Input();
hi_udelay(5);//tRC 典型5us
if(Get_SDA())//tSample
dat = 1;
else
dat = 0;
hi_udelay(70);//tDelay >60us 确保一帧数据传输完毕
return dat;
}
static uint8_t DQ_Read_Byte(void)
{
uint8_t i, j, dat = 0;
for(i=0; i<8; i++)
{
j = DQ_Read_Bit();
dat = (dat) | (j<<i);
}
return dat;
}
static void DQ_Write_Byte(uint8_t dat)
{
uint8_t i, testb;
SDA_Output();
for( i=0; i<8; i++ )
{
testb = dat&0x01;
dat = dat>>1;
if(testb)//写1
{
DHT11_DQ_OUT_OFF
hi_udelay(5);//>1us <15us
DHT11_DQ_OUT_ON
hi_udelay(70);//>=60us
}
else//写0
{
DHT11_DQ_OUT_OFF
hi_udelay(70);//MY_hi_udelay(70);>60us
DHT11_DQ_OUT_ON
hi_udelay(5);//???? 5us
}
}
}
static uint8_t CRC8MHT_Cal(uint8_t *serial, uint8_t length)
{
uint8_t result = 0x00;
uint8_t pDataBuf;
uint8_t i;
while(length--)
{
pDataBuf = *serial++;
for(i=0; i<8; i++)
{
if((result^(pDataBuf))&0x01)
{
result ^= 0x18;
result >>= 1;
result |= 0x80;
}
else
{
result >>= 1;
}
pDataBuf >>= 1;
}
}
return result;
}
static uint16_t OwHumA,OwHumB;
//初始化获取校准数据A B值
void DHT21_Init()
{
uint8_t i,crc;
uint8_t ResDat[13];
//Timer4Stop();
DQ_Rst();
DQ_Presence();
DQ_Write_Byte(0xcc);
DQ_Write_Byte(0xdd);
/* OwHumA = DQ_Read_Byte();
OwHumA = (OwHumA<<8)|DQ_Read_Byte();
OwHumB = DQ_Read_Byte();
OwHumB = (OwHumB<<8)|DQ_Read_Byte();
*/
//Timer4Start();
//当读取满一组数据即 13 个字节后,才有 CRC 值
//无需要时可以按上面读取前面 4 个即可
for(i=0;i<13;i++)
{
ResDat[i] = DQ_Read_Byte();
}
crc = CRC8MHT_Cal(ResDat,13);
if(crc == 0)
{
OwHumA = ResDat[0];
OwHumA = (OwHumA<<8)|ResDat[1];
OwHumB = ResDat[2];
OwHumB = (OwHumB<<8)|ResDat[3];
}
}
//读取温湿度函数
uint8_t DHT21_onewire(uint16_t *tem,uint16_t *hum)
{
uint8_t ResDat[5],crc=0;
uint16_t TemBuf;
uint16_t CapBuf;
DQ_Rst();
DQ_Presence();
DQ_Write_Byte(0xcc);
DQ_Write_Byte(0x10);
osDelay(3);
DQ_Rst();
DQ_Presence();
DQ_Write_Byte(0xcc);
DQ_Write_Byte(0xbd);
ResDat[0] = DQ_Read_Byte();
ResDat[1] = DQ_Read_Byte();
ResDat[2] = DQ_Read_Byte();
ResDat[3] = DQ_Read_Byte();
ResDat[4] = DQ_Read_Byte();
crc = CRC8MHT_Cal(ResDat,5);
if(crc == 0)
{
TemBuf = (uint16_t)ResDat[1]<<8|(ResDat[0]);
TemBuf = 40+TemBuf/256; //*10 结果*10倍 286即28.6℃;
*tem = TemBuf;
CapBuf = (uint16_t)ResDat[3]<<8|(ResDat[2]);
CapBuf = (CapBuf-OwHumB)*600/(OwHumA-OwHumB)+300;//同样结果*10
//20℃为5个湿度点 即1℃为0.25个湿度点 0.1℃为0.025
CapBuf = CapBuf+ 2.5*(TemBuf-250)/10;
if(CapBuf>999)CapBuf = 999;
else if(CapBuf<0)CapBuf=0;
*hum = (uint16_t)CapBuf;
}
return crc;
}

View File

@ -0,0 +1,81 @@
/*
* Copyright (c) 2020  Jinan Bosai Network Technology Co., LTD
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "pn532_hi3861.h"
#include "cmsis_os2.h"
#include "ohos_init.h"
#define TASK_STACK_SIZE 1024 * 8
#define TASK_PRIO 25
static void ExampleTask(void)
{
uint8_t buff[255];
uint8_t uid[MIFARE_UID_MAX_LENGTH];
int32_t uid_len = 0;
/* USER CODE BEGIN 2 */
printf("Hello!\r\n");
PN532 pn532;
// PN532_SPI_Init(&pn532);
PN532_I2C_Init(&pn532);
PN532_GetFirmwareVersion(&pn532, buff);
if (PN532_GetFirmwareVersion(&pn532, buff) == PN532_STATUS_OK) {
printf("Found PN532 with firmware version: %d.%d\r\n", buff[1], buff[2]);
} else {
return -1;
}
PN532_SamConfiguration(&pn532);
printf("Waiting for RFID/NFC card...\r\n");
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
// Check if a card is available to read
uid_len = PN532_ReadPassiveTarget(&pn532, uid, PN532_MIFARE_ISO14443A, 1000);
if (uid_len == PN532_STATUS_ERROR) {
printf(".");
} else {
printf("Found card with UID: ");
for (uint8_t i = 0; i < uid_len; i++) {
printf("%02x ", uid[i]);
}
printf("\r\n");
}
}
}
static void ExampleEntry(void)
{
osThreadAttr_t attr;
attr.name = "ExampleTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = TASK_STACK_SIZE;
attr.priority = TASK_PRIO;
if (osThreadNew((osThreadFunc_t)ExampleTask, NULL, &attr) == NULL) {
printf("Failed to create ExampleTask!\n");
}
}
APP_FEATURE_INIT(ExampleEntry);

26
app/A08_NFC/BUILD.gn Normal file
View File

@ -0,0 +1,26 @@
# Copyright (c) 2020  Jinan Bosai Network Technology Co., LTD
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_library("A08_NFC") {
sources = [
"src/pn532_hi3861.c",
"src/pn532.c",
"A08_NFC_example.c"
]
include_dirs = [
"//base/iot_hardware/peripheral/interfaces/kits",
"//device/bossay/hi3861_l0/iot_hardware_hals/include",
"include"
]
}

View File

@ -0,0 +1,81 @@
/*
* Copyright (c) 2020  Jinan Bosai Network Technology Co., LTD
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __MPU6050_H__
#define __MPU6050_H__
/* 宏定义 --------------------------------------------------------------------*/
#define MPU6050_GYRO_OUT 0x43 //MPU6050陀螺仪数据寄存器地址
#define MPU6050_ACC_OUT 0x3B //MPU6050加速度数据寄存器地址
#define MPU6050_SLAVE_ADDRESS 0x68 //MPU6050器件读地址
#define MPU6050_ADDRESS_AD0_LOW 0x68 // address pin low (GND), default for InvenSense evaluation board
#define MPU6050_RA_CONFIG 0x1A
#define MPU6050_RA_ACCEL_CONFIG 0x1C
#define MPU6050_RA_FF_THR 0x1D
#define MPU6050_RA_FF_DUR 0x1E
#define MPU6050_RA_MOT_THR 0x1F //运动检测阀值设置寄存器
#define MPU6050_RA_MOT_DUR 0x20 //运动检测时间阀值
#define MPU6050_RA_ZRMOT_THR 0x21
#define MPU6050_RA_ZRMOT_DUR 0x22
#define MPU6050_RA_FIFO_EN 0x23
#define MPU6050_RA_INT_PIN_CFG 0x37 //中断/旁路设置寄存器
#define MPU6050_RA_INT_ENABLE 0x38 //中断使能寄存器
#define MPU6050_RA_TEMP_OUT_H 0x41
#define MPU6050_RA_USER_CTRL 0x6A
#define MPU6050_RA_PWR_MGMT_1 0x6B
#define MPU6050_RA_WHO_AM_I 0x75
#define SENSOR_DATA_WIDTH_8_BIT 8 // 8 bit
#define ACCEL_DATA_LEN 6
#define TEMP_DATA_LEN 2
typedef enum
{
OFF = 0,
ON
} SwitchStatus;
enum AccelAxisNum {
ACCEL_X_AXIS = 0,
ACCEL_Y_AXIS = 1,
ACCEL_Z_AXIS = 2,
ACCEL_AXIS_NUM = 3,
};
enum AccelAxisPart {
ACCEL_X_AXIS_LSB = 0,
ACCEL_X_AXIS_MSB = 1,
ACCEL_Y_AXIS_LSB = 2,
ACCEL_Y_AXIS_MSB = 3,
ACCEL_Z_AXIS_LSB = 4,
ACCEL_Z_AXIS_MSB = 5,
ACCEL_AXIS_BUTT,
};
enum TempPart {
TEMP_LSB = 0,
TEMP_MSB = 1,
};
/* MPU6050传感器数据类型定义 ------------------------------------------------------------*/
typedef struct
{
short Temperature;
short Accel[3];
} MPU6050Data;
int BoardInit(void);
int MPU6050ReadData(MPU6050Data *ReadData);
void LedD1StatusSet(SwitchStatus status);
void LedD2StatusSet(SwitchStatus status);
#endif

277
app/A08_NFC/include/pn532.h Normal file
View File

@ -0,0 +1,277 @@
/**************************************************************************
* @file pn532.h
* @author Yehui from Waveshare
* @license BSD
*
* Header file for pn532.c
*
* Check out the links above for our tutorials and wiring diagrams
* These chips use SPI communicate.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documnetation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
**************************************************************************/
#ifndef PN532_H
#define PN532_H
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
#define PN532_PREAMBLE (0x00)
#define PN532_STARTCODE1 (0x00)
#define PN532_STARTCODE2 (0xFF)
#define PN532_POSTAMBLE (0x00)
#define PN532_HOSTTOPN532 (0xD4)
#define PN532_PN532TOHOST (0xD5)
// PN532 Commands
#define PN532_COMMAND_DIAGNOSE (0x00)
#define PN532_COMMAND_GETFIRMWAREVERSION (0x02)
#define PN532_COMMAND_GETGENERALSTATUS (0x04)
#define PN532_COMMAND_READREGISTER (0x06)
#define PN532_COMMAND_WRITEREGISTER (0x08)
#define PN532_COMMAND_READGPIO (0x0C)
#define PN532_COMMAND_WRITEGPIO (0x0E)
#define PN532_COMMAND_SETSERIALBAUDRATE (0x10)
#define PN532_COMMAND_SETPARAMETERS (0x12)
#define PN532_COMMAND_SAMCONFIGURATION (0x14)
#define PN532_COMMAND_POWERDOWN (0x16)
#define PN532_COMMAND_RFCONFIGURATION (0x32)
#define PN532_COMMAND_RFREGULATIONTEST (0x58)
#define PN532_COMMAND_INJUMPFORDEP (0x56)
#define PN532_COMMAND_INJUMPFORPSL (0x46)
#define PN532_COMMAND_INLISTPASSIVETARGET (0x4A)
#define PN532_COMMAND_INATR (0x50)
#define PN532_COMMAND_INPSL (0x4E)
#define PN532_COMMAND_INDATAEXCHANGE (0x40)
#define PN532_COMMAND_INCOMMUNICATETHRU (0x42)
#define PN532_COMMAND_INDESELECT (0x44)
#define PN532_COMMAND_INRELEASE (0x52)
#define PN532_COMMAND_INSELECT (0x54)
#define PN532_COMMAND_INAUTOPOLL (0x60)
#define PN532_COMMAND_TGINITASTARGET (0x8C)
#define PN532_COMMAND_TGSETGENERALBYTES (0x92)
#define PN532_COMMAND_TGGETDATA (0x86)
#define PN532_COMMAND_TGSETDATA (0x8E)
#define PN532_COMMAND_TGSETMETADATA (0x94)
#define PN532_COMMAND_TGGETINITIATORCOMMAND (0x88)
#define PN532_COMMAND_TGRESPONSETOINITIATOR (0x90)
#define PN532_COMMAND_TGGETTARGETSTATUS (0x8A)
#define PN532_RESPONSE_INDATAEXCHANGE (0x41)
#define PN532_RESPONSE_INLISTPASSIVETARGET (0x4B)
#define PN532_WAKEUP (0x55)
#define PN532_SPI_STATREAD (0x02)
#define PN532_SPI_DATAWRITE (0x01)
#define PN532_SPI_DATAREAD (0x03)
#define PN532_SPI_READY (0x01)
#define PN532_I2C_ADDRESS (0x48 >> 1)
#define PN532_I2C_READBIT (0x01)
#define PN532_I2C_BUSY (0x00)
#define PN532_I2C_READY (0x01)
#define PN532_I2C_READYTIMEOUT (20)
#define PN532_MIFARE_ISO14443A (0x00)
// Mifare Commands
#define MIFARE_CMD_AUTH_A (0x60)
#define MIFARE_CMD_AUTH_B (0x61)
#define MIFARE_CMD_READ (0x30)
#define MIFARE_CMD_WRITE (0xA0)
#define MIFARE_CMD_TRANSFER (0xB0)
#define MIFARE_CMD_DECREMENT (0xC0)
#define MIFARE_CMD_INCREMENT (0xC1)
#define MIFARE_CMD_STORE (0xC2)
#define MIFARE_ULTRALIGHT_CMD_WRITE (0xA2)
#define MIFARE_UID_MAX_LENGTH MIFARE_UID_TRIPLE_LENGTH
#define MIFARE_UID_SINGLE_LENGTH (4)
#define MIFARE_UID_DOUBLE_LENGTH (7)
#define MIFARE_UID_TRIPLE_LENGTH (10)
#define MIFARE_KEY_LENGTH (6)
#define MIFARE_BLOCK_LENGTH (16)
// NTAG2xx Commands
#define NTAG2XX_BLOCK_LENGTH (4)
// Prefixes for NDEF Records (to identify record type)
#define NDEF_URIPREFIX_NONE (0x00)
#define NDEF_URIPREFIX_HTTP_WWWDOT (0x01)
#define NDEF_URIPREFIX_HTTPS_WWWDOT (0x02)
#define NDEF_URIPREFIX_HTTP (0x03)
#define NDEF_URIPREFIX_HTTPS (0x04)
#define NDEF_URIPREFIX_TEL (0x05)
#define NDEF_URIPREFIX_MAILTO (0x06)
#define NDEF_URIPREFIX_FTP_ANONAT (0x07)
#define NDEF_URIPREFIX_FTP_FTPDOT (0x08)
#define NDEF_URIPREFIX_FTPS (0x09)
#define NDEF_URIPREFIX_SFTP (0x0A)
#define NDEF_URIPREFIX_SMB (0x0B)
#define NDEF_URIPREFIX_NFS (0x0C)
#define NDEF_URIPREFIX_FTP (0x0D)
#define NDEF_URIPREFIX_DAV (0x0E)
#define NDEF_URIPREFIX_NEWS (0x0F)
#define NDEF_URIPREFIX_TELNET (0x10)
#define NDEF_URIPREFIX_IMAP (0x11)
#define NDEF_URIPREFIX_RTSP (0x12)
#define NDEF_URIPREFIX_URN (0x13)
#define NDEF_URIPREFIX_POP (0x14)
#define NDEF_URIPREFIX_SIP (0x15)
#define NDEF_URIPREFIX_SIPS (0x16)
#define NDEF_URIPREFIX_TFTP (0x17)
#define NDEF_URIPREFIX_BTSPP (0x18)
#define NDEF_URIPREFIX_BTL2CAP (0x19)
#define NDEF_URIPREFIX_BTGOEP (0x1A)
#define NDEF_URIPREFIX_TCPOBEX (0x1B)
#define NDEF_URIPREFIX_IRDAOBEX (0x1C)
#define NDEF_URIPREFIX_FILE (0x1D)
#define NDEF_URIPREFIX_URN_EPC_ID (0x1E)
#define NDEF_URIPREFIX_URN_EPC_TAG (0x1F)
#define NDEF_URIPREFIX_URN_EPC_PAT (0x20)
#define NDEF_URIPREFIX_URN_EPC_RAW (0x21)
#define NDEF_URIPREFIX_URN_EPC (0x22)
#define NDEF_URIPREFIX_URN_NFC (0x23)
#define PN532_GPIO_VALIDATIONBIT (0x80)
/* Official PN532 Errors Definitions */
#define PN532_ERROR_NONE (0x00)
// Time Out, the target has not answered
#define PN532_ERROR_TIMEOUT (0x01)
// A CRC error has been detected by the CIU
#define PN532_ERROR_CRC (0x02)
// A Parity error has been detected by the CIU
#define PN532_ERROR_PARITY (0x03)
// During an anti-collision/select operation (ISO/IEC14443-3 Type A and
// ISO/IEC18092 106 kbps passive mode), an erroneous Bit Count has been
// detected
#define PN532_ERROR_COLLISION_BITCOUNT (0x04)
// Framing error during MIFARE operation
#define PN532_ERROR_MIFARE_FRAMING (0x05)
// An abnormal bit-collision has been detected during bit wise
// anti-collision at 106 kbps
#define PN532_ERROR_COLLISION_BITCOLLISION (0x06)
// Communication buffer size insufficien
#define PN532_ERROR_NOBUFS (0x07)
// RF Buffer overflow has been detected by the CI
#define PN532_ERROR_RFNOBUFS (0x09)
// In active communication mode, the RF field has not been switched on
// in time by the counterpart (as defined in NFCIP-1 standard
#define PN532_ERROR_ACTIVE_TOOSLOW (0x0a)
// RF Protocol error
#define PN532_ERROR_RFPROTO (0x0b)
// Temperature error: the internal temperature sensor has detected
// overheating, and therefore has automatically switched off the
// antenna drivers
#define PN532_ERROR_TOOHOT (0x0d)
// Internal buffer overflow
#define PN532_ERROR_INTERNAL_NOBUFS (0x0e)
// Invalid parameter (range, format...)
#define PN532_ERROR_INVAL (0x10)
// DEP Protocol: The PN533 configured in target mode does not support
// the command received from the initiator (the command received is not
// one of the following: ATR_REQ, WUP_REQ, PSL_REQ, DEP_REQ, DSL_REQ,
// RLS_REQ)
#define PN532_ERROR_DEP_INVALID_COMMAND (0x12)
// DEP Protocol, MIFARE or ISO/IEC14443-4: The data format does not
// match to the specification. Depending on the RF protocol used, it
// can be: Bad length of RF received frame, Incorrect value of PCB or
// PFB, Invalid or unexpected RF received frame, NAD or DID incoherence.
#define PN532_ERROR_DEP_BADDATA (0x13)
// MIFARE: Authentication error
#define PN532_ERROR_MIFARE_AUTH (0x14)
// Target or Initiator does not support NFC Secur
#define PN532_ERROR_NOSECURE (0x18)
// I2C bus line is Busy. A TDA transaction is on going
#define PN532_ERROR_I2CBUSY (0x19)
// ISO/IEC14443-3: UID Check byte is wrong
#define PN532_ERROR_UIDCHECKSUM (0x23)
// DEP Protocol: Invalid device state, the system is in a state which
// does not allow the operation
#define PN532_ERROR_DEPSTATE (0x25)
// Operation not allowed in this configuration (host controller
// interface)
#define PN532_ERROR_HCIINVAL (0x26)
// This command is not acceptable due to the current context of the
// PN533 (Initiator vs. Target, unknown target number, Target not in the
// good state, ...)
#define PN532_ERROR_CONTEXT (0x27)
// The PN533 configured as target has been released by its initiator
#define PN532_ERROR_RELEASED (0x29)
// PN533 and ISO/IEC14443-3B only: the ID of the card does not match,
// meaning that the expected card has been exchanged with another one.
#define PN532_ERROR_CARDSWAPPED (0x2a)
// PN533 and ISO/IEC14443-3B only: the card previously activated has
// disappeared.
#define PN532_ERROR_NOCARD (0x2b)
// Mismatch between the NFCID3 initiator and the NFCID3 target in DEP
// 212/424 kbps passive.
#define PN532_ERROR_MISMATCH (0x2c)
// An over-current event has been detected
#define PN532_ERROR_OVERCURRENT (0x2d)
// NAD missing in DEP frame
#define PN532_ERROR_NONAD (0x2e)
/* End: Official PN532 Errors Definitions */
// Other Error Definitions
#define PN532_STATUS_ERROR (-1)
#define PN532_STATUS_OK (0)
typedef struct _PN532 {
int (*reset)(void);
int (*read_data)(uint8_t* data, uint16_t count);
int (*write_data)(uint8_t *data, uint16_t count);
bool (*wait_ready)(uint32_t timeout);
int (*wakeup)(void);
void (*log)(const char* log);
} PN532;
int PN532_WriteFrame(PN532* pn532, uint8_t* data, uint16_t length);
int PN532_ReadFrame(PN532* pn532, uint8_t* buff, uint16_t length);
int PN532_CallFunction(PN532* pn532, uint8_t command, uint8_t* response, uint16_t response_length, uint8_t* params, uint16_t params_length, uint32_t timeout);
int PN532_GetFirmwareVersion(PN532* pn532, uint8_t* version);
int PN532_SamConfiguration(PN532* pn532);
int PN532_ReadPassiveTarget(PN532* pn532, uint8_t* response, uint8_t card_baud, uint32_t timeout);
int PN532_MifareClassicAuthenticateBlock(PN532* pn532, uint8_t* uid, uint8_t uid_length, uint16_t block_number, uint16_t key_number, uint8_t* key);
int PN532_MifareClassicReadBlock(PN532* pn532, uint8_t* response, uint16_t block_number);
int PN532_MifareClassicWriteBlock(PN532* pn532, uint8_t* data, uint16_t block_number);
int PN532_Ntag2xxReadBlock(PN532* pn532, uint8_t* response, uint16_t block_number);
int PN532_Ntag2xxWriteBlock(PN532* pn532, uint8_t* data, uint16_t block_number);
int PN532_ReadGpio(PN532* pn532, uint8_t* pins_state);
bool PN532_ReadGpioP(PN532* pn532, uint8_t pin_number);
bool PN532_ReadGpioI(PN532* pn532, uint8_t pin_number);
int PN532_WriteGpio(PN532* pn532, uint8_t* pins_state);
int PN532_WriteGpioP(PN532* pn532, uint8_t pin_number, bool pin_state);
#ifdef __cplusplus
}
#endif
#endif /* PN532_H */
/* End of file */

View File

@ -0,0 +1,48 @@
/**************************************************************************
* @file pn532_stm32f1.h
* @author Yehui from Waveshare
* @license BSD
*
* Header file for pn532_stm32f1.c
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documnetation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
**************************************************************************/
#ifndef PN532_STM32F1
#define PN532_STM32F1
#include "pn532.h"
void PN532_Init(PN532* dev);
int PN532_Reset(void);
void PN532_Log(const char* log);
int PN532_SPI_ReadData(uint8_t* data, uint16_t count);
int PN532_SPI_WriteData(uint8_t *data, uint16_t count);
bool PN532_SPI_WaitReady(uint32_t timeout);
int PN532_SPI_Wakeup(void);
void PN532_SPI_Init(PN532* dev);
int PN532_I2C_ReadData(uint8_t* data, uint16_t count);
int PN532_I2C_WriteData(uint8_t *data, uint16_t count);
bool PN532_I2C_WaitReady(uint32_t timeout);
int PN532_I2C_Wakeup(void);
void PN532_I2C_Init(PN532* dev);
#endif /* PN532_STM32F1 */

381
app/A08_NFC/src/MPU6050.c Normal file
View File

@ -0,0 +1,381 @@
/*
* Copyright (c) 2020  Jinan Bosai Network Technology Co., LTD
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "MPU6050.h"
#include "cmsis_os2.h"
#include "iot_errno.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#include "iot_i2c.h"
#include "iot_i2c_ex.h"
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define WIFI_IOT_IO_FUNC_GPIO_0_I2C1_SDA 6
#define WIFI_IOT_IO_FUNC_GPIO_1_I2C1_SCL 6
#define WIFI_IOT_IO_FUNC_GPIO_8_GPIO 0
#define WIFI_IOT_IO_FUNC_GPIO_7_GPIO 0
#define WIFI_IOT_I2C_IDX_1 1
#define WIFI_IOT_IO_NAME_GPIO_7 7
#define WIFI_IOT_IO_NAME_GPIO_8 8
#define WIFI_IOT_IO_NAME_GPIO_0 0
#define WIFI_IOT_IO_NAME_GPIO_1 1
#define RESET_DELAY_US 20000
#define READ_DATA_DELAY_US 50000
/***************************************************************
* : GpioInit
* : GPIO初始化
* :
* :
***************************************************************/
static void GpioInit(void)
{
IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_8);
IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_8, WIFI_IOT_IO_FUNC_GPIO_8_GPIO);
IoTGpioSetDir(WIFI_IOT_IO_NAME_GPIO_8, IOT_GPIO_DIR_OUT); // 设置GPIO_8为输出模式
IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_7);
IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_7, WIFI_IOT_IO_FUNC_GPIO_7_GPIO);
IoTGpioSetDir(WIFI_IOT_IO_NAME_GPIO_7, IOT_GPIO_DIR_OUT); // 设置GPIO_7为输出模式
IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_0);
IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_0, WIFI_IOT_IO_FUNC_GPIO_0_I2C1_SDA); // GPIO_0复用为I2C1_SDA
IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_1);
IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_1, WIFI_IOT_IO_FUNC_GPIO_1_I2C1_SCL); // GPIO_1复用为I2C1_SCL
IoTI2cInit(WIFI_IOT_I2C_IDX_1, 400000); /* baudrate: 400kbps */
}
/***************************************************************
* : I2C写入一个值到指定寄存器内
* : AddrI2C设备地址
* Reg
* Value
* :
* :
**************************************************************/
static int MPU6050WriteData(uint8_t Reg, uint8_t Value)
{
uint32_t ret;
uint8_t send_data[2] = {Reg, Value};
ret = IoTI2cWrite(WIFI_IOT_I2C_IDX_1, (MPU6050_SLAVE_ADDRESS << 1) | 0x00, send_data, 2);
if (ret != 0) {
printf("===== Error: I2C write ret = 0x%x! =====\r\n", ret);
return -1;
}
return 0;
}
/***************************************************************
* : I2C写入一段数据到指定寄存器内
* : AddrI2C设备地址
* Reg
* RegSize(816)
* pBuffer
* Length
* : HAL_StatusTypeDef
* :
**************************************************************/
static int MPU6050WriteBuffer(uint8_t Reg, uint8_t* pBuffer, uint16_t Length)
{
uint32_t ret = 0;
uint8_t send_data[256] = {0};
send_data[0] = Reg;
for (int j = 0; j < Length; j++) {
send_data[j + 1] = pBuffer[j];
}
ret = IoTI2cWrite(WIFI_IOT_I2C_IDX_1, (MPU6050_SLAVE_ADDRESS << 1) | 0x00, send_data, Length + 1);
if (ret != 0) {
printf("===== Error: I2C write ret = 0x%x! =====\r\n", ret);
return -1;
}
return 0;
}
/***************************************************************
* : I2C读取一段寄存器内容存放到指定的缓冲区内
* : AddrI2C设备地址
* Reg
* RegSize(816)
* pBuffer
* Length
* : HAL_StatusTypeDef
* :
**************************************************************/
static int MPU6050ReadBuffer(uint8_t Reg, uint8_t* pBuffer, uint16_t Length)
{
uint32_t ret = 0;
IotI2cData mpu6050_i2c_data = {0};
uint8_t buffer[1] = {Reg};
mpu6050_i2c_data.sendBuf = buffer;
mpu6050_i2c_data.sendLen = 1;
mpu6050_i2c_data.receiveBuf = pBuffer;
mpu6050_i2c_data.receiveLen = Length;
ret = IoTI2cWriteread(WIFI_IOT_I2C_IDX_1, (MPU6050_SLAVE_ADDRESS << 1) | 0x00, &mpu6050_i2c_data);
if (ret != 0) {
printf("===== Error: I2C writeread ret = 0x%x! =====\r\n", ret);
return -1;
}
return 0;
}
/***************************************************************
* : MPU6050寄存器
* :
* :
* :
***************************************************************/
static void MPU6050WriteReg(uint8_t reg_add, uint8_t reg_dat)
{
MPU6050WriteData(reg_add, reg_dat);
}
/***************************************************************
* : MPU6050寄存器读取数据
* :
* :
* :
***************************************************************/
static int MPU6050Read(uint8_t reg_add, unsigned char* read, uint8_t num)
{
return MPU6050ReadBuffer(reg_add, read, num);
}
/***************************************************************
* : MPU6050的加速度数据
* :
* :
* :
***************************************************************/
static int MPU6050ReadAcc(short* accData)
{
int ret;
uint8_t buf[ACCEL_DATA_LEN];
ret = MPU6050Read(MPU6050_ACC_OUT, buf, ACCEL_DATA_LEN);
if (ret != 0) {
return -1;
}
accData[ACCEL_X_AXIS] = (buf[ACCEL_X_AXIS_LSB] << SENSOR_DATA_WIDTH_8_BIT) | buf[ACCEL_X_AXIS_MSB];
accData[ACCEL_Y_AXIS] = (buf[ACCEL_Y_AXIS_LSB] << SENSOR_DATA_WIDTH_8_BIT) | buf[ACCEL_Y_AXIS_MSB];
accData[ACCEL_Z_AXIS] = (buf[ACCEL_Z_AXIS_LSB] << SENSOR_DATA_WIDTH_8_BIT) | buf[ACCEL_Z_AXIS_MSB];
return 0;
}
/***************************************************************
* : MPU6050的角速度数据
* :
* :
* :
***************************************************************/
static int MPU6050ReadGyro(short* gyroData)
{
int ret;
uint8_t buf[ACCEL_DATA_LEN];
ret = MPU6050Read(MPU6050_GYRO_OUT, buf, ACCEL_DATA_LEN);
if (ret != 0) {
return -1;
}
gyroData[ACCEL_X_AXIS] = (buf[ACCEL_X_AXIS_LSB] << SENSOR_DATA_WIDTH_8_BIT) | buf[ACCEL_X_AXIS_MSB];
gyroData[ACCEL_Y_AXIS] = (buf[ACCEL_Y_AXIS_LSB] << SENSOR_DATA_WIDTH_8_BIT) | buf[ACCEL_Y_AXIS_MSB];
gyroData[ACCEL_Z_AXIS] = (buf[ACCEL_Z_AXIS_LSB] << SENSOR_DATA_WIDTH_8_BIT) | buf[ACCEL_Z_AXIS_MSB];
return 0;
}
/***************************************************************
* : MPU6050的原始温度数据
* :
* :
* :
***************************************************************/
static int MPU6050ReadTemp(short* tempData)
{
int ret;
uint8_t buf[TEMP_DATA_LEN];
ret = MPU6050Read(MPU6050_RA_TEMP_OUT_H, buf, TEMP_DATA_LEN); // 读取温度值
if (ret != 0) {
return -1;
}
*tempData = (buf[TEMP_LSB] << SENSOR_DATA_WIDTH_8_BIT) | buf[TEMP_MSB];
return 0;
}
/***************************************************************
* : MPU6050的温度数据
* :
* :
* :
**************************************************************/
static int MPU6050ReturnTemp(short* Temperature)
{
int ret;
short temp3;
uint8_t buf[TEMP_DATA_LEN];
ret = MPU6050Read(MPU6050_RA_TEMP_OUT_H, buf, TEMP_DATA_LEN); // 读取温度值
if (ret != 0) {
return -1;
}
temp3 = (buf[TEMP_LSB] << SENSOR_DATA_WIDTH_8_BIT) | buf[TEMP_MSB];
*Temperature = (((double)(temp3 + 13200)) / 280) - 13;
return 0;
}
/***************************************************************
* :
* :
* :
* :
**************************************************************/
void FreeFallInterrupt(void) // 自由落体中断
{
MPU6050WriteReg(MPU6050_RA_FF_THR, 0x01); // 自由落体阈值
MPU6050WriteReg(MPU6050_RA_FF_DUR, 0x01); // 自由落体检测时间20ms 单位1ms 寄存器0X20
}
void MotionInterrupt(void) // 运动中断
{
MPU6050WriteReg(MPU6050_RA_MOT_THR, 0x03); // 运动阈值
MPU6050WriteReg(MPU6050_RA_MOT_DUR, 0x14); // 检测时间20ms 单位1ms 寄存器0X20
}
void ZeroMotionInterrupt(void) // 静止中断
{
MPU6050WriteReg(MPU6050_RA_ZRMOT_THR, 0x20); // 静止阈值
MPU6050WriteReg(MPU6050_RA_ZRMOT_DUR, 0x20); // 静止检测时间20ms 单位1ms 寄存器0X20
}
/***************************************************************
* : MPU6050芯片
* :
* :
* :
***************************************************************/
void MPU6050Init(void)
{
MPU6050WriteReg(MPU6050_RA_PWR_MGMT_1, 0X80); // 复位MPU6050
usleep(RESET_DELAY_US);
MPU6050WriteReg(MPU6050_RA_PWR_MGMT_1, 0X00); // 唤醒MPU6050
MPU6050WriteReg(MPU6050_RA_INT_ENABLE, 0X00); // 关闭所有中断
MPU6050WriteReg(MPU6050_RA_USER_CTRL, 0X00); // I2C主模式关闭
MPU6050WriteReg(MPU6050_RA_FIFO_EN, 0X00); // 关闭FIFO
MPU6050WriteReg(MPU6050_RA_INT_PIN_CFG,
0X80); // 中断的逻辑电平模式,设置为0中断信号为高电设置为1中断信号为低电平时。
MotionInterrupt(); // 运动中断
MPU6050WriteReg(MPU6050_RA_CONFIG, 0x04); // 配置外部引脚采样和DLPF数字低通滤波器
MPU6050WriteReg(MPU6050_RA_ACCEL_CONFIG, 0x1C); // 加速度传感器量程和高通滤波器配置
MPU6050WriteReg(MPU6050_RA_INT_PIN_CFG, 0X1C); // INT引脚低电平平时
MPU6050WriteReg(MPU6050_RA_INT_ENABLE, 0x40); // 中断使能寄存器
}
/***************************************************************
* : MPU6050的ID
* :
* :
* :
***************************************************************/
int MPU6050ReadID(void)
{
unsigned char Re = 0;
MPU6050Read(MPU6050_RA_WHO_AM_I, &Re, 1); // 读器件地址
if (Re != 0x68) {
printf("MPU6050 dectected error!\r\n");
return -1;
} else {
return 0;
}
}
/***************************************************************
* : BoardInit
* :
* :
* :
***************************************************************/
int BoardInit(void)
{
uint32_t ret = 0;
GpioInit();
MPU6050Init();
ret = MPU6050ReadID();
if (ret != 0) {
return -1;
}
osDelay(100);
return 0;
}
/***************************************************************
* : MPU6050ReadData
* :
* :
* :
***************************************************************/
int MPU6050ReadData(MPU6050Data* ReadData)
{
int ret;
short Accel[3];
short Temp;
if (MPU6050ReadID() != 0) {
return -1;
}
ret = MPU6050ReadAcc(Accel);
if (ret != 0) {
return -1;
}
ret = MPU6050ReturnTemp(&Temp);
if (ret != 0) {
return -1;
}
ReadData->Temperature = Temp;
ReadData->Accel[ACCEL_X_AXIS] = Accel[ACCEL_X_AXIS];
ReadData->Accel[ACCEL_Y_AXIS] = Accel[ACCEL_Y_AXIS];
ReadData->Accel[ACCEL_Z_AXIS] = Accel[ACCEL_Z_AXIS];
usleep(READ_DATA_DELAY_US);
return 0;
}
/***************************************************************
* : LedD1StatusSet
* : LED_D1状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void LedD1StatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(7, 1); // 设置GPIO_7输出高电平点亮灯
}
if (status == OFF) {
IoTGpioSetOutputVal(7, 0); // 设置GPIO_7输出低电平关闭灯
}
}
/***************************************************************
* : LedD2StatusSet
* : LED_D2状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void LedD2StatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(8, 1); // 设置GPIO_8输出高电平点亮灯
}
if (status == OFF) {
IoTGpioSetOutputVal(8, 0); // 设置GPIO_8输出低电平关闭灯
}
}

498
app/A08_NFC/src/pn532.c Normal file
View File

@ -0,0 +1,498 @@
/**************************************************************************
* @file pn532.c
* @author Yehui from Waveshare
* @license BSD
*
* This is a library for the Waveshare PN532 NFC modules
*
* Check out the links above for our tutorials and wiring diagrams
* These chips use SPI communicate.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documnetation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
**************************************************************************/
#include <stdio.h>
#include "pn532.h"
const uint8_t PN532_ACK[] = {0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00};
const uint8_t PN532_FRAME_START[] = {0x00, 0x00, 0xFF};
#define PN532_FRAME_MAX_LENGTH 255
#define PN532_DEFAULT_TIMEOUT 1000
/**
* @brief: Write a frame to the PN532 of at most length bytes in size.
* Note that less than length bytes might be returned!
* @retval: Returns -1 if there is an error parsing the frame.
*/
int PN532_WriteFrame(PN532* pn532, uint8_t* data, uint16_t length) {
if (length > PN532_FRAME_MAX_LENGTH || length < 1) {
return PN532_STATUS_ERROR; // Data must be array of 1 to 255 bytes.
}
// Build frame to send as:
// - Preamble (0x00)
// - Start code (0x00, 0xFF)
// - Command length (1 byte)
// - Command length checksum
// - Command bytes
// - Checksum
// - Postamble (0x00)
uint8_t frame[PN532_FRAME_MAX_LENGTH + 7];
uint8_t checksum = 0;
frame[0] = PN532_PREAMBLE;
frame[1] = PN532_STARTCODE1;
frame[2] = PN532_STARTCODE2;
for (uint8_t i = 0; i < 3; i++) {
checksum += frame[i];
}
frame[3] = length & 0xFF;
frame[4] = (~length + 1) & 0xFF;
for (uint8_t i = 0; i < length; i++) {
frame[5 + i] = data[i];
checksum += data[i];
}
frame[length + 5] = ~checksum & 0xFF;
frame[length + 6] = PN532_POSTAMBLE;
if (pn532->write_data(frame, length + 7) != PN532_STATUS_OK) {
return PN532_STATUS_ERROR;
}
return PN532_STATUS_OK;
}
/**
* @brief: Read a response frame from the PN532 of at most length bytes in size.
* Note that less than length bytes might be returned!
* @retval: Returns frame length or -1 if there is an error parsing the frame.
*/
int PN532_ReadFrame(PN532* pn532, uint8_t* response, uint16_t length) {
uint8_t buff[PN532_FRAME_MAX_LENGTH + 7];
uint8_t checksum = 0;
// Read frame with expected length of data.
pn532->read_data(buff, length + 7);
// Swallow all the 0x00 values that preceed 0xFF.
uint8_t offset = 0;
while (buff[offset] == 0x00) {
offset += 1;
if (offset >= length + 8){
pn532->log("Response frame preamble does not contain 0x00FF!");
return PN532_STATUS_ERROR;
}
}
if (buff[offset] != 0xFF) {
pn532->log("Response frame preamble does not contain 0x00FF!");
return PN532_STATUS_ERROR;
}
offset += 1;
if (offset >= length + 8) {
pn532->log("Response contains no data!");
return PN532_STATUS_ERROR;
}
// Check length & length checksum match.
uint8_t frame_len = buff[offset];
if (((frame_len + buff[offset+1]) & 0xFF) != 0) {
pn532->log("Response length checksum did not match length!");
return PN532_STATUS_ERROR;
}
// Check frame checksum value matches bytes.
for (uint8_t i = 0; i < frame_len + 1; i++) {
checksum += buff[offset + 2 + i];
}
checksum &= 0xFF;
if (checksum != 0) {
pn532->log("Response checksum did not match expected checksum");
return PN532_STATUS_ERROR;
}
// Return frame data.
for (uint8_t i = 0; i < frame_len; i++) {
response[i] = buff[offset + 2 + i];
}
return frame_len;
}
/**
* @brief: Send specified command to the PN532 and expect up to response_length.
* Will wait up to timeout seconds for a response and read a bytearray into
* response buffer.
* @param pn532: PN532 handler
* @param command: command to send
* @param response: buffer returned
* @param response_length: expected response length
* @param params: can optionally specify an array of bytes to send as parameters
* to the function call, or NULL if there is no need to send parameters.
* @param params_length: length of the argument params
* @param timeout: timout of systick
* @retval: Returns the length of response or -1 if error.
*/
int PN532_CallFunction(
PN532* pn532,
uint8_t command,
uint8_t* response,
uint16_t response_length,
uint8_t* params,
uint16_t params_length,
uint32_t timeout
) {
// Build frame data with command and parameters.
uint8_t buff[PN532_FRAME_MAX_LENGTH];
buff[0] = PN532_HOSTTOPN532;
buff[1] = command & 0xFF;
for (uint8_t i = 0; i < params_length; i++) {
buff[2 + i] = params[i];
}
// Send frame and wait for response.
if (PN532_WriteFrame(pn532, buff, params_length + 2) != PN532_STATUS_OK) {
pn532->wakeup();
pn532->log("Trying to wakeup");
return PN532_STATUS_ERROR;
}
if (!pn532->wait_ready(timeout)) {
return PN532_STATUS_ERROR;
}
// Verify ACK response and wait to be ready for function response.
pn532->read_data(buff, sizeof(PN532_ACK));
for (uint8_t i = 0; i < sizeof(PN532_ACK); i++) {
if (PN532_ACK[i] != buff[i]) {
pn532->log("Did not receive expected ACK from PN532!");
return PN532_STATUS_ERROR;
}
}
if (!pn532->wait_ready(timeout)) {
return PN532_STATUS_ERROR;
}
// Read response bytes.
int frame_len = PN532_ReadFrame(pn532, buff, response_length + 2);
// Check that response is for the called function.
if (! ((buff[0] == PN532_PN532TOHOST) && (buff[1] == (command+1)))) {
pn532->log("Received unexpected command response!");
return PN532_STATUS_ERROR;
}
// Return response data.
for (uint8_t i = 0; i < response_length; i++) {
response[i] = buff[i + 2];
}
// The the number of bytes read
return frame_len - 2;
}
/**
* @brief: Call PN532 GetFirmwareVersion function and return a buff with the IC,
* Ver, Rev, and Support values.
*/
int PN532_GetFirmwareVersion(PN532* pn532, uint8_t* version) {
// length of version: 4
if (PN532_CallFunction(pn532, PN532_COMMAND_GETFIRMWAREVERSION,
version, 4, NULL, 0, 500) == PN532_STATUS_ERROR) {
pn532->log("Failed to detect the PN532");
return PN532_STATUS_ERROR;
}
return PN532_STATUS_OK;
}
/**
* @brief: Configure the PN532 to read MiFare cards.
*/
int PN532_SamConfiguration(PN532* pn532) {
// Send SAM configuration command with configuration for:
// - 0x01, normal mode
// - 0x14, timeout 50ms * 20 = 1 second
// - 0x01, use IRQ pin
// Note that no other verification is necessary as call_function will
// check the command was executed as expected.
uint8_t params[] = {0x01, 0x14, 0x01};
PN532_CallFunction(pn532, PN532_COMMAND_SAMCONFIGURATION,
NULL, 0, params, sizeof(params), PN532_DEFAULT_TIMEOUT);
return PN532_STATUS_OK;
}
/**
* @brief: Wait for a MiFare card to be available and return its UID when found.
* Will wait up to timeout seconds and return None if no card is found,
* otherwise a bytearray with the UID of the found card is returned.
* @retval: Length of UID, or -1 if error.
*/
int PN532_ReadPassiveTarget(
PN532* pn532,
uint8_t* response,
uint8_t card_baud,
uint32_t timeout
) {
// Send passive read command for 1 card. Expect at most a 7 byte UUID.
uint8_t params[] = {0x01, card_baud};
uint8_t buff[19];
int length = PN532_CallFunction(pn532, PN532_COMMAND_INLISTPASSIVETARGET,
buff, sizeof(buff), params, sizeof(params), timeout);
if (length < 0) {
return PN532_STATUS_ERROR; // No card found
}
// Check only 1 card with up to a 7 byte UID is present.
if (buff[0] != 0x01) {
pn532->log("More than one card detected!");
return PN532_STATUS_ERROR;
}
if (buff[5] > 7) {
pn532->log("Found card with unexpectedly long UID!");
return PN532_STATUS_ERROR;
}
for (uint8_t i = 0; i < buff[5]; i++) {
response[i] = buff[6 + i];
}
return buff[5];
}
/**
* @brief: Authenticate specified block number for a MiFare classic card.
* @param uid: A byte array with the UID of the card.
* @param uid_length: Length of the UID of the card.
* @param block_number: The block to authenticate.
* @param key_number: The key type (like MIFARE_CMD_AUTH_A or MIFARE_CMD_AUTH_B).
* @param key: A byte array with the key data.
* @retval: true if the block was authenticated, or false if not authenticated.
* @retval: PN532 error code.
*/
int PN532_MifareClassicAuthenticateBlock(
PN532* pn532,
uint8_t* uid,
uint8_t uid_length,
uint16_t block_number,
uint16_t key_number,
uint8_t* key
) {
// Build parameters for InDataExchange command to authenticate MiFare card.
uint8_t response[1] = {0xFF};
uint8_t params[3 + MIFARE_UID_MAX_LENGTH + MIFARE_KEY_LENGTH];
params[0] = 0x01;
params[1] = key_number & 0xFF;
params[2] = block_number & 0xFF;
// params[3:3+keylen] = key
for (uint8_t i = 0; i < MIFARE_KEY_LENGTH; i++) {
params[3 + i] = key[i];
}
// params[3+keylen:] = uid
for (uint8_t i = 0; i < uid_length; i++) {
params[3 + MIFARE_KEY_LENGTH + i] = uid[i];
}
// Send InDataExchange request
PN532_CallFunction(pn532, PN532_COMMAND_INDATAEXCHANGE, response, sizeof(response),
params, 3 + MIFARE_KEY_LENGTH + uid_length, PN532_DEFAULT_TIMEOUT);
return response[0];
}
/**
* @brief: Read a block of data from the card. Block number should be the block
* to read.
* @param response: buffer of length 16 returned if the block is successfully read.
* @param block_number: specify a block to read.
* @retval: PN532 error code.
*/
int PN532_MifareClassicReadBlock(PN532* pn532, uint8_t* response, uint16_t block_number) {
uint8_t params[] = {0x01, MIFARE_CMD_READ, block_number & 0xFF};
uint8_t buff[MIFARE_BLOCK_LENGTH + 1];
// Send InDataExchange request to read block of MiFare data.
PN532_CallFunction(pn532, PN532_COMMAND_INDATAEXCHANGE, buff, sizeof(buff),
params, sizeof(params), PN532_DEFAULT_TIMEOUT);
// Check first response is 0x00 to show success.
if (buff[0] != PN532_ERROR_NONE) {
return buff[0];
}
for (uint8_t i = 0; i < MIFARE_BLOCK_LENGTH; i++) {
response[i] = buff[i + 1];
}
return buff[0];
}
/**
* @brief: Write a block of data to the card. Block number should be the block
* to write and data should be a byte array of length 16 with the data to
* write.
* @param data: data to write.
* @param block_number: specify a block to write.
* @retval: PN532 error code.
*/
int PN532_MifareClassicWriteBlock(PN532* pn532, uint8_t* data, uint16_t block_number) {
uint8_t params[MIFARE_BLOCK_LENGTH + 3];
uint8_t response[1];
params[0] = 0x01; // Max card numbers
params[1] = MIFARE_CMD_WRITE;
params[2] = block_number & 0xFF;
for (uint8_t i = 0; i < MIFARE_BLOCK_LENGTH; i++) {
params[3 + i] = data[i];
}
PN532_CallFunction(pn532, PN532_COMMAND_INDATAEXCHANGE, response,
sizeof(response), params, sizeof(params), PN532_DEFAULT_TIMEOUT);
return response[0];
}
/**
* @brief: Read a block of data from the card. Block number should be the block
* to read.
* @param response: buffer of length 4 returned if the block is successfully read.
* @param block_number: specify a block to read.
* @retval: PN532 error code.
*/
int PN532_Ntag2xxReadBlock(PN532* pn532, uint8_t* response, uint16_t block_number) {
uint8_t params[] = {0x01, MIFARE_CMD_READ, block_number & 0xFF};
// The response length of NTAG2xx is same as Mifare's
uint8_t buff[MIFARE_BLOCK_LENGTH + 1];
// Send InDataExchange request to read block of MiFare data.
PN532_CallFunction(pn532, PN532_COMMAND_INDATAEXCHANGE, buff, sizeof(buff),
params, sizeof(params), PN532_DEFAULT_TIMEOUT);
// Check first response is 0x00 to show success.
if (buff[0] != PN532_ERROR_NONE) {
return buff[0];
}
// Although the response length of NTAG2xx is same as Mifare's,
// only the first 4 bytes are available
for (uint8_t i = 0; i < NTAG2XX_BLOCK_LENGTH; i++) {
response[i] = buff[i + 1];
}
return buff[0];
}
/**
* @brief: Write a block of data to the card. Block number should be the block
* to write and data should be a byte array of length 4 with the data to
* write.
* @param data: data to write.
* @param block_number: specify a block to write.
* @retval: PN532 error code.
*/
int PN532_Ntag2xxWriteBlock(PN532* pn532, uint8_t* data, uint16_t block_number) {
uint8_t params[NTAG2XX_BLOCK_LENGTH + 3];
uint8_t response[1];
params[0] = 0x01; // Max card numbers
params[1] = MIFARE_ULTRALIGHT_CMD_WRITE;
params[2] = block_number & 0xFF;
for (uint8_t i = 0; i < NTAG2XX_BLOCK_LENGTH; i++) {
params[3 + i] = data[i];
}
PN532_CallFunction(pn532, PN532_COMMAND_INDATAEXCHANGE, response,
sizeof(response), params, sizeof(params), PN532_DEFAULT_TIMEOUT);
return response[0];
}
/**
* @brief: Read the GPIO states.
* @param pin_state: pin state buffer (3 bytes) returned.
* returns 3 bytes containing the pin state where:
* P3[0] = P30, P7[0] = 0, I[0] = I0,
* P3[1] = P31, P7[1] = P71, I[1] = I1,
* P3[2] = P32, P7[2] = P72, I[2] = 0,
* P3[3] = P33, P7[3] = 0, I[3] = 0,
* P3[4] = P34, P7[4] = 0, I[4] = 0,
* P3[5] = P35, P7[5] = 0, I[5] = 0,
* P3[6] = 0, P7[6] = 0, I[6] = 0,
* P3[7] = 0, P7[7] = 0, I[7] = 0,
* @retval: -1 if error
*/
int PN532_ReadGpio(PN532* pn532, uint8_t* pins_state) {
return PN532_CallFunction(pn532, PN532_COMMAND_READGPIO, pins_state, 3,
NULL, 0, PN532_DEFAULT_TIMEOUT);
}
/**
* @brief: Read the GPIO state of specified pins in (P30 ... P35).
* @param pin_number: specify the pin to read.
* @retval: true if HIGH, false if LOW
*/
bool PN532_ReadGpioP(PN532* pn532, uint8_t pin_number) {
uint8_t pins_state[3];
PN532_CallFunction(pn532, PN532_COMMAND_READGPIO, pins_state,
sizeof(pins_state), NULL, 0, PN532_DEFAULT_TIMEOUT);
if ((pin_number >= 30) && (pin_number <= 37)) {
return (pins_state[0] >> (pin_number - 30)) & 1 ? true : false;
}
if ((pin_number >= 70) && (pin_number <= 77)) {
return (pins_state[1] >> (pin_number - 70)) & 1 ? true : false;
}
return false;
}
/**
* @brief: Read the GPIO state of I0 or I1 pin.
* @param pin_number: specify the pin to read.
* @retval: true if HIGH, false if LOW
*/
bool PN532_ReadGpioI(PN532* pn532, uint8_t pin_number) {
uint8_t pins_state[3];
PN532_CallFunction(pn532, PN532_COMMAND_READGPIO, pins_state,
sizeof(pins_state), NULL, 0, PN532_DEFAULT_TIMEOUT);
if (pin_number <= 7) {
return (pins_state[2] >> pin_number) & 1 ? true : false;
}
return false;
}
/**
* @brief: Write the GPIO states.
* @param pins_state: pin state buffer (2 bytes) to write.
* no need to read pin states before write with the param pin_state
* P3 = pin_state[0], P7 = pin_state[1]
* bits:
* P3[0] = P30, P7[0] = 0,
* P3[1] = P31, P7[1] = P71,
* P3[2] = P32, P7[2] = P72,
* P3[3] = P33, P7[3] = nu,
* P3[4] = P34, P7[4] = nu,
* P3[5] = P35, P7[5] = nu,
* P3[6] = nu, P7[6] = nu,
* P3[7] = Val, P7[7] = Val,
* For each port that is validated (bit Val = 1), all the bits are applied
* simultaneously. It is not possible for example to modify the state of
* the port P32 without applying a value to the ports P30, P31, P33, P34
* and P35.
* @retval: -1 if error
*/
int PN532_WriteGpio(PN532* pn532, uint8_t* pins_state) {
uint8_t params[2];
// 0x80, the validation bit.
params[0] = 0x80 | pins_state[0];
params[1] = 0x80 | pins_state[1];
return PN532_CallFunction(pn532, PN532_COMMAND_WRITEGPIO, NULL, 0,
params, sizeof(params), PN532_DEFAULT_TIMEOUT);
}
/**
* @brief: Write the specified pin with given states.
* @param pin_number: specify the pin to write.
* @param pin_state: specify the pin state. true for HIGH, false for LOW.
* @retval: -1 if error
*/
int PN532_WriteGpioP(PN532* pn532, uint8_t pin_number, bool pin_state) {
uint8_t pins_state[2];
uint8_t params[2];
if (PN532_ReadGpio(pn532, pins_state) == PN532_STATUS_ERROR) {
return PN532_STATUS_ERROR;
}
if ((pin_number >= 30) && (pin_number <= 37)) {
if (pin_state) {
params[0] = 0x80 | pins_state[0] | 1 << (pin_number - 30);
} else {
params[0] = (0x80 | pins_state[0]) & ~(1 << (pin_number - 30));
}
params[1] = 0x00; // leave p7 unchanged
}
if ((pin_number >= 70) && (pin_number <= 77)) {
if (pin_state) {
params[1] = 0x80 | pins_state[1] | 1 << (pin_number - 70);
} else {
params[1] = (0x80 | pins_state[1]) & ~(1 << (pin_number - 70));
}
params[0] = 0x00; // leave p3 unchanged
}
return PN532_CallFunction(pn532, PN532_COMMAND_WRITEGPIO, NULL, 0,
params, sizeof(params), PN532_DEFAULT_TIMEOUT);
}

View File

@ -0,0 +1,172 @@
/**************************************************************************
* @file pn532_stm32f1.c
* @author Yehui from Waveshare
* @license BSD
*
* This implements the peripheral interfaces.
*
* Check out the links above for our tutorials and wiring diagrams
* These chips use SPI communicate.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documnetation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
**************************************************************************/
// #include "stm32f1xx_hal.h"
// #include "main.h"
#include "pn532_hi3861.h"
#include "cmsis_os2.h"
#include "iot_errno.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#include "iot_i2c.h"
#include "iot_i2c_ex.h"
#define RESET_GPIO 14
#define WIFI_IOT_I2C_IDX_1 1
#define _I2C_ADDRESS 0x24
#define _I2C_TIMEOUT 10
#define WIFI_IOT_IO_FUNC_GPIO_0_I2C1_SDA 6
#define WIFI_IOT_IO_FUNC_GPIO_1_I2C1_SCL 6
#define WIFI_IOT_I2C_IDX_1 1
#define WIFI_IOT_IO_NAME_GPIO_7 7
#define WIFI_IOT_IO_NAME_GPIO_8 8
#define WIFI_IOT_IO_NAME_GPIO_0 0
#define WIFI_IOT_IO_NAME_GPIO_1 1
#define MAX30102_INIT_GPIO 7
/***************************************************************
* : GpioInit
* : GPIO初始化
* :
* :
***************************************************************/
void BoardInit(void)
{
IoTGpioInit(RESET_GPIO);
IoTGpioSetFunc(RESET_GPIO, IOT_GPIO_FUNC_GPIO_14_GPIO);
IoTGpioSetDir(RESET_GPIO, IOT_GPIO_DIR_OUT); // 设置GPIO_8为输出模式
// IoTGpioInit(MAX30102_INIT_GPIO);
// IoTGpioSetFunc(MAX30102_INIT_GPIO, IOT_GPIO_FUNC_GPIO_7_GPIO);
// IoTGpioSetDir(MAX30102_INIT_GPIO, IOT_GPIO_DIR_IN); // 设置GPIO_7为输出模式
IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_0);
IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_0, WIFI_IOT_IO_FUNC_GPIO_0_I2C1_SDA); // GPIO_0复用为I2C1_SDA
IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_1);
IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_1, WIFI_IOT_IO_FUNC_GPIO_1_I2C1_SCL); // GPIO_1复用为I2C1_SCL
IoTI2cInit(WIFI_IOT_I2C_IDX_1, 400000); /* baudrate: 400kbps */
}
/**************************************************************************
* Reset and Log implements
**************************************************************************/
int PN532_Reset(void) {
IoTGpioSetOutputVal(RESET_GPIO, 1);
osDelay(100);
IoTGpioSetOutputVal(RESET_GPIO, 0);
osDelay(500);
IoTGpioSetOutputVal(RESET_GPIO, 1);
osDelay(100);
return PN532_STATUS_OK;
}
void PN532_Log(const char* log) {
printf("%s\r\n", log);
}
/**************************************************************************
* End: Reset and Log implements
**************************************************************************/
/**************************************************************************
* I2C
**************************************************************************/
void I2cRead(uint8_t* data, uint16_t count) {
// HAL_I2C_Master_Receive(&hi2c1, _I2C_ADDRESS, data, count, _I2C_TIMEOUT);
IoTI2cRead(WIFI_IOT_I2C_IDX_1, (_I2C_ADDRESS << 1) | 0x01, data, count);
}
void I2cWrite(uint8_t* data, uint16_t count) {
// HAL_I2C_Master_Transmit(&hi2c1, _I2C_ADDRESS, data, count, _I2C_TIMEOUT);
IoTI2cWrite(WIFI_IOT_I2C_IDX_1, (_I2C_ADDRESS << 1) | 0x00, data, count);
}
int PN532_I2C_ReadData(uint8_t* data, uint16_t count) {
uint8_t status[] = {0x00};
uint8_t frame[count + 1];
I2cRead(status, sizeof(status));
if (status[0] != PN532_I2C_READY) {
return PN532_STATUS_ERROR;
}
I2cRead(frame, count + 1);
for (uint8_t i = 0; i < count; i++) {
data[i] = frame[i + 1];
}
return PN532_STATUS_OK;
}
int PN532_I2C_WriteData(uint8_t *data, uint16_t count) {
I2cWrite(data, count);
return PN532_STATUS_OK;
}
bool PN532_I2C_WaitReady(uint32_t timeout) {
uint8_t status[] = {0x00};
uint32_t tickstart = osKernelGetTickCount();
while (osKernelGetTickCount() - tickstart < timeout) {
I2cRead(status, sizeof(status));
if (status[0] == PN532_I2C_READY) {
return true;
} else {
osDelay(5);
}
}
return false;
}
int PN532_I2C_Wakeup(void) {
// TODO
// HAL_GPIO_WritePin(PN532_REQ_GPIO_Port, PN532_REQ_Pin, GPIO_PIN_SET);
osDelay(100);
// HAL_GPIO_WritePin(PN532_REQ_GPIO_Port, PN532_REQ_Pin, GPIO_PIN_RESET);
osDelay(100);
// HAL_GPIO_WritePin(PN532_REQ_GPIO_Port, PN532_REQ_Pin, GPIO_PIN_SET);
osDelay(500);
return PN532_STATUS_OK;
}
void PN532_I2C_Init(PN532* pn532) {
BoardInit();
// init the pn532 functions
pn532->reset = PN532_Reset;
pn532->read_data = PN532_I2C_ReadData;
pn532->write_data = PN532_I2C_WriteData;
pn532->wait_ready = PN532_I2C_WaitReady;
pn532->wakeup = PN532_I2C_Wakeup;
pn532->log = PN532_Log;
// hardware wakeup
pn532->wakeup();
}
/**************************************************************************
* End: I2C
**************************************************************************/

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2022 Jinan Bosai Network Technology Co., LTD Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "elevator.h"
#include "cmsis_os2.h"
#include "ohos_init.h"
#define TASK_STACK_SIZE 1024 * 8
#define TASK_PRIO 25
static void ExampleTask(void)
{
int ret;
// uint8_t dht_temperature;
// uint8_t dht_humidity;
// float Lux;
// BoardInit();
//GPIO_0复用为I2C1_SDA
BoardInit();
while (1)
{
if(ElevatorReadData() == 0)
{
printf("Near the flame!\n");
FanStatusSet(ON);
}
else
{
printf("Far the flame!\n");
FanStatusSet(OFF);
}
sleep(1);
}
}
static void ExampleEntry(void)
{
osThreadAttr_t attr;
attr.name = "ExampleTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = TASK_STACK_SIZE;
attr.priority = TASK_PRIO;
if (osThreadNew((osThreadFunc_t)ExampleTask, NULL, &attr) == NULL) {
printf("Failed to create ExampleTask!\n");
}
}
APP_FEATURE_INIT(ExampleEntry);

26
app/A09_Elevator/BUILD.gn Normal file
View File

@ -0,0 +1,26 @@
# Copyright (c) 2020  Jinan Bosai Network Technology Co., LTD
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_library("A09_Elevator") {
sources = [
"src/elevator.c",
"A09_Elevator_example.c"
]
include_dirs = [
"//base/iot_hardware/peripheral/interfaces/kits",
"//device/bossay/hi3861_l0/iot_hardware_hals/include",
"//device/bossay/hi3861_l0/sdk_liteos/include",
"include"
]
}

View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2020  Jinan Bosai Network Technology Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __Elevator_H__
#define __Elevator_H__
#include <stdint.h>
typedef enum
{
OFF = 0,
ON
} SwitchStatus;
void BoardInit(void);
uint8_t ElevatorReadData(void);
void FanStatusSet(SwitchStatus status);
#endif /* __Elevator_H__ */

View File

@ -0,0 +1,237 @@
/*
* Copyright (c) 2022 Jinan Bosai Network Technology Co., LTD Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "elevator.h"
#include "cmsis_os2.h"
#include "iot_errno.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#include "iot_i2c.h"
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define WIFI_IOT_IO_FUNC_GPIO_0_I2C1_SDA 6
#define WIFI_IOT_IO_FUNC_GPIO_1_I2C1_SCL 6
#define WIFI_IOT_IO_FUNC_GPIO_7_GPIO 0
#define WIFI_IOT_I2C_IDX_1 1
#define LED1 12
#define LED2 7
#define LED3 14
#define LED4 10
#define LED5 13
// #define LED6 14
// #define LED7 7
// #define LED8 8
// #define LED9 1
// #define LED10 0
#define OUT_GPIO 2
/***************************************************************
* : BoardInit
* : GPIO初始化
* :
* :
***************************************************************/
void BoardInit(void)
{
IoTGpioInit(LED1);
IoTGpioSetFunc(LED1, IOT_GPIO_FUNC_GPIO_12_GPIO);
IoTGpioSetDir(LED1, IOT_GPIO_DIR_OUT); //设置为输出模式
IoTGpioInit(LED2);
IoTGpioSetFunc(LED2, IOT_GPIO_FUNC_GPIO_7_GPIO);
IoTGpioSetDir(LED2, IOT_GPIO_DIR_OUT); //设置为输出模式
IoTGpioInit(LED3);
IoTGpioSetFunc(LED3, IOT_GPIO_FUNC_GPIO_14_GPIO);
IoTGpioSetDir(LED3, IOT_GPIO_DIR_OUT); //设置为输出模式
IoTGpioInit(LED4);
IoTGpioSetFunc(LED4, IOT_GPIO_FUNC_GPIO_10_GPIO);
IoTGpioSetDir(LED4, IOT_GPIO_DIR_OUT); //设置为输出模式
IoTGpioInit(LED5);
IoTGpioSetFunc(LED5, IOT_GPIO_FUNC_GPIO_13_GPIO);
IoTGpioSetDir(LED5, IOT_GPIO_DIR_OUT); //设置为输出模式
// IoTGpioInit(LED6);
// IoTGpioSetFunc(LED6, IOT_GPIO_FUNC_GPIO_14_GPIO);
// IoTGpioSetDir(LED6, IOT_GPIO_DIR_OUT); //设置为输出模式
// IoTGpioInit(LED7);
// IoTGpioSetFunc(LED7, IOT_GPIO_FUNC_GPIO_7_GPIO);
// IoTGpioSetDir(LED7, IOT_GPIO_DIR_OUT); //设置为输出模式
// IoTGpioInit(LED8);
// IoTGpioSetFunc(LED8, IOT_GPIO_FUNC_GPIO_8_GPIO);
// IoTGpioSetDir(LED8, IOT_GPIO_DIR_OUT); //设置为输出模式
// IoTGpioInit(LED9);
// IoTGpioSetFunc(LED9, IOT_GPIO_FUNC_GPIO_1_GPIO);
// IoTGpioSetDir(LED9, IOT_GPIO_DIR_OUT); //设置为输出模式
// IoTGpioInit(LED10);
// IoTGpioSetFunc(LED10, IOT_GPIO_FUNC_GPIO_0_GPIO);
// IoTGpioSetDir(LED10, IOT_GPIO_DIR_OUT); //设置为输出模式
IoTGpioInit(OUT_GPIO);
IoTGpioSetFunc(OUT_GPIO, IOT_GPIO_FUNC_GPIO_2_GPIO);
IoTGpioSetDir(OUT_GPIO, IOT_GPIO_DIR_IN); // 设置为输入模式
}
/***************************************************************
* : ElevatorReadData
* :
* :
* :
***************************************************************/
uint8_t ElevatorReadData(void)
{
IotGpioValue temp = {0};
IoTGpioGetInputVal(OUT_GPIO,&temp);
return temp;
}
/***************************************************************
* : FanStatusSet
* :
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void FanStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(LED1, 0);
IoTGpioSetOutputVal(LED2, 1);
IoTGpioSetOutputVal(LED3, 1);
IoTGpioSetOutputVal(LED4, 1);
IoTGpioSetOutputVal(LED5, 1);
// IoTGpioSetOutputVal(LED6, 1);
// IoTGpioSetOutputVal(LED7, 1);
// IoTGpioSetOutputVal(LED8, 1);
// IoTGpioSetOutputVal(LED9, 1);
// IoTGpioSetOutputVal(LED10, 0);
osDelay(20);
IoTGpioSetOutputVal(LED1, 0);
IoTGpioSetOutputVal(LED2, 0);
IoTGpioSetOutputVal(LED3, 1);
IoTGpioSetOutputVal(LED4, 1);
IoTGpioSetOutputVal(LED5, 1);
// IoTGpioSetOutputVal(LED6, 1);
// IoTGpioSetOutputVal(LED7, 1);
// IoTGpioSetOutputVal(LED8, 1);
// IoTGpioSetOutputVal(LED9, 0);
// IoTGpioSetOutputVal(LED10, 0);
osDelay(20);
IoTGpioSetOutputVal(LED1, 0);
IoTGpioSetOutputVal(LED2, 0);
IoTGpioSetOutputVal(LED3, 0);
IoTGpioSetOutputVal(LED4, 1);
IoTGpioSetOutputVal(LED5, 1);
// IoTGpioSetOutputVal(LED6, 1);
// IoTGpioSetOutputVal(LED7, 1);
// IoTGpioSetOutputVal(LED8, 0);
// IoTGpioSetOutputVal(LED9, 0);
// IoTGpioSetOutputVal(LED10, 0);
osDelay(20);
IoTGpioSetOutputVal(LED1, 0);
IoTGpioSetOutputVal(LED2, 0);
IoTGpioSetOutputVal(LED3, 0);
IoTGpioSetOutputVal(LED4, 0);
IoTGpioSetOutputVal(LED5, 1);
// IoTGpioSetOutputVal(LED6, 1);
// IoTGpioSetOutputVal(LED7, 0);
// IoTGpioSetOutputVal(LED8, 0);
// IoTGpioSetOutputVal(LED9, 0);
// IoTGpioSetOutputVal(LED10, 0);
osDelay(20);
IoTGpioSetOutputVal(LED1, 0);
IoTGpioSetOutputVal(LED2, 0);
IoTGpioSetOutputVal(LED3, 0);
IoTGpioSetOutputVal(LED4, 0);
IoTGpioSetOutputVal(LED5, 0);
// IoTGpioSetOutputVal(LED6, 0);
// IoTGpioSetOutputVal(LED7, 0);
// IoTGpioSetOutputVal(LED8, 0);
// IoTGpioSetOutputVal(LED9, 0);
// IoTGpioSetOutputVal(LED10, 0);
}
if (status == OFF) {
IoTGpioSetOutputVal(LED1, 0);
IoTGpioSetOutputVal(LED2, 0);
IoTGpioSetOutputVal(LED3, 0);
IoTGpioSetOutputVal(LED4, 0);
IoTGpioSetOutputVal(LED5, 1);
// IoTGpioSetOutputVal(LED6, 1);
// IoTGpioSetOutputVal(LED7, 0);
// IoTGpioSetOutputVal(LED8, 0);
// IoTGpioSetOutputVal(LED9, 0);
// IoTGpioSetOutputVal(LED10, 0);
osDelay(20);
IoTGpioSetOutputVal(LED1, 0);
IoTGpioSetOutputVal(LED2, 0);
IoTGpioSetOutputVal(LED3, 0);
IoTGpioSetOutputVal(LED4, 1);
IoTGpioSetOutputVal(LED5, 1);
// IoTGpioSetOutputVal(LED6, 1);
// IoTGpioSetOutputVal(LED7, 1);
// IoTGpioSetOutputVal(LED8, 0);
// IoTGpioSetOutputVal(LED9, 0);
// IoTGpioSetOutputVal(LED10, 0);
osDelay(20);
IoTGpioSetOutputVal(LED1, 0);
IoTGpioSetOutputVal(LED2, 0);
IoTGpioSetOutputVal(LED3, 1);
IoTGpioSetOutputVal(LED4, 1);
IoTGpioSetOutputVal(LED5, 1);
// IoTGpioSetOutputVal(LED6, 1);
// IoTGpioSetOutputVal(LED7, 1);
// IoTGpioSetOutputVal(LED8, 1);
// IoTGpioSetOutputVal(LED9, 0);
// IoTGpioSetOutputVal(LED10, 0);
osDelay(20);
IoTGpioSetOutputVal(LED1, 0);
IoTGpioSetOutputVal(LED2, 1);
IoTGpioSetOutputVal(LED3, 1);
IoTGpioSetOutputVal(LED4, 1);
IoTGpioSetOutputVal(LED5, 1);
// IoTGpioSetOutputVal(LED6, 1);
// IoTGpioSetOutputVal(LED7, 1);
// IoTGpioSetOutputVal(LED8, 1);
// IoTGpioSetOutputVal(LED9, 1);
// IoTGpioSetOutputVal(LED10, 0);
osDelay(20);
IoTGpioSetOutputVal(LED1, 1);
IoTGpioSetOutputVal(LED2, 1);
IoTGpioSetOutputVal(LED3, 1);
IoTGpioSetOutputVal(LED4, 1);
IoTGpioSetOutputVal(LED5, 1);
// IoTGpioSetOutputVal(LED6, 1);
// IoTGpioSetOutputVal(LED7, 1);
// IoTGpioSetOutputVal(LED8, 1);
// IoTGpioSetOutputVal(LED9, 1);
// IoTGpioSetOutputVal(LED10, 1);
}
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2022 Jinan Bosai Network Technology Co., LTD Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "PM2_5.h"
#include "cmsis_os2.h"
#include "ohos_init.h"
#define TASK_STACK_SIZE 1024 * 8
#define TASK_PRIO 25
static void ExampleTask(void)
{
PM2D5Data data;
BoardInit();
// LedWarnStatusSet(ON);
LedSafeStatusSet(ON);
while (1) {
PM2DReadData(&data);
printf("\r\n******************************PM1.0 is %d\r\n", data.pm1_0);
printf("\r\n******************************PM2.5 is %d\r\n", data.pm2_5);
printf("\r\n******************************PM10 is %d\r\n", data.pm10);
sleep(1);
}
}
static void ExampleEntry(void)
{
osThreadAttr_t attr;
attr.name = "ExampleTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = TASK_STACK_SIZE;
attr.priority = TASK_PRIO;
if (osThreadNew((osThreadFunc_t)ExampleTask, NULL, &attr) == NULL) {
printf("Failed to create ExampleTask!\n");
}
}
APP_FEATURE_INIT(ExampleEntry);

26
app/A11_PM2_5/BUILD.gn Normal file
View File

@ -0,0 +1,26 @@
# Copyright (c) 2022 Jinan Bosai Network Technology Co., LTD Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_library("A11_PM2_5") {
sources = [
"src/PM2_5.c",
"A11_PM2_5_example.c"
]
include_dirs = [
"//base/iot_hardware/peripheral/interfaces/kits",
"//device/bossay/hi3861_l0/iot_hardware_hals/include",
"//device/bossay/hi3861_l0/sdk_liteos/include",
"include"
]
}

View File

@ -0,0 +1,30 @@
#ifndef __PM_2_5_H__
#define __PM_2_5_H__
#include <stdint.h>
typedef enum
{
OFF = 0,
ON
} SwitchStatus;
typedef struct
{
uint32_t pm1_0;
uint32_t pm2_5;
uint32_t pm10;
} PM2D5Data;
void BoardInit(void);
uint8_t Button_Left_Read_Data(void);
void PM2DReadData(PM2D5Data* ReadData);
void LedWarnStatusSet(SwitchStatus status);
void LedSafeStatusSet(SwitchStatus status);
#endif

120
app/A11_PM2_5/src/PM2_5.c Normal file
View File

@ -0,0 +1,120 @@
#include "PM2_5.h"
#include "iot_errno.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#include "iot_uart.h"
#include "stdio.h"
#define RESET_GPIO 7
#define LED_SAFE_GPIO 8
#define LED_WARN_GPIO 14
#define SET_GPIO 13
#define WIFI_IOT_UART_IDX_1 1
uint8_t RxBuffer[3];
void BoardInit(void)
{
IoTGpioInit(RESET_GPIO);
IoTGpioSetFunc(RESET_GPIO, IOT_GPIO_FUNC_GPIO_7_GPIO);
IoTGpioSetDir(RESET_GPIO, IOT_GPIO_DIR_OUT); // 设置为输出模式
IoTGpioSetOutputVal(RESET_GPIO, 1);
IoTGpioInit(LED_SAFE_GPIO);
IoTGpioSetFunc(LED_SAFE_GPIO, IOT_GPIO_FUNC_GPIO_8_GPIO);
IoTGpioSetDir(LED_SAFE_GPIO, IOT_GPIO_DIR_OUT); // 设置为输出模式
IoTGpioInit(LED_WARN_GPIO);
IoTGpioSetFunc(LED_WARN_GPIO, IOT_GPIO_FUNC_GPIO_14_GPIO);
IoTGpioSetDir(LED_WARN_GPIO, IOT_GPIO_DIR_OUT); // 设置为输出模式
IoTGpioInit(SET_GPIO);
IoTGpioSetFunc(SET_GPIO, IOT_GPIO_FUNC_GPIO_13_GPIO);
IoTGpioSetDir(SET_GPIO, IOT_GPIO_DIR_OUT); // 设置为输入模式
IoTGpioSetOutputVal(SET_GPIO, 1);
uint32_t ret;
IotUartAttribute uart_attr = {
// baud_rate: 9600
.baudRate = 9600,
// data_bits: 8bits
.dataBits = 8,
.stopBits = 1,
.parity = 0,
};
// Initialize uart driver
ret = IoTUartInit(WIFI_IOT_UART_IDX_1, &uart_attr);
if (ret != IOT_SUCCESS) {
printf("Failed to init uart! Err code = %d\n", ret);
return;
}
}
static unsigned char read_date[32];
/***************************************************************
* : PM2DReadData
* : GPS经纬度信息
* :
* :
***************************************************************/
void PM2DReadData(PM2D5Data* ReadData)
{
//通过串口1接收数据
IoTUartRead(WIFI_IOT_UART_IDX_1, read_date, 32);
// for(int i = 0; i<32; i++)
// {
// printf("%d------%x\r\n",i,read_date[i]);
// }
if(read_date[0]== 0x42 && read_date[1]== 0x4d)
{
ReadData->pm1_0=read_date[2]<<8|read_date[3];
ReadData->pm2_5=read_date[4]<<8|read_date[5];
ReadData->pm10=read_date[6]<<8|read_date[7];
}
}
/***************************************************************
* : LedWarnStatusSet
* : LED_Warn状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void LedWarnStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(LED_WARN_GPIO, 1); // 设置输出高电平点亮灯
}
if (status == OFF) {
IoTGpioSetOutputVal(LED_WARN_GPIO, 0); // 设置输出低电平关闭灯
}
}
/***************************************************************
* : LedSafeStatusSet
* : LED_Safe状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void LedSafeStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(LED_SAFE_GPIO, 1); // 设置输出高电平点亮灯
}
if (status == OFF) {
IoTGpioSetOutputVal(LED_SAFE_GPIO, 0); // 设置输出低电平关闭灯
}
}

View File

@ -0,0 +1,78 @@
/*
* Copyright (c) 2020  Jinan Bosai Network Technology Co., LTD
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <math.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "SOCKET.h"
#define TASK_STACK_SIZE 1024*8
#define TASK_PRIO 25
static void ExampleTask(void)
{
BoardInit();
while (1) {
printf("=======================================\r\n");
printf("*************A12_SOCKET_example***********\r\n");
printf("=======================================\r\n");
RelayStatusSet(ON);
LedRedStatusSet(OFF);
LedGreenStatusSet(OFF);
LedBlueStatusSet(ON);
osDelay(200);
LedRedStatusSet(ON);
LedGreenStatusSet(OFF);
LedBlueStatusSet(OFF);
osDelay(200);
LedRedStatusSet(OFF);
LedGreenStatusSet(ON);
LedBlueStatusSet(OFF);
osDelay(200);
// LedBlueStatusSet(ON);
}
}
/**
* @brief Main Entry of the A22_MQ2 Example
*
*/
static void ExampleEntry(void)
{
osThreadAttr_t attr;
attr.name = "ExampleTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = TASK_STACK_SIZE;
attr.priority = TASK_PRIO;
if (osThreadNew((osThreadFunc_t)ExampleTask, NULL, &attr) == NULL) {
printf("Failed to create ExampleTask!\n");
}
}
APP_FEATURE_INIT(ExampleEntry);

25
app/A12_SOCKET/BUILD.gn Normal file
View File

@ -0,0 +1,25 @@
# Copyright (c) 2022 Jinan Bosai Network Technology Co., LTD Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_library("A12_SOCKET") {
sources = [
"src/SOCKET.c",
"A12_SOCKET_example.c"
]
include_dirs = [
"//base/iot_hardware/peripheral/interfaces/kits",
"//device/bossay/hi3861_l0/iot_hardware_hals/include",
"include"
]
}

View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2022 Jinan Bosai Network Technology Co., LTD Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __SOCKET_H__
#define __SOCKET_H__
typedef enum
{
OFF = 0,
ON
} SwitchStatus;
void BoardInit(void);
void RelayStatusSet(SwitchStatus status);
void LedRedStatusSet(SwitchStatus status);
void LedGreenStatusSet(SwitchStatus status);
void LedBlueStatusSet(SwitchStatus status);
#endif /* __SOCKET_H__ */

126
app/A12_SOCKET/src/SOCKET.c Normal file
View File

@ -0,0 +1,126 @@
/*
* Copyright (c) 2022 Jinan Bosai Network Technology Co., LTD Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "SOCKET.h"
#include "iot_errno.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#define RELAY_GPIO 14
#define LED_RED_GPIO 7
#define LED_GREEN_GPIO 8
#define LED_BLUE_GPIO 13
/***************************************************************
* : BoardInit
* :
* :
* :
***************************************************************/
void BoardInit(void)
{
IoTGpioInit(RELAY_GPIO);
IoTGpioSetFunc(RELAY_GPIO, IOT_GPIO_FUNC_GPIO_14_GPIO);
IoTGpioSetDir(RELAY_GPIO, IOT_GPIO_DIR_OUT); //设置为输出模式
IoTGpioInit(LED_RED_GPIO);
IoTGpioSetFunc(LED_RED_GPIO, IOT_GPIO_FUNC_GPIO_7_GPIO);
IoTGpioSetDir(LED_RED_GPIO, IOT_GPIO_DIR_OUT); //设置为输出模式
IoTGpioInit(LED_GREEN_GPIO);
IoTGpioSetFunc(LED_GREEN_GPIO, IOT_GPIO_FUNC_GPIO_8_GPIO);
IoTGpioSetDir(LED_GREEN_GPIO, IOT_GPIO_DIR_OUT); //设置为输出模式
IoTGpioInit(LED_BLUE_GPIO);
IoTGpioSetFunc(LED_BLUE_GPIO, IOT_GPIO_FUNC_GPIO_13_GPIO);
IoTGpioSetDir(LED_BLUE_GPIO, IOT_GPIO_DIR_OUT); //设置为输出模式
}
/***************************************************************
* : RelayStatusSet
* :
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void RelayStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(RELAY_GPIO, 1); //设置输出高电平点亮LED灯
}
if (status == OFF) {
IoTGpioSetOutputVal(RELAY_GPIO, 0); //设置输出低电平点亮LED灯
}
}
/***************************************************************
* : LedRedStatusSet
* :
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void LedRedStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(LED_RED_GPIO, 0); //设置输出高电平点亮LED灯
}
if (status == OFF) {
IoTGpioSetOutputVal(LED_RED_GPIO, 1); //设置输出低电平点亮LED灯
}
}
/***************************************************************
* : LedGreenStatusSet
* :
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void LedGreenStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(LED_GREEN_GPIO, 0); //设置输出高电平点亮LED灯
}
if (status == OFF) {
IoTGpioSetOutputVal(LED_GREEN_GPIO, 1); //设置输出低电平点亮LED灯
}
}
/***************************************************************
* : LedBlueStatusSet
* :
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void LedBlueStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(LED_BLUE_GPIO, 0); //设置输出高电平点亮LED灯
}
if (status == OFF) {
IoTGpioSetOutputVal(LED_BLUE_GPIO, 1); //设置输出低电平点亮LED灯
}
}

View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 2020  Jinan Bosai Network Technology Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "flame.h"
#include "cmsis_os2.h"
#include "ohos_init.h"
#define TASK_STACK_SIZE 1024 * 8
#define TASK_PRIO 25
static void ExampleTask(void)
{
float ad_value;
FlameInit();
usleep(1000000);
while (1)
{
ad_value = GetVoltage();
if(FlameReadData() == 0)
{
printf("Near the flame!\n");
printf("ad_value:%2.2fV\n",ad_value);
BeepStatusSet(ON);
LedWarnStatusSet(ON);
}
else{
printf("Far the flame!\n");
printf("ad_value:%2.2fV\n",ad_value);
BeepStatusSet(OFF);
LedWarnStatusSet(OFF);
}
sleep(1);
}
}
static void ExampleEntry(void)
{
osThreadAttr_t attr;
attr.name = "ExampleTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = TASK_STACK_SIZE;
attr.priority = TASK_PRIO;
if (osThreadNew((osThreadFunc_t)ExampleTask, NULL, &attr) == NULL) {
printf("Failed to create ExampleTask!\n");
}
}
APP_FEATURE_INIT(ExampleEntry);

26
app/A13_FLAME/BUILD.gn Normal file
View File

@ -0,0 +1,26 @@
# Copyright (c) 2020  Jinan Bosai Network Technology Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_library("A13_FLAME") {
sources = [
"src/flame.c",
"A13_FLAME_example..c"
]
include_dirs = [
"//base/iot_hardware/peripheral/interfaces/kits",
"//device/bossay/hi3861_l0/iot_hardware_hals/include",
"//device/bossay/hi3861_l0/sdk_liteos/include",
"include"
]
}

View File

@ -0,0 +1,23 @@
#ifndef __FLAME_H__
#define __FLAME_H__
#include <stdint.h>
typedef enum
{
OFF = 0,
ON
} SwitchStatus;
void FlameInit(void);
float GetVoltage(void);
uint8_t FlameReadData(void);
void BeepStatusSet(SwitchStatus status);
void LedWarnStatusSet(SwitchStatus status);
#endif

103
app/A13_FLAME/src/flame.c Normal file
View File

@ -0,0 +1,103 @@
#include "flame.h"
#include "iot_adc.h"
#include "iot_errno.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#define WIFI_IOT_IO_NAME_GPIO_8 8
#define WIFI_IOT_IO_NAME_GPIO_14 14
#define OUT_GPIO 7
void FlameInit(void)
{
IoTGpioInit(OUT_GPIO);
IoTGpioSetFunc(OUT_GPIO, IOT_GPIO_FUNC_GPIO_7_GPIO);
IoTGpioSetDir(OUT_GPIO, IOT_GPIO_DIR_IN); // 设置GPIO_8为输出模式
// IoTGpioInit(13);
// IoTGpioSetFunc(13, IOT_GPIO_FUNC_GPIO_13_GPIO);
// IoTGpioSetDir(13, IOT_GPIO_DIR_IN); // 设置GPIO_8为输出模式
IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_14);
IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_14, IOT_GPIO_FUNC_GPIO_14_GPIO);
IoTGpioSetDir(WIFI_IOT_IO_NAME_GPIO_14, IOT_GPIO_DIR_OUT);
IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_8);
IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_8, IOT_GPIO_FUNC_GPIO_8_GPIO);
IoTGpioSetDir(WIFI_IOT_IO_NAME_GPIO_8, IOT_GPIO_DIR_OUT);
}
/***************************************************************
* : GetVoltage
* :
* :
*
* :
***************************************************************/
float GetVoltage(void)
{
unsigned int ret;
unsigned short data;
ret = IoTAdcRead(6, &data, IOT_ADC_EQU_MODEL_8, IOT_ADC_CUR_BAIS_DEFAULT, 0xff);
if (ret != IOT_SUCCESS)
{
printf("ADC Read Fail\n");
}
return (float)data * 1.8 * 4 / 4096.0;
}
/***************************************************************
* : FlameReadData
* :
* :
* :
***************************************************************/
uint8_t FlameReadData(void)
{
IotGpioValue temp = {0};
IoTGpioGetInputVal(OUT_GPIO,&temp);
return temp;
}
/***************************************************************
* : BeepStatusSet
* : Beep状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void BeepStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, 1); // 设置GPIO_7输出高电平点亮灯
}
if (status == OFF) {
IoTGpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, 0); // 设置GPIO_7输出低电平关闭灯
}
}
/***************************************************************
* : LedWarnStatusSet
* : LED_Warn状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void LedWarnStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_14, 1); // 设置GPIO_14输出高电平点亮灯
}
if (status == OFF) {
IoTGpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_14, 0); // 设置GPIO_14输出低电平关闭灯
}
}

View File

@ -0,0 +1,112 @@
/*
* Copyright (c) 2022 Jinan Bosai Network Technology Co., LTD Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "DOOR.h"
#include "cmsis_os2.h"
#include "ohos_init.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#include "hi_time.h"
#define TASK_STACK_SIZE 1024 * 8
#define TASK_PRIO 25
#define GPIO_0 10
#define GPIO_1 12
float GetDistance (void) {
static unsigned long start_time = 0, time = 0;
float distance = 0.0;
IotGpioValue value = IOT_GPIO_VALUE0;
unsigned int flag = 0;
IoTWatchDogDisable();
// hi_io_set_func(GPIO_8, GPIO_FUNC);
IoTGpioInit(GPIO_0);
IoTGpioSetFunc(GPIO_0, IOT_GPIO_FUNC_GPIO_10_GPIO);
IoTGpioSetDir(GPIO_0, IOT_GPIO_DIR_IN);
IoTGpioInit(GPIO_1);
IoTGpioSetFunc(GPIO_1, IOT_GPIO_FUNC_GPIO_12_GPIO);
IoTGpioSetDir(GPIO_1, IOT_GPIO_DIR_OUT);
IoTGpioSetOutputVal(GPIO_1, IOT_GPIO_VALUE1);
hi_udelay(20);
IoTGpioSetOutputVal(GPIO_1, IOT_GPIO_VALUE0);
while (1) {
IoTGpioGetInputVal(GPIO_0, &value);
if ( value == IOT_GPIO_VALUE1 && flag == 0) {
start_time = hi_get_us();
flag = 1;
}
if (value == IOT_GPIO_VALUE0 && flag == 1) {
time = hi_get_us() - start_time;
start_time = 0;
break;
}
}
distance = time * 0.034 / 2;
return distance;
}
static void ExampleTask(void)
{
IotGpioValue value = IOT_GPIO_VALUE0;
// IoTGpioInit(11);
// IoTGpioSetFunc(11, IOT_GPIO_FUNC_GPIO_11_GPIO);
// IoTGpioSetPull(11,IOT_GPIO_PULL_UP);
// IoTGpioSetDir(11, IOT_GPIO_DIR_IN);
printf("start test hcsr04\r\n");
while (1) {
// IoTGpioGetInputVal(11, &value);
// if (value == IOT_GPIO_VALUE0) {
float distance = GetDistance();
printf("distance is %f\r\n", distance);
//
// }
osDelay(100);
}
}
static void ExampleEntry(void)
{
osThreadAttr_t attr;
attr.name = "ExampleTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = TASK_STACK_SIZE;
attr.priority = TASK_PRIO;
if (osThreadNew((osThreadFunc_t)ExampleTask, NULL, &attr) == NULL) {
printf("Failed to create ExampleTask!\n");
}
}
APP_FEATURE_INIT(ExampleEntry);

26
app/A14_CAR/BUILD.gn Normal file
View File

@ -0,0 +1,26 @@
# Copyright (c) 2022 Jinan Bosai Network Technology Co., LTD Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_library("A14_CAR") {
sources = [
"src/DOOR.c",
"A01_DOOR_example.c"
]
include_dirs = [
"//base/iot_hardware/peripheral/interfaces/kits",
"//device/bossay/hi3861_l0/iot_hardware_hals/include",
"//device/bossay/hi3861_l0/sdk_liteos/include",
"include"
]
}

View File

@ -0,0 +1,23 @@
#ifndef __DOOR_H__
#define __DOOR_H__
#include <stdint.h>
typedef enum
{
OFF = 0,
ON
} SwitchStatus;
void BoardInit(void);
uint8_t Button_Left_Read_Data(void);
void BeepStatusSet(SwitchStatus status);
void LedWarnStatusSet(SwitchStatus status);
void LedSafeStatusSet(SwitchStatus status);
#endif

98
app/A14_CAR/src/DOOR.c Normal file
View File

@ -0,0 +1,98 @@
#include "DOOR.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#define OUT_GPIO 13
#define LED_SAFE_GPIO 7
#define LED_WARN_GPIO 14
#define BEEP_GPIO 8
void BoardInit(void)
{
IoTGpioInit(OUT_GPIO);
IoTGpioSetFunc(OUT_GPIO, IOT_GPIO_FUNC_GPIO_13_GPIO);
IoTGpioSetDir(OUT_GPIO, IOT_GPIO_DIR_IN); // 设置GPIO_8为输出模式
IoTGpioInit(LED_SAFE_GPIO);
IoTGpioSetFunc(LED_SAFE_GPIO, IOT_GPIO_FUNC_GPIO_7_GPIO);
IoTGpioSetDir(LED_SAFE_GPIO, IOT_GPIO_DIR_OUT); // 设置为输出模式
IoTGpioInit(LED_WARN_GPIO);
IoTGpioSetFunc(LED_WARN_GPIO, IOT_GPIO_FUNC_GPIO_14_GPIO);
IoTGpioSetDir(LED_WARN_GPIO, IOT_GPIO_DIR_OUT); // 设置为输入模式
IoTGpioInit(BEEP_GPIO);
IoTGpioSetFunc(BEEP_GPIO, IOT_GPIO_FUNC_GPIO_8_GPIO);
IoTGpioSetDir(BEEP_GPIO, IOT_GPIO_DIR_OUT); // 设置为输入模式
}
/***************************************************************
* : Door_Read_Data
* :
* :
* :
***************************************************************/
uint8_t Door_Read_Data(void)
{
IotGpioValue temp = {0};
IoTGpioGetInputVal(OUT_GPIO,&temp);
return temp;
}
/***************************************************************
* : BeepStatusSet
* : Beep状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void BeepStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(BEEP_GPIO, 1); // 设置GPIO_7输出高电平点亮灯
}
if (status == OFF) {
IoTGpioSetOutputVal(BEEP_GPIO, 0); // 设置GPIO_7输出低电平关闭灯
}
}
/***************************************************************
* : LedWarnStatusSet
* : LED_Warn状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void LedWarnStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(LED_WARN_GPIO, 1); // 设置输出高电平点亮灯
}
if (status == OFF) {
IoTGpioSetOutputVal(LED_WARN_GPIO, 0); // 设置输出低电平关闭灯
}
}
/***************************************************************
* : LedSafeStatusSet
* : LED_Safe状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void LedSafeStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(LED_SAFE_GPIO, 1); // 设置输出高电平点亮灯
}
if (status == OFF) {
IoTGpioSetOutputVal(LED_SAFE_GPIO, 0); // 设置输出低电平关闭灯
}
}

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2020  Jinan Bosai Network Technology Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "L76K.h"
#include "cmsis_os2.h"
#include "ohos_init.h"
#define TASK_STACK_SIZE 1024 * 8
#define TASK_PRIO 25
// #define FLAGS_MSK1 0x00000001U
// osEventFlagsId_t evt_id;
// static void Beep_Alarm(char *arg)
// {
// (void)arg;
// osEventFlagsSet(evt_id, FLAGS_MSK1);
// printf("Beep_Alarm\n");
// }
static void ExampleTask(void)
{
// L76Data data;
BoardInit();
// LedWarnStatusSet(ON);
// BeepStatusSet(ON);
while (1) {
PLAY();
sleep(2);
}
}
static void ExampleEntry(void)
{
osThreadAttr_t attr;
attr.name = "ExampleTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = TASK_STACK_SIZE;
attr.priority = TASK_PRIO;
if (osThreadNew((osThreadFunc_t)ExampleTask, NULL, &attr) == NULL) {
printf("Failed to create ExampleTask!\n");
}
}
APP_FEATURE_INIT(ExampleEntry);

25
app/A16_PLAY/BUILD.gn Normal file
View File

@ -0,0 +1,25 @@
# Copyright (c) 2020  Jinan Bosai Network Technology Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_library("A16_PLAY") {
sources = [
"src/L76K.c",
"A24_GPS_example.c"
]
include_dirs = [
"//base/iot_hardware/peripheral/interfaces/kits",
"//device/bossay/hi3861_l0/iot_hardware_hals/include",
"include"
]
}

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2020  Jinan Bosai Network Technology Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __L76_H__
#define __L76_H__
#include <stdint.h>
/***************************************************************
* : GasStatus_ENUM
*
***************************************************************/
typedef enum
{
OFF = 0,
ON
} SwitchStatus;
void BoardInit(void);
void PLAY(void);
#endif /* __L76_H__ */

81
app/A16_PLAY/src/L76K.c Normal file
View File

@ -0,0 +1,81 @@
/*
* Copyright (c) 2020  Jinan Bosai Network Technology Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include "L76K.h"
#include "iot_errno.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#include "iot_pwm.h"
#include "iot_uart.h"
#define WIFI_IOT_PWM_PORT_PWM1 1
#define WIFI_IOT_IO_FUNC_GPIO_8_PWM1_OUT 5
#define WIFI_IOT_IO_FUNC_GPIO_7_GPIO 0
#define BEEP_GPIO 8
#define LED_GPIO 14
#define RESET_GPIO 7
#define STANDBY_GPIO 13
#define WIFI_IOT_UART_IDX_1 1
/***************************************************************
* : BoardInit
* :
* :
* :
***************************************************************/
void BoardInit(void)
{
uint32_t ret;
IotUartAttribute uart_attr = {
// baud_rate: 9600
.baudRate = 9600,
// data_bits: 8bits
.dataBits = 8,
.stopBits = 1,
.parity = 0,
};
// Initialize uart driver
ret = IoTUartInit(WIFI_IOT_UART_IDX_1, &uart_attr);
if (ret != IOT_SUCCESS) {
printf("Failed to init uart! Err code = %d\n", ret);
return;
}
}
static const char* data = "A2\r\n";
/***************************************************************
* : L76ReadData
* :
* :
* :
***************************************************************/
void PLAY(void)
{
//通过串口1接收数据
IoTUartWrite(WIFI_IOT_UART_IDX_1, (unsigned char*)data, strlen(data));
}

85
app/A17_CH2O/A17_CH2O.c Normal file
View File

@ -0,0 +1,85 @@
/*
* Copyright (c) 2022 Jinan Bosai Network Technology Co., LTD Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <math.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "CH2O.h"
#define TASK_STACK_SIZE 1024*8
#define TASK_PRIO 25
static void ExampleTask(void)
{
int ret;
float ppm;
BoardInit();
//Sensor calibration
usleep(1000000);
MQ2PPMCalibration();
while (1) {
printf("=======================================\r\n");
printf("*************A22_MQ2_example***********\r\n");
printf("=======================================\r\n");
//get mq2 ppm
ret = GetMQ2PPM(&ppm);
if (ret != 0) {
printf("ADC Read Fail\n");
return ;
}
printf("ppm:%.3f \n", ppm);
if (ppm > 20) {
BeepStatusSet(ON);
LedSafeStatusSet(OFF);
LedWarnStatusSet(ON);
} else {
BeepStatusSet(OFF);
LedSafeStatusSet(ON);
LedWarnStatusSet(OFF);
}
usleep(1000000);
}
}
/**
* @brief Main Entry of the A22_MQ2 Example
*
*/
static void ExampleEntry(void)
{
osThreadAttr_t attr;
attr.name = "ExampleTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = TASK_STACK_SIZE;
attr.priority = TASK_PRIO;
if (osThreadNew((osThreadFunc_t)ExampleTask, NULL, &attr) == NULL) {
printf("Failed to create ExampleTask!\n");
}
}
APP_FEATURE_INIT(ExampleEntry);

25
app/A17_CH2O/BUILD.gn Normal file
View File

@ -0,0 +1,25 @@
# Copyright (c) 2022 Jinan Bosai Network Technology Co., LTD Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_library("A17_CH2O") {
sources = [
"src/CH2O.c",
"A17_CH2O.c"
]
include_dirs = [
"//base/iot_hardware/peripheral/interfaces/kits",
"//device/bossay/hi3861_l0/iot_hardware_hals/include",
"include"
]
}

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2020  Jinan Bosai Network Technology Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __E53_SF1_H__
#define __E53_SF1_H__
typedef enum
{
OFF = 0,
ON
} SwitchStatus;
void BoardInit(void);
void MQ2PPMCalibration(void);
int GetMQ2PPM(float *ppm);
void BeepStatusSet(SwitchStatus status);
void LedSafeStatusSet(SwitchStatus status);
void LedWarnStatusSet(SwitchStatus status);
#endif /* __E53_SF1_H__ */

168
app/A17_CH2O/src/CH2O.c Normal file
View File

@ -0,0 +1,168 @@
/*
* Copyright (c) 2020  Jinan Bosai Network Technology Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "CH2O.h"
#include "iot_adc.h"
#include "iot_errno.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#include "iot_pwm.h"
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define CAL_PPM 20 //校准环境中PPM值
#define RL 1 // RL阻值
#define WIFI_IOT_IO_NAME_GPIO_8 8
#define WIFI_IOT_PWM_PORT_PWM1 1
#define WIFI_IOT_IO_FUNC_GPIO_8_PWM1_OUT 5
#define SAFE_LED_GPIO 14
#define WARN_LED_GPIO 7
static float R0; //元件在洁净空气中的阻值
/***************************************************************
* : MQ2Init
* : MQ2Init
* :
* :
***************************************************************/
void BoardInit(void)
{
IoTGpioInit(SAFE_LED_GPIO);
IoTGpioSetFunc(SAFE_LED_GPIO, IOT_GPIO_FUNC_GPIO_14_GPIO);
IoTGpioSetDir(SAFE_LED_GPIO, IOT_GPIO_DIR_OUT); //设置为输出模式
IoTGpioInit(WARN_LED_GPIO);
IoTGpioSetFunc(WARN_LED_GPIO, IOT_GPIO_FUNC_GPIO_7_GPIO);
IoTGpioSetDir(WARN_LED_GPIO, IOT_GPIO_DIR_OUT); //设置为输出模式
IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_8); //初始化GPIO_8
IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_8, WIFI_IOT_IO_FUNC_GPIO_8_PWM1_OUT); //设置GPIO_8引脚复用功能为PWM
IoTGpioSetDir(WIFI_IOT_IO_NAME_GPIO_8, IOT_GPIO_DIR_OUT); //设置GPIO_8引脚为输出模式
IoTPwmInit(WIFI_IOT_PWM_PORT_PWM1); //初始化PWM1端口
}
/***************************************************************
* : GetVoltage
* :
* :
*
* :
***************************************************************/
static float GetVoltage(void)
{
unsigned int ret;
unsigned short data;
ret = IoTAdcRead(5, &data, IOT_ADC_EQU_MODEL_8, IOT_ADC_CUR_BAIS_DEFAULT, 0xff);
if (ret != IOT_SUCCESS)
{
printf("ADC Read Fail\n");
}
return (float)data * 1.8 * 4 / 4096.0;
}
/***************************************************************
* : GetMQ2PPM
* : PPM函数
* : ppm
* : 0 ; -1
***************************************************************/
int GetMQ2PPM(float* ppm)
{
unsigned int ret;
unsigned short data;
float voltage, RS;
ret = IoTAdcRead(6, &data, IOT_ADC_EQU_MODEL_8, IOT_ADC_CUR_BAIS_DEFAULT, 0xff);
if (ret != 0) {
printf("ADC Read Fail\n");
return -1;
}
voltage = (float)data * 1.8 * 4 / 4096.0;
printf("voltage:%2.2fV\n",voltage);
RS = (5 - voltage) / voltage * RL; //计算RS
*ppm = 613.9f * pow(RS / R0, -2.074f); //计算ppm
return 0;
}
/***************************************************************
* : MQ2PPMCalibration
* :
* :
* :
***************************************************************/
void MQ2PPMCalibration(void)
{
float voltage = GetVoltage();
float RS = (5 - voltage) / voltage * RL;
R0 = RS / pow(CAL_PPM / 613.9f, 1 / -2.074f);
}
/***************************************************************
* : BeepStatusSet
* :
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void BeepStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTPwmStart(WIFI_IOT_PWM_PORT_PWM1, 50, 4000); //输出PWM波
}
if (status == OFF) {
IoTPwmStop(WIFI_IOT_PWM_PORT_PWM1);
}
}
/***************************************************************
* : LedSafeStatusSet
* : LED_Safe状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void LedSafeStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(SAFE_LED_GPIO, 1); // 设置GPIO_7输出高电平点亮灯
}
if (status == OFF) {
IoTGpioSetOutputVal(SAFE_LED_GPIO, 0); // 设置GPIO_7输出低电平关闭灯
}
}
/***************************************************************
* : LedWarnStatusSet
* : LED_Warn状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void LedWarnStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(WARN_LED_GPIO, 1); // 设置GPIO_14输出高电平点亮灯
}
if (status == OFF) {
IoTGpioSetOutputVal(WARN_LED_GPIO, 0); // 设置GPIO_14输出低电平关闭灯
}
}

View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 2022 Jinan Bosai Network Technology Co., LTD Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "st02d.h"
#include "cmsis_os2.h"
#include "ohos_init.h"
#define TASK_STACK_SIZE 1024 * 8
#define TASK_PRIO 25
// #define FLAGS_MSK1 0x00000001U
// osEventFlagsId_t evt_id;
// static void Beep_Alarm(char *arg)
// {
// (void)arg;
// osEventFlagsSet(evt_id, FLAGS_MSK1);
// printf("Beep_Alarm\n");
// }
static void ExampleTask(void)
{
// ST02D_Init();
// Button_Left_Read_Data(Beep_Alarm);
// Button_Right_Read_Data(Beep_Alarm);
// while (1)
// {
// osEventFlagsWait(evt_id, FLAGS_MSK1, osFlagsWaitAny, osWaitForever);
// BeepStatusSet(ON);
// LedWarnStatusSet(ON);
// osDelay(300);
// BeepStatusSet(OFF);
// LedWarnStatusSet(OFF);
// }
ST02D_Init();
// Button_Left_Read_Data(Beep_Alarm);
// Button_Right_Read_Data(Beep_Alarm);
while (1)
{
if(Button_Left_Read_Data() == 0|Button_Right_Read_Data() == 0)
{
BeepStatusSet(ON);
LedWarnStatusSet(ON);
}
else
{
BeepStatusSet(OFF);
LedWarnStatusSet(OFF);
}
sleep(1);
}
}
static void ExampleEntry(void)
{
osThreadAttr_t attr;
attr.name = "ExampleTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = TASK_STACK_SIZE;
attr.priority = TASK_PRIO;
if (osThreadNew((osThreadFunc_t)ExampleTask, NULL, &attr) == NULL) {
printf("Failed to create ExampleTask!\n");
}
}
APP_FEATURE_INIT(ExampleEntry);

26
app/A18_ST02D/BUILD.gn Normal file
View File

@ -0,0 +1,26 @@
# Copyright (c) 2022 Jinan Bosai Network Technology Co., LTD Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_library("A18_ST02D") {
sources = [
"src/st02d.c",
"A18_ST02D_example.c"
]
include_dirs = [
"//base/iot_hardware/peripheral/interfaces/kits",
"//device/bossay/hi3861_l0/iot_hardware_hals/include",
"//device/bossay/hi3861_l0/sdk_liteos/include",
"include"
]
}

View File

@ -0,0 +1,27 @@
#ifndef __ST02D_H__
#define __ST02D_H__
#include <stdint.h>
typedef enum
{
OFF = 0,
ON
} SwitchStatus;
typedef void (*ST02D_CallbackFunc) (char *arg);
void ST02D_Init(void);
// void Button_Left_Read_Data(ST02D_CallbackFunc func);
// void Button_Right_Read_Data(ST02D_CallbackFunc func);
uint8_t Button_Left_Read_Data(void);
uint8_t Button_Right_Read_Data(void);
void BeepStatusSet(SwitchStatus status);
void LedWarnStatusSet(SwitchStatus status);
#endif

119
app/A18_ST02D/src/st02d.c Normal file
View File

@ -0,0 +1,119 @@
#include "st02d.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#define WIFI_IOT_IO_NAME_GPIO_8 8
#define WIFI_IOT_IO_NAME_GPIO_14 14
#define WIFI_IOT_IO_NAME_GPIO_0 0
#define WIFI_IOT_IO_NAME_GPIO_1 1
#define WIFI_IOT_I2C_IDX_1 1
#define OUT1_GPIO 13
#define OUT2_GPIO 7
uint8_t RxBuffer[3];
void ST02D_Init(void)
{
IoTGpioInit(OUT1_GPIO);
IoTGpioSetFunc(OUT1_GPIO, IOT_GPIO_FUNC_GPIO_13_GPIO);
IoTGpioSetDir(OUT1_GPIO, IOT_GPIO_DIR_IN); // 设置GPIO_8为输出模式
IoTGpioInit(OUT2_GPIO);
IoTGpioSetFunc(OUT2_GPIO, IOT_GPIO_FUNC_GPIO_7_GPIO);
IoTGpioSetDir(OUT2_GPIO, IOT_GPIO_DIR_IN); // 设置GPIO_8为输出模式
IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_14);
IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_14, IOT_GPIO_FUNC_GPIO_14_GPIO);
IoTGpioSetDir(WIFI_IOT_IO_NAME_GPIO_14, IOT_GPIO_DIR_OUT); // 设置为输入模式
IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_8);
IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_8, IOT_GPIO_FUNC_GPIO_8_GPIO);
IoTGpioSetDir(WIFI_IOT_IO_NAME_GPIO_8, IOT_GPIO_DIR_OUT); // 设置为输入模式
}
// /***************************************************************
// * 函数名称: Button_Left_Read_Data
// * 说 明: 读取数据
// * 参 数: 无
// * 返 回 值: 无
// ***************************************************************/
// void Button_Left_Read_Data(void)
// {
// IoTGpioRegisterIsrFunc(WIFI_IOT_IO_NAME_GPIO_14, IOT_INT_TYPE_EDGE, IOT_GPIO_EDGE_FALL_LEVEL_LOW,func, 0);
// }
// /***************************************************************
// * 函数名称: Button_Right_Read_Data
// * 说 明: 读取数据
// * 参 数: 无
// * 返 回 值: 无
// ***************************************************************/
// void Button_Right_Read_Data(void)
// {
// IoTGpioRegisterIsrFunc(WIFI_IOT_IO_NAME_GPIO_8, IOT_INT_TYPE_EDGE, IOT_GPIO_EDGE_FALL_LEVEL_LOW,func, 0);
// }
/***************************************************************
* : Button_Left_Read_Data
* :
* :
* :
***************************************************************/
uint8_t Button_Left_Read_Data(void)
{
IotGpioValue temp = {0};
IoTGpioGetInputVal(OUT1_GPIO,&temp);
return temp;
}
/***************************************************************
* : Button_Right_Read_Data
* :
* :
* :
***************************************************************/
uint8_t Button_Right_Read_Data(void)
{
IotGpioValue temp = {0};
IoTGpioGetInputVal(OUT2_GPIO,&temp);
return temp;
}
/***************************************************************
* : BeepStatusSet
* : Beep状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void BeepStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, 1); // 设置GPIO_7输出高电平点亮灯
}
if (status == OFF) {
IoTGpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, 0); // 设置GPIO_7输出低电平关闭灯
}
}
/***************************************************************
* : LedWarnStatusSet
* : LED_Warn状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void LedWarnStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_14, 1); // 设置GPIO_14输出高电平点亮灯
}
if (status == OFF) {
IoTGpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_14, 0); // 设置GPIO_14输出低电平关闭灯
}
}

View File

@ -0,0 +1,71 @@
/*
* Copyright (c) 2020  Jinan Bosai Network Technology Co., LTD
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "mlx90614.h"
#include "cmsis_os2.h"
#include "ohos_init.h"
#define TASK_STACK_SIZE 1024 * 8
#define TASK_PRIO 25
static void ExampleTask(void)
{
MLX90614_Init();
while (1) {
printf("\r\n Ambient Temp: %0.2f \r\n", MLX90614_Read_TempData(MLX90614_RAM | AMBIENT_TEMP)); // ambient
printf("\r\n Object Temp: %0.2f \r\n", MLX90614_Read_TempData(MLX90614_RAM | OBJECT_TEMP)); // object
if(MLX90614_Read_TempData(MLX90614_RAM | OBJECT_TEMP)>32)
{
LedSafeStatusSet(OFF);
LedWarnStatusSet(ON);
BeepStatusSet(ON);
}
else
{
LedSafeStatusSet(ON);
LedWarnStatusSet(OFF);
BeepStatusSet(OFF);
}
sleep(2);
}
}
static void ExampleEntry(void)
{
osThreadAttr_t attr;
attr.name = "ExampleTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = TASK_STACK_SIZE;
attr.priority = TASK_PRIO;
if (osThreadNew((osThreadFunc_t)ExampleTask, NULL, &attr) == NULL) {
printf("Failed to create ExampleTask!\n");
}
}
APP_FEATURE_INIT(ExampleEntry);

27
app/A19_MXL90614/BUILD.gn Normal file
View File

@ -0,0 +1,27 @@
# Copyright (c) 2020  Jinan Bosai Network Technology Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_library("A19_MXL90614") {
sources = [
"src/smbus.c",
"src/mlx90614.c",
"A19_MXL90614_example.c"
]
include_dirs = [
"//base/iot_hardware/peripheral/interfaces/kits",
"//device/bossay/hi3861_l0/iot_hardware_hals/include",
"//device/bossay/hi3861_l0/sdk_liteos/include",
"include"
]
}

View File

@ -0,0 +1,32 @@
#ifndef __MLX90614_H
#define __MLX90614_H
#include <stdint.h>
#define MLX90614_ADDR_WRITE 0x00
#define MLX90614_ADDR_READ 0x01
#define MLX90614_RAM 0x00
#define AMBIENT_TEMP 0x06
#define OBJECT_TEMP 0x07
typedef enum
{
OFF = 0,
ON
} SwitchStatus;
extern uint8_t RxBuffer[3];
void MLX90614_Init(void);
float MLX90614_Read_TempData(uint8_t ambient_or_object);
void LedSafeStatusSet(SwitchStatus status);
void LedWarnStatusSet(SwitchStatus status);
void BeepStatusSet(SwitchStatus status);
#endif

View File

@ -0,0 +1,26 @@
#ifndef __SMBUS_H
#define __SMBUS_H
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#define ACK 0
#define NACK 1
#define WIFI_IOT_IO_NAME_GPIO_10 10
#define WIFI_IOT_IO_NAME_GPIO_12 12
#define SMBUS_SCL_H() IoTGpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_10, 1);
#define SMBUS_SCL_L() IoTGpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_10, 0);
#define SMBUS_SDA_H() IoTGpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_12, 1);
#define SMBUS_SDA_L() IoTGpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_12, 0);
void SMBus_Start(void);
void SMBus_Stop(void);
void SMBus_SendBit(uint8_t bit_out);
uint8_t SMBus_ReceiveBit(void);
uint8_t SMBus_SendByte(uint8_t Tx_buffer);
uint8_t SMBus_ReceiveByte(uint8_t ack_nack);
#endif

View File

@ -0,0 +1,246 @@
#include "mlx90614.h"
#include "smbus.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#define WIFI_IOT_IO_NAME_GPIO_7 7
#define WIFI_IOT_IO_NAME_GPIO_14 14
#define WIFI_IOT_IO_NAME_GPIO_10 10
#define WIFI_IOT_IO_NAME_GPIO_12 12
#define WIFI_IOT_I2C_IDX_1 1
uint8_t RxBuffer[3];
#define BEEP_GPIO 8
void MLX90614_Init(void)
{
IoTGpioInit(BEEP_GPIO);
IoTGpioSetFunc(BEEP_GPIO, IOT_GPIO_FUNC_GPIO_8_GPIO);
IoTGpioSetDir(BEEP_GPIO, IOT_GPIO_DIR_OUT); //设置为输出模式
IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_10);
IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_10, IOT_GPIO_FUNC_GPIO_10_GPIO);
IoTGpioSetDir(WIFI_IOT_IO_NAME_GPIO_10, IOT_GPIO_DIR_OUT); // 设置GPIO_8为输出模式
IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_12);
IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_12, IOT_GPIO_FUNC_GPIO_12_GPIO);
IoTGpioSetDir(WIFI_IOT_IO_NAME_GPIO_12, IOT_GPIO_DIR_OUT); // 设置GPIO_8为输出模式
IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_14);
IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_14, IOT_GPIO_FUNC_GPIO_14_GPIO);
IoTGpioSetDir(WIFI_IOT_IO_NAME_GPIO_14, IOT_GPIO_DIR_OUT); // 设置GPIO_14为输出模式
IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_7);
IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_7, IOT_GPIO_FUNC_GPIO_7_GPIO);
IoTGpioSetDir(WIFI_IOT_IO_NAME_GPIO_7, IOT_GPIO_DIR_OUT); // 设置GPIO_7为输出模式
}
/*******************************************************************************
* : PEC_calculation
* :
* Input : pec[]
* Output : None
* Return : pec[0]-this byte contains calculated crc value
*******************************************************************************/
uint8_t PEC_Calculation(uint8_t pec[])
{
uint8_t crc[6];
uint8_t BitPosition=47;
uint8_t shift;
uint8_t i;
uint8_t j;
uint8_t temp;
do
{
/*Load pattern value 0x000000000107*/
crc[5]=0;
crc[4]=0;
crc[3]=0;
crc[2]=0;
crc[1]=0x01;
crc[0]=0x07;
/*Set maximum bit position at 47 ( six bytes byte5...byte0,MSbit=47)*/
BitPosition=47;
/*Set shift position at 0*/
shift=0;
/*Find first "1" in the transmited message beginning from the MSByte byte5*/
i=5;
j=0;
while((pec[i]&(0x80>>j))==0 && i>0)
{
BitPosition--;
if(j<7)
{
j++;
}
else
{
j=0x00;
i--;
}
}/*End of while */
/*Get shift value for pattern value*/
shift=BitPosition-8;
/*Shift pattern value */
while(shift)
{
for(i=5; i<0xFF; i--)
{
if((crc[i-1]&0x80) && (i>0))
{
temp=1;
}
else
{
temp=0;
}
crc[i]<<=1;
crc[i]+=temp;
}/*End of for*/
shift--;
}/*End of while*/
/*Exclusive OR between pec and crc*/
for(i=0; i<=5; i++)
{
pec[i] ^=crc[i];
}/*End of for*/
}
while(BitPosition>8); /*End of do-while*/
return pec[0];
}
/*******************************************************************************
* : SMBus_ReadMemory
* : READ DATA FROM RAM/EEPROM
* Input : slaveAddress, command
* Return : Data
*******************************************************************************/
uint16_t SMBus_ReadMemory(uint8_t slaveAddress, uint8_t command)
{
uint16_t data; // Data storage (DataH:DataL)
uint8_t Pec; // PEC byte storage
uint8_t DataL=0; // Low data byte storage
uint8_t DataH=0; // High data byte storage
uint8_t arr[6]; // Buffer for the sent bytes
uint8_t PecReg; // Calculated PEC byte storage
uint8_t ErrorCounter; // Defines the number of the attempts for communication with MLX90614
ErrorCounter=0x00; // Initialising of ErrorCounter
slaveAddress <<= 1; //2-7位表示从机地址
do
{
repeat:
SMBus_Stop(); //If slave send NACK stop comunication
--ErrorCounter; //Pre-decrement ErrorCounter
if(!ErrorCounter) //ErrorCounter=0?
{
break; //Yes,go out from do-while{}
}
SMBus_Start(); //Start condition
if(SMBus_SendByte(slaveAddress))//Send SlaveAddress 最低位Wr=0表示接下来写命令
{
goto repeat; //Repeat comunication again
}
if(SMBus_SendByte(command)) //Send command
{
goto repeat; //Repeat comunication again
}
SMBus_Start(); //Repeated Start condition
if(SMBus_SendByte(slaveAddress+1)) //Send SlaveAddress 最低位Rd=1表示接下来读数据
{
goto repeat; //Repeat comunication again
}
DataL = SMBus_ReceiveByte(ACK); //Read low data,master must send ACK
DataH = SMBus_ReceiveByte(ACK); //Read high data,master must send ACK
Pec = SMBus_ReceiveByte(NACK); //Read PEC byte, master must send NACK
SMBus_Stop(); //Stop condition
arr[5] = slaveAddress; //
arr[4] = command; //
arr[3] = slaveAddress+1; //Load array arr
arr[2] = DataL; //
arr[1] = DataH; //
arr[0] = 0; //
PecReg=PEC_Calculation(arr);//Calculate CRC
}
while(PecReg != Pec); //If received and calculated CRC are equal go out from do-while{}
data = (DataH<<8) | DataL; //data=DataH:DataL
return data;
}
/***************************************************************************
* @brief Read object temperature(Tobj) from RAM registers of MLX90614
* @param ambient_or_object : Which temperature you want to get
* @retval Object temperature
****************************************************************************/
float MLX90614_Read_TempData(uint8_t ambient_or_object)
{
return SMBus_ReadMemory(MLX90614_ADDR_WRITE, ambient_or_object)*0.02-273.15;
}
/***************************************************************
* : LedSafeStatusSet
* : LED_Safe状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void LedSafeStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(7, 1); // 设置GPIO_7输出高电平点亮灯
}
if (status == OFF) {
IoTGpioSetOutputVal(7, 0); // 设置GPIO_7输出低电平关闭灯
}
}
/***************************************************************
* : LedWarnStatusSet
* : LED_Warn状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void LedWarnStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_14, 1); // 设置GPIO_14输出高电平点亮灯
}
if (status == OFF) {
IoTGpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_14, 0); // 设置GPIO_14输出低电平关闭灯
}
}
/***************************************************************
* : BeepStatusSet
* : Beep状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void BeepStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(BEEP_GPIO, 1); // 设置GPIO_7输出高电平点亮灯
}
if (status == OFF) {
IoTGpioSetOutputVal(BEEP_GPIO, 0); // 设置GPIO_7输出低电平关闭灯
}
}

View File

@ -0,0 +1,158 @@
#include "mlx90614.h"
#include "smbus.h"
#include "hi_time.h"
/***************************************************************************
* @brief SMBus start bit
* @param None
* @retval None
****************************************************************************/
void SMBus_Start(void)
{
SMBUS_SDA_H();
hi_udelay(5);
SMBUS_SCL_H();
hi_udelay(5);
SMBUS_SDA_L();
hi_udelay(5);
SMBUS_SCL_L();
hi_udelay(5);
}
/***************************************************************************
* @brief SMBus stop bit
* @param None
* @retval None
****************************************************************************/
void SMBus_Stop(void)
{
SMBUS_SCL_L();
hi_udelay(5);
SMBUS_SDA_L();
hi_udelay(5);
SMBUS_SCL_H();
hi_udelay(5);
SMBUS_SDA_H();
}
/*******************************************************************************
* : SMBus_SendBit
* : Send a bit on SMBus 82.5kHz
* Input : bit_out
* Output : None
* Return : None
*******************************************************************************/
void SMBus_SendBit(uint8_t bit_out)
{
if(bit_out==0)
{
SMBUS_SDA_L();
}
else
{
SMBUS_SDA_H();
}
hi_udelay(2); // Tsu:dat = 250ns minimum
SMBUS_SCL_H(); // Set SCL line
hi_udelay(6); // High Level of Clock Pulse
SMBUS_SCL_L(); // Clear SCL line
hi_udelay(3); // Low Level of Clock Pulse
return;
}
static uint8_t SMBUS_SDA_READ(void)
{
IotGpioValue temp = {0};
IoTGpioGetInputVal(WIFI_IOT_IO_NAME_GPIO_12,&temp);
return temp;
}
/*******************************************************************************
* Function Name : SMBus_ReceiveBit
* Description : Receive a bit on SMBus
* Input : None
* Output : None
* Return : Ack_bit
*******************************************************************************/
uint8_t SMBus_ReceiveBit(void)
{
uint8_t Ack_bit;
SMBUS_SDA_H(); //引脚靠外部电阻上拉,当作输入
hi_udelay(2); // High Level of Clock Pulse
SMBUS_SCL_H(); // Set SCL line
hi_udelay(5); // High Level of Clock Pulse
if (SMBUS_SDA_READ())
{
Ack_bit=1;
}
else
{
Ack_bit=0;
}
SMBUS_SCL_L(); // Clear SCL line
hi_udelay(3); // Low Level of Clock Pulse
return Ack_bit;
}
/*******************************************************************************
* : SMBus_SendByte
* : Send a byte on SMBus
* Input : Tx_buffer
* Output : None
* Return : None
*******************************************************************************/
uint8_t SMBus_SendByte(uint8_t Tx_buffer)
{
uint8_t Bit_counter;
uint8_t Ack_bit;
uint8_t bit_out;
for(Bit_counter=8; Bit_counter; Bit_counter--)
{
if (Tx_buffer&0x80)
{
bit_out=1; // If the current bit of Tx_buffer is 1 set bit_out
}
else
{
bit_out=0; // else clear bit_out
}
SMBus_SendBit(bit_out); // Send the current bit on SDA
Tx_buffer<<=1; // Get next bit for checking
}
Ack_bit=SMBus_ReceiveBit(); // Get acknowledgment bit
return Ack_bit;
}
/*******************************************************************************
* : SMBus_ReceiveByte
* : Receive a byte on SMBus
* Input : ack_nack
* Output : None
* Return : RX_buffer
*******************************************************************************/
uint8_t SMBus_ReceiveByte(uint8_t ack_nack)
{
uint8_t RX_buffer;
uint8_t Bit_Counter;
for(Bit_Counter=8; Bit_Counter; Bit_Counter--)
{
if(SMBus_ReceiveBit()) // Get a bit from the SDA line
{
RX_buffer <<= 1; // If the bit is HIGH save 1 in RX_buffer
RX_buffer |=0x01;
}
else
{
RX_buffer <<= 1; // If the bit is LOW save 0 in RX_buffer
RX_buffer &=0xfe;
}
}
SMBus_SendBit(ack_nack); // Sends acknowledgment bit
return RX_buffer;
}

View File

@ -0,0 +1,71 @@
/*
* Copyright (c) 2020  Jinan Bosai Network Technology Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "VOICE.h"
#include "cmsis_os2.h"
#include "ohos_init.h"
#define TASK_STACK_SIZE 1024 * 8
#define TASK_PRIO 25
static void ExampleTask(void)
{
BoardInit();
while (1)
{
BeepStatusSet(ON);
LedRed1StatusSet(ON);
LedRed2StatusSet(ON);
LedBlue1StatusSet(OFF);
LedBlue2StatusSet(OFF);
osDelay(50);
BeepStatusSet(OFF);
LedRed1StatusSet(OFF);
LedRed2StatusSet(OFF);
LedBlue1StatusSet(ON);
LedBlue2StatusSet(ON);
osDelay(150);
}
}
static void ExampleEntry(void)
{
osThreadAttr_t attr;
attr.name = "ExampleTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = TASK_STACK_SIZE;
attr.priority = TASK_PRIO;
if (osThreadNew((osThreadFunc_t)ExampleTask, NULL, &attr) == NULL) {
printf("Failed to create ExampleTask!\n");
}
}
APP_FEATURE_INIT(ExampleEntry);

26
app/A20_VOICE/BUILD.gn Normal file
View File

@ -0,0 +1,26 @@
# Copyright (c) 2020  Jinan Bosai Network Technology Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_library("A20_VOICE") {
sources = [
"src/VOICE.c",
"A20_VOICE_example.c"
]
include_dirs = [
"//base/iot_hardware/peripheral/interfaces/kits",
"//device/bossay/hi3861_l0/iot_hardware_hals/include",
"//device/bossay/hi3861_l0/sdk_liteos/include",
"include"
]
}

View File

@ -0,0 +1,24 @@
#ifndef __VOICE_H__
#define __VOICE_H__
#include <stdint.h>
typedef enum
{
OFF = 0,
ON
} SwitchStatus;
void BoardInit(void);
void BeepStatusSet(SwitchStatus status);
void LedBlue1StatusSet(SwitchStatus status);
void LedBlue2StatusSet(SwitchStatus status);
void LedRed1StatusSet(SwitchStatus status);
void LedRed2StatusSet(SwitchStatus status);
#endif

128
app/A20_VOICE/src/VOICE.c Normal file
View File

@ -0,0 +1,128 @@
#include "VOICE.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#define LED_BLUE1_GPIO 5
#define LED_BLUE2_GPIO 6
#define LED_RED1_GPIO 14
#define LED_RED2_GPIO 7
#define BEEP_GPIO 8
void BoardInit(void)
{
IoTGpioInit(LED_BLUE1_GPIO);
IoTGpioSetFunc(LED_BLUE1_GPIO, IOT_GPIO_FUNC_GPIO_5_GPIO);
IoTGpioSetDir(LED_BLUE1_GPIO, IOT_GPIO_DIR_OUT); // 设置GPIO_8为输出模式
IoTGpioInit(LED_BLUE2_GPIO);
IoTGpioSetFunc(LED_BLUE2_GPIO, IOT_GPIO_FUNC_GPIO_6_GPIO);
IoTGpioSetDir(LED_BLUE2_GPIO, IOT_GPIO_DIR_OUT); // 设置GPIO_8为输出模式
IoTGpioInit(LED_RED1_GPIO);
IoTGpioSetFunc(LED_RED1_GPIO, IOT_GPIO_FUNC_GPIO_14_GPIO);
IoTGpioSetDir(LED_RED1_GPIO, IOT_GPIO_DIR_OUT); // 设置为输入模式
IoTGpioInit(LED_RED2_GPIO);
IoTGpioSetFunc(LED_RED2_GPIO, IOT_GPIO_FUNC_GPIO_7_GPIO);
IoTGpioSetDir(LED_RED2_GPIO, IOT_GPIO_DIR_OUT); // 设置为输出模式
IoTGpioInit(BEEP_GPIO);
IoTGpioSetFunc(BEEP_GPIO, IOT_GPIO_FUNC_GPIO_8_GPIO);
IoTGpioSetDir(BEEP_GPIO, IOT_GPIO_DIR_OUT); // 设置为输入模式
}
/***************************************************************
* : BeepStatusSet
* : Beep状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void BeepStatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(BEEP_GPIO, 1); // 设置GPIO_7输出高电平点亮灯
}
if (status == OFF) {
IoTGpioSetOutputVal(BEEP_GPIO, 0); // 设置GPIO_7输出低电平关闭灯
}
}
/***************************************************************
* : LedBlue1StatusSet
* : LED_Blue1状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void LedBlue1StatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(LED_BLUE1_GPIO, 1); // 设置输出高电平点亮灯
}
if (status == OFF) {
IoTGpioSetOutputVal(LED_BLUE1_GPIO, 0); // 设置输出低电平关闭灯
}
}
/***************************************************************
* : LedBlue2StatusSet
* : LED_Blue1状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void LedBlue2StatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(LED_BLUE2_GPIO, 1); // 设置输出高电平点亮灯
}
if (status == OFF) {
IoTGpioSetOutputVal(LED_BLUE2_GPIO, 0); // 设置输出低电平关闭灯
}
}
/***************************************************************
* : LedBlue1StatusSet
* : LED_Red2状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void LedRed1StatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(LED_RED1_GPIO, 1); // 设置输出高电平点亮灯
}
if (status == OFF) {
IoTGpioSetOutputVal(LED_RED1_GPIO, 0); // 设置输出低电平关闭灯
}
}
/***************************************************************
* : LedRed2StatusSet
* : LED_Red2状态设置
* : status,ENUM枚举的数据
* OFF,
* ON,
* :
***************************************************************/
void LedRed2StatusSet(SwitchStatus status)
{
if (status == ON) {
IoTGpioSetOutputVal(LED_RED2_GPIO, 1); // 设置输出高电平点亮灯
}
if (status == OFF) {
IoTGpioSetOutputVal(LED_RED2_GPIO, 0); // 设置输出低电平关闭灯
}
}

View File

@ -0,0 +1,102 @@
/*
* Copyright (c) 2020  Jinan Bosai Network Technology Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "DHT11.h"
#include "BH1750.h"
#include "cmsis_os2.h"
#include "ohos_init.h"
#define TASK_STACK_SIZE 1024 * 8
#define TASK_PRIO 25
uint8_t fan_status;
static void FanTask(void)
{
while (1)
{
if(fan_status == 1)
FanStatusSet(ON,1);
else
{
FanStatusSet(OFF,0);
sleep(1);
}
}
}
static void ExampleTask(void)
{
int ret;
uint8_t dht_temperature;
uint8_t dht_humidity;
float Lux;
// BoardInit();
//GPIO_0复用为I2C1_SDA
ret = BoardInit();
if (ret != 0) {
printf("E53_SC1 Init failed!\r\n");
return;
}
while (1)
{
DHT11_Read_Data(&dht_temperature,&dht_humidity);
printf("temperature=%d \r\n",dht_temperature);
printf("humidity=%d %%\r\n",dht_humidity);
ret = BH1750ReadData(&Lux);
if (ret != 0) {
printf("E53_SC1 Read Data failed!\r\n");
return;
}
printf("Lux data:%.2f\r\n", Lux);
if (Lux < 20) {
fan_status = 1;
LightStatusSet(ON);
} else {
LightStatusSet(OFF);
fan_status = 0;
FanStatusSet(OFF,1);
}
sleep(3);
}
}
static void ExampleEntry(void)
{
osThreadAttr_t attr;
attr.name = "ExampleTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = TASK_STACK_SIZE;
attr.priority = TASK_PRIO;
if (osThreadNew((osThreadFunc_t)ExampleTask, NULL, &attr) == NULL) {
printf("Failed to create ExampleTask!\n");
}
attr.name = "FanTask";
if (osThreadNew((osThreadFunc_t)FanTask, NULL, &attr) == NULL) {
printf("Failed to create FanTask!\n");
}
}
APP_FEATURE_INIT(ExampleEntry);

Some files were not shown because too many files have changed in this diff Show More