diff --git a/11538_hi3861_home_server/README.md b/11538_hi3861_home_server/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1391921a4653294ce2d1b438881d9192c075b031 --- /dev/null +++ b/11538_hi3861_home_server/README.md @@ -0,0 +1,186 @@ +# 海思主控下的智能阳台:多模态感知与智能决策系统 + +## 简介 + +随着智能家居技术的快速发展,家庭环境智能化管理需求日益增长。针对传统 +阳台设备控制分散、依赖人工操作、缺乏环境自适应能力等问题。本报告详细介 +绍了智能阳台的设计理念、功能特点、技术创新以及应用前景。 +智能阳台具备窗帘和窗户的自动开闭、自动为植物进行补光和浇水、温度和湿 +度的检测、自动检测人在阳台上是否摔倒,全过程自动化不需要人的参与、节能 +环保和美观设计等多项功能,这些功能均围绕提升智能阳台的便利程度和用户的 +居住体验而设计。 + +智能阳台的自动调节系统,智能检测摔倒系统,以及自动为植物补光和浇水。 +自动调节系统能够根据外面的天气状况自动调整设备运行,用户可以查看屏幕的 +显示了解窗帘和窗户的状态,节能环保措施使植物充分利用光能茁壮的成长,能 +源消耗低,使其更加的绿色环保。 +智能阳台在人们现代快节奏的生活可以节省很多时间,可以很好的当做科研为 +学生们学好普中-Hi3861 鸿蒙开发板。可以把智能阳台作为酒店居住的新型产业 +为用户提供舒适的居住环境和生活体验。 + +## 作品概述 + +### 功能与特性 + +1. 窗户和窗帘的自动开闭:智能阳台可以通过外面的天气状况自动的打开窗 + 户和窗帘 + +2.温度和湿度检测:智能阳台能够检测温度和湿度为居住者可以提供实时的 +温度和湿度的显示。 + +3.补光灯控制:智能阳台通过对外面天气的检测,可以决定是否为植物开启 +补光灯进行补光。 + +4.自动浇水控制:智能阳台通过对环境的温度和湿度的检测,决定是否开启 +水泵为植物浇水。 + +5.天气检测控制:如果外面突然下雨,可以通过雨滴传感器的检测直接关闭 +窗帘和窗户。 + +6.智能摔倒检测:如果人在阳台上突然摔倒,可以通过摄像头的实时采集并 +且触发红色报警弹窗 + +7.节能环保:智能阳台通过充分的利用光能通过自动化的调节让植物茁壮的 +成长。 + +8.美观设计:智能阳台在设计时考虑到外观的美观性,和智能家居相互协调 +成为智能家居的重要组成部分。 + + + +### 应用领域 + +1.智能种植与园艺:通过土壤湿度、温度、光照强度自动为植物实现灌溉系 +统,补光灯装置、温湿度控制器,实现傻瓜式家庭园艺。支持蔬菜、花卉等植物 +的精准养护。 + +2.商业展示和差异化体验:在高端酒店,智能阳台通过住户偏好自动打开窗 +户和窗帘,提供“阳台下午茶场景”,提升入住体验。 + +3.教育和科研:智能阳台可以用于教育和科研用于给学生教会 hi3861 国产 +芯片如何搭建和使用等其它方面。 + +4.环境检测:智能阳台可以实时检测周围环境的温度、湿度、光照强度,可 +以让居民更好对外界环境做出防范措施。 + +5.科技展示和产品推广:智能阳台作为现代科技产品的代表,可以用于科技 +展览和产品推广,展示最新智能阳台技术。 + +6.安全措施和防范意识:智能阳台可以通过实时摄像头检测,发现人是否在 +阳台上摔倒,可以帮助人们及时做出应对措施。 + +### 主要技术特点 + +1.普中-鸿蒙开发板:描述了开发板的型号和性能参数,如处理速度、存大 +小、接口类型等。例如,我们选择了普中—Hi3861 鸿蒙开发板采用 ARMCortex-M4 +内核,最多 24 个 GPIO 可以灵活配置输出和输入。采用动态功耗管理,支持深 +度睡眠模式,仅在需要通信时唤醒。普中鸿蒙 Hi3861 的开发板的核心优势在于 +高性能低功耗 Wi-FiMCU+鸿蒙物联网生态的深度融合。其技术特点使其成为智 +能阳台等物联网的理想开发平台。可以更好完成智能阳台各个模块的充分展示和 +稳定运行。 + +2.摔倒检测机制:采用摄像头实时采集,用 OpenCV 和 YOLOv8 模型合,完 +成动态画面下人在阳台的是否摔倒的检测,该摄像头采用斯泰克高清的摄像头, +该摄像头录制视频清晰,自动对焦,拥有广角,检测范围更宽。 + +3.温度传感器:描述温度传感器的型号和功能,如测量精度、响应速度等。 +例如,我们选择了 DS18B20 温度传感器,它具有±0.5°C 的测量精度,响应速 +度快,能够在-55~+125℃的温度范围内进行测量。DS18B20 温度传感 器采用单 +总线通信方式,具有响应速度快、抗干扰能力强、稳定性好的特点,能够实时监 +测室内和室外的温度确保植物可以正常的生长。 + +4.雨滴传感器:描述雨滴传感器的型号与功能,如输出形式、反应速度等。 +例如,我们选择了 FC-37 的雨滴传感器,当 DO 输出为高电平表示感应板没有滴 +水,当 DO 输出为低电平表示感应板有水滴,开关指示灯亮。响应速度快,可以 +很好的检测室外是否下雨,可以判断窗帘和窗户是否关闭和打开。 + +5.土壤湿度传感器:描述土壤湿度传感器的型号和功能,如输出形式、精度 +测量、响应速度等。例如我们选择了土壤湿度检测的传感器,它具有 0-100%的 +测量精度,它具有通过电位器调节控制相应阈值,湿度低于设定值,DO 输出高 +电平,高于设定值时,DO 输出低电平,响应速度快,可以通过土壤湿度的检测 +确定是否打开水泵为植物浇水。 + + + +6.光照传感器:描述光照传感器的型号与功能,如输出形式、反应速度等。 +例如,我们选择了光敏二级管模块,它具有 DO 数字开关量输出(0 和 1)和 AO +模拟电压输出,响应速度快,根据光照的强弱可以决定窗帘和窗户是否打开和关 +闭。 + +7.水泵:描述水泵的型号和功能,如流量、噪音等。例如,我们选择了 DC3W +水泵,它具有稳定的流量和低噪音的特点。DC3W 水泵采用直流无刷电机,具 +有高效节能、寿命长的特点,能够很好的给植物浇水和养护。 + +8.补光灯:描述补光灯的型号和功能,例如我们选择了发光二极管 LED 作 +为补光灯,它具有寿命长、快速点亮、超低发热量,可以给植物快速和稳定的补 +光并且耗电量少节能环保。 + +### 主要性能指标 + +序号 性能指标 主要内容 +1 窗户和窗帘的自动开闭 +智能阳台可以根据光照强度和天气状况,自动的打开和关闭窗帘和窗户。 + +2 温度检测装置 +智能阳台通过对外界环境的温度做出检测,可以使人们做好防护措施。 + +3 自动补光装置 +智能阳台通过对外界环境的检测,可以决定是否给植物补充光能。 + +4 自动浇水装置 +智能阳台通过对花盆温度和湿度检测可以决定是否给植物浇水。 + +5 环境检测的准确性 +采用高精度传感器和先进的控制算法,确保环境检测的准确性,为智能阳台各个模块可以准确执行,提供了必要的条件。 + +6 智能摔倒检测 +智能阳台通过实时摄像头的采集检测人是否摔倒,可以发出红色警报弹窗。 + + + +### 主要创新 + +1.自动化控制系统:通过集成传感器和微处理器智能阳台可以根据外界环境 +的天气状况和光照强度可以对窗户和窗帘自动实行打开和关闭使人们可以更加舒适的居住。 + +2.自动为植物进行补光和浇水:智能阳台通过对环境温度和湿度的检测可以对植物进行浇水,如果光照强度不够的情况下,可以自动打开补光灯为植物进行补光可以让植物茁壮的成长。 + +3.节能环保设计:采用节能水泵和 LED 照明,减少能耗,同时让植物茁壮的成长 + + + +4.实时数据检测:传感器通过对外界环境的温度、湿度和光照强度的实时检测传递到显示屏幕上可以观测周围环境的实时动态特性。 + +5.实时动态观测:可以通过观察智能阳台的显示屏幕可以看到窗户和窗帘是否打开和关闭,外面是否下雨,水泵是否打开为植物浇水。 + +6.实时检测人的状态:通过 OpenCV 和 YOLOv8 完成动态画面检测人有没有在阳台上摔倒,是否发出红色报警弹窗。 + + + +### 设计流程 + +1.需求分析:确定我们组智能阳台的尺寸、材质和造型等。确定智能功能的 +需求,如窗帘和窗户根据温度和天气状况的自动打开和关闭、温湿度检测、为植 +物进行补光和浇水等。 + +2.概念设计:通过实物搭建确定智能阳台整体布局和组件位置。 +3.技术规格:确定所需要的硬件组,如传感器、水泵、窗帘和窗户、LED 灯、 +摄像头、显示屏等。 + +4.详细设计:设计主控器和各个单元模块的连接,设计系统程序代码进行数 +据传递。 + +5.原型设计:制作智能阳台的初步原型,对其进行工件及传感器的组装和加 +工。进行功能和美观性测试。 + +6.测试与迭代:对智能阳台进行全面的测试,包括功能测试、耐久性测试、 +反应速度的测试。根据测试结果进行设计迭代和改进。 + +\### 目录结构说明 + +code + +第一个是模块驱动代码主要讲了电机、水泵、显示屏等一系列传感器怎么运作的等等一系列的,这一部分是重要的运作代码,程序实现运作功能。 + +第二个是主要逻辑和历程,这个是项目的最重要的部分是大脑,说明了各个逻辑的组合和实现,控制了驱动代码的运行和执行的功能包括了显示、通信、电机、水泵等一系列传感器的控制,指挥多模态智能阳台的运作。 + diff --git "a/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221.txt" "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221.txt" new file mode 100644 index 0000000000000000000000000000000000000000..db91b0d291b474ddf23e4ae54d4a7efc37e8166a --- /dev/null +++ "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221.txt" @@ -0,0 +1,452 @@ + +#include +#include + +#include "ohos_init.h" +#include "cmsis_os2.h" + +#include "bsp_led.h" +#include "bsp_wifi.h" +#include "lwip/netifapi.h" +#include "lwip/sockets.h" +#include "lwip/api_shell.h" + +#include "bsp_oled.h" +#include "bsp_sr04.h" +#include "bsp_beep.h" +#include "bsp_key.h" +#include "bsp_ds18b20.h" +#include "bsp_adc.h" +#include "bsp_dc_motor.h" +#include "bsp_relay.h" +#include "bsp_uart.h" + +uint8_t OLED_DISPLAY_BUF[64];//OLED显示缓存 +uint8_t AUTO_HAND_BIT = 0;//手动1自动0模式 + + +//温度 + +#define TEMPERATURE_MAX 99 //温度采集最大值 +#define TEMPERATURE_MIN 0 //温度采集最小值 + +uint8_t TEMPERATURE_SET_MAX = 40; //温度设置最大值 +uint8_t TEMPERATURE_SET_MIN = 0 ; //温度设置最小值 + +uint16_t temperature = 0; //温度 +//湿度 + +#define HUMIDITY_MAX 99 //湿度采集最大值 +#define HUMIDITY_MIN 0 //湿度采集最小值 + +uint8_t HUMIDITY_SET_MAX = 80; //湿度设置最大值 +uint8_t HUMIDITY_SET_MIN = 0; //湿度设置最小值 + +uint8_t humidity = 0; //湿度 + + + +//土壤湿度 + +#define SOIL_MAX 255 //SOIL采集最大值 +#define SOIL_MIN 0 //SOIL采集最小值 + +uint8_t SOIL_SET_MAX = 200; //SOIL设置最大值 +uint8_t SOIL_SET_MIN = 100 ; //SOIL设置最小值 +uint8_t soil = 0; //SOIL + +//5.光照 + +#define LIGHT_MAX 255 //光照采集最大值 +#define LIGHT_MIN 0 //光照采集最小值 + +uint8_t LIGHT_SET_MAX = 100; //光照设置最大值 +uint8_t LIGHT_SET_MIN = 30 ; //光照设置最小值 + +uint8_t light = 0; //光照 +#define RAIN_MAX 255 //雨量采集最大值 +#define RAIN_MIN 0 //雨量采集最小值 + +uint8_t RAIN_SET_MAX = 100; //雨量设置最大值 +uint8_t RAIN_SET_MIN = 20 ; //雨量设置最小值 + +uint16_t rain = 0; //雨量 + +uint8_t ON_MOTOR1_BIT = 1;//窗户 +uint8_t OFF_MOTOR1_BIT = 1; + +uint8_t ON_MOTOR2_BIT = 1; +uint8_t OFF_MOTOR2_BIT = 1;//窗帘 + + +uint8_t MOTOR1_STA = 0;//水泵状态 +uint8_t MOTOR2_STA = 0;//窗户状态 +uint8_t MOTOR3_STA = 0;//窗帘状态 +uint8_t LED_STA = 0;//LED状态 +uint8_t UART_BUF = 0; +void OPEN_MOTOR1()//正传打开 +{ + + if(ON_MOTOR1_BIT) + { + ON_MOTOR1_BIT = 0; + OFF_MOTOR1_BIT = 1; + MOTOR1_FWD();//正传 + usleep(2000*1000); + MOTOR1_STOP(); + } + +} +void CLOSE_MOTOR1()//反传关闭 +{ + + if(OFF_MOTOR1_BIT) + { + OFF_MOTOR1_BIT = 0; + ON_MOTOR1_BIT = 1; + MOTOR1_RVS();//右旋转 + usleep(2000*1000); + MOTOR1_STOP();//右旋转 + } +} +void OPEN_MOTOR2()//正传打开 +{ + + if(ON_MOTOR2_BIT) + { + ON_MOTOR2_BIT = 0; + OFF_MOTOR2_BIT = 1; + MOTOR2_FWD();//正传 + usleep(2000*1000); + MOTOR2_STOP(); + } + +} +void CLOSE_MOTOR2()//反传关闭 +{ + + if(OFF_MOTOR2_BIT) + { + OFF_MOTOR2_BIT = 0; + ON_MOTOR2_BIT = 1; + MOTOR2_RVS();//右旋转 + usleep(2000*1000); + MOTOR2_STOP();//右旋转 + } +} + +void Display_Init()//显示初始化内容 +{ + // 智(0) 能(1) 阳(2) 台(3) 系(4) 统(5) 温(6) 湿(7) 度(8) 光(9) 照(10) 雨(11) 滴(12) 状(13) 态(14) 模(15) 式(16) + // 智(0) 能(1) 阳(2) 台(3) 系(4) 统(5) 温(6) 湿(7) 度(8) 土(9) 壤(10) 光(11) 照(12) +/************ *************/ + //oled_showstring(0, 0,0); // + oled_showfontHZ(16,0,0,16,1); // + oled_showfontHZ(32,0,1,16,1); // + oled_showfontHZ(48,0,2,16,1); // + oled_showfontHZ(64,0,3,16,1); // + oled_showfontHZ(80,0,4,16,1); // + oled_showfontHZ(96,0,5,16,1); // + //oled_showstring(112,6,7); // + /***********温(6) 湿(7) 度(8)*****************/ + oled_showfontHZ(0,16,6,16,1); + oled_showfontHZ(16,16,8,16,1); + oled_showstring(32,16,":000",16); + oled_showfontHZ(64,16,7,16,1); + oled_showfontHZ(80,16,8,16,1); + oled_showstring(96,16,":000",16); + /*********** 光(9) 照(10) 雨(11) 滴(12) ********************/ + oled_showfontHZ(0,32,9,16,1); + oled_showfontHZ(16,32,10,16,1); + oled_showstring(32,32,":000",16); + oled_showfontHZ(64,32,11,16,1); + oled_showfontHZ(80,32,12,16,1); + oled_showstring(96,32,":N",16); + /*********** 状(13) 态(14)*************/ + oled_showfontHZ(0,48,13,16,1); // + oled_showfontHZ(16,48,14,16,1); // + oled_showstring(32,48,":N N N",16); + oled_showstring(96,48,"auto",16); +} + +void ALARM()//异常监测 +{ + + +} +//LED任务 +osThreadId_t LED_Task_ID; //led任务ID + +void LED_Task(void) +{ + uint8_t recbuf[1]; + uint8_t len=0; + led_init();//LED初始化 + uart0_init(115200); + while (1) + { + len=uart0_read_data(recbuf,1); + if(len > 0) + { + printf("len = %d,rec = %c\r\n",len,recbuf[0]); + UART_BUF = recbuf[0]; + recbuf[0] = 0; + } + // LED(1); + // MOTOR1_FWD_SET();MOTOR1_RVS_SET(); MOTOR2_FWD_SET();MOTOR2_RVS_SET(); + // usleep(1000*1000); //200ms + // LED(0); + // MOTOR1_FWD_CLR();MOTOR1_RVS_CLR(); MOTOR2_FWD_CLR();MOTOR2_RVS_CLR(); + // usleep(1000*1000); //200ms + + } +} +//LED任务创建 +void led_task_create(void) +{ + osThreadAttr_t taskOptions; + taskOptions.name = "LEDTask"; // 任务的名字 + taskOptions.attr_bits = 0; // 属性位 + taskOptions.cb_mem = NULL; // 堆空间地址 + taskOptions.cb_size = 0; // 堆空间大小 + taskOptions.stack_mem = NULL; // 栈空间地址 + taskOptions.stack_size = 1024; // 栈空间大小 单位:字节 + taskOptions.priority = osPriorityNormal; // 任务的优先级 + + LED_Task_ID = osThreadNew((osThreadFunc_t)LED_Task, NULL, &taskOptions); // 创建任务1 + if (LED_Task_ID != NULL) + { + printf("ID = %d, Create LED_Task_ID is OK!\n", LED_Task_ID); + } +} + +void Motor_Handle()//电机处理 +{ + if(MOTOR1_STA)//打开水泵 + { + oled_showstring(72,48,"Y",16); //显示水泵状态 + RELAY(1);//打开继电器 + } + else + { + oled_showstring(72,48,"N",16); //显示水泵状态 + RELAY(0);//关闭继电器 + } + if(MOTOR2_STA)//打开窗户 + { + oled_showstring(32,48,":Y",16); + OPEN_MOTOR1();//正传打开 + } + else + { + oled_showstring(32,48,":N",16); + CLOSE_MOTOR1();//反传关闭 + } + if(MOTOR3_STA)//打开窗帘 + { + oled_showstring(56,48,"Y",16); + OPEN_MOTOR2();//正传打开 + } + else + { + oled_showstring(56,48,"N",16); + CLOSE_MOTOR2();//反传关闭 + } + +} +void LED_Handle()//LED处理 +{ + if(LED_STA)//开灯 + { + LED(1);//开灯 + } + else//关灯 + { + LED(0);//关灯 + } +} + +//控制任务 +osThreadId_t OLED_Task_ID; //任务ID + +void OLED_Task(void) +{ + static uint8_t i=0; + uint16_t adc_value=0; + + float adc_vol; + float temper; + uint8_t key=0; + uint8_t key2=0; + + float dis=0; + char buf[32]; + oled_init(); + oled_clear(); + Display_Init();//显示初始化内容 + oled_refresh_gram(); + key_init();//按键初始化 + adc2_init(); + adc5_init(); + relay_init();//继电器初始化 + led_init();//LED初始化 + while(ds18b20_init()) + { + printf("DS18B20检测失败,请插好!\r\n"); + usleep(500*1000); //500ms + } + + printf("DS18B20检测成功!\r\n"); + MOTOR_FWD_RVS_GPIO_CFG();//初始化电机 + while (1) + { + key=key_scan(0);//按键扫描 + // if(key==KEY1_PRESS) + // { + // if(AUTO_HAND_BIT)//手动1自动0模式 + // { + // AUTO_HAND_BIT = 0;//自动0 + // oled_showstring(96,48,"auto",16); + // } + // else + // { + // AUTO_HAND_BIT = 1;//手动1 + // oled_showstring(96,48,"hand",16); + // } + // printf("AUTO_HAND_BIT = %d\r\n",AUTO_HAND_BIT); + // } + + if(soil < SOIL_SET_MIN) + { + oled_showstring(72,48,"Y",16); //显示水泵状态 + RELAY(1);//继电器吸合 + printf("==RELAY 1\r\n"); + } + else + { + oled_showstring(72,48,"N",16); //显示水泵状态 + RELAY(0);//继电器关闭 + printf("==RELAY 0\r\n"); + } + key2 = key2_get(); + if(key2 == KEY2_PRESS)//雨滴 + { + //printf("###key2 = %d\r\n",key2); + CLOSE_MOTOR1();//窗户反传关闭 + CLOSE_MOTOR2();//窗帘反传关闭 + oled_showstring(96,32,":Y",16);//雨滴状态 + oled_showstring(32,48,":N N",16); + } + else + { + oled_showstring(96,32,":N",16);//雨滴状态 + //printf("==key2 = %d\r\n",key2); + if(light < LIGHT_SET_MIN) + { + printf("==1111= %d\r\n",key2); + LED(1);//开灯 + CLOSE_MOTOR1();//窗户反传关闭 + CLOSE_MOTOR2();//窗帘反传关闭 + + oled_showstring(32,48,":N N",16); //窗户窗帘状态 + } + else if(light > LIGHT_SET_MAX) + { + printf("==222 = %d\r\n",key2); + LED(0);//关灯 + OPEN_MOTOR1();//窗户正传打开 + OPEN_MOTOR2();//窗帘正传打开 + + oled_showstring(32,48,":Y Y",16); //窗户窗帘状态 + } + else + { + printf("==333 = %d\r\n",key2); + } + + } + + + i++; + if(i > 5) + { + i = 0; + temper=ds18b20_gettemperture(); + temperature = (uint16_t)(temper*10.0); + if(temper<0) + { + printf("检测的温度为:-"); + } + else + { + printf("检测的温度为: "); + } + printf("%.1f°C\r\n",temper); + } + + adc_value=get_adc5_value() - 120; + soil = adc_value / 8 ; + adc_value=get_adc2_value() - 120; + light = 255 - (adc_value / 8 ); + //printf("adc_value=%d\r\n",adc_value); + //adc_vol=get_adc5_voltage(); + //printf("adc_vol=%.1f\r\n",adc_vol); + + //printf("温度=%d°C,湿度=%d,light = %d,key = %d,key2 = %d\r\n",temperature,soil,light,key,key2); + + memset(OLED_DISPLAY_BUF, 0, sizeof(OLED_DISPLAY_BUF)); // 先清除整个缓冲 + OLED_DISPLAY_BUF[0] = temperature / 100 + 0x30; + OLED_DISPLAY_BUF[1] = temperature / 10 % 10 + 0x30; + OLED_DISPLAY_BUF[2] = 'C'; + OLED_DISPLAY_BUF[3] = '\0'; + oled_showstring(40,16,(unsigned char*)OLED_DISPLAY_BUF,16); + memset(OLED_DISPLAY_BUF, 0, sizeof(OLED_DISPLAY_BUF)); // 先清除整个缓冲 + OLED_DISPLAY_BUF[0] = soil / 100 + 0x30; + OLED_DISPLAY_BUF[1] = soil / 10 % 10 + 0x30; + OLED_DISPLAY_BUF[2] = soil % 10 + 0x30; + OLED_DISPLAY_BUF[3] = '\0'; + oled_showstring(104,16,(unsigned char*)OLED_DISPLAY_BUF,16); + memset(OLED_DISPLAY_BUF, 0, sizeof(OLED_DISPLAY_BUF)); // 先清除整个缓冲 + OLED_DISPLAY_BUF[0] = light / 100 + 0x30; + OLED_DISPLAY_BUF[1] = light / 10 % 10 + 0x30; + OLED_DISPLAY_BUF[2] = light % 10 + 0x30; + OLED_DISPLAY_BUF[3] = '\0'; + oled_showstring(40,32,(unsigned char*)OLED_DISPLAY_BUF,16); + + oled_refresh_gram(); + usleep(2*1000); //2ms + } +} +//任务创建 +void oled_task_create(void) +{ + osThreadAttr_t taskOptions; + taskOptions.name = "oledTask"; // 任务的名字 + taskOptions.attr_bits = 0; // 属性位 + taskOptions.cb_mem = NULL; // 堆空间地址 + taskOptions.cb_size = 0; // 堆空间大小 + taskOptions.stack_mem = NULL; // 栈空间地址 + taskOptions.stack_size = 1024; // 栈空间大小 单位:字节 + taskOptions.priority = osPriorityNormal; // 任务的优先级 + + OLED_Task_ID = osThreadNew((osThreadFunc_t)OLED_Task, NULL, &taskOptions); // 创建任务 + if (OLED_Task_ID != NULL) + { + printf("ID = %d, Task Create OK!\n", OLED_Task_ID); + } +} + + +/** + * @description: 初始化并创建任务 + * @param {*} + * @return {*} + */ +static void template_demo(void) +{ + printf("普中-Hi3861开发板--WIFI UDP实验\r\n"); + // led_task_create(); + oled_task_create();//任务创建 + +} +SYS_RUN(template_demo); diff --git "a/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_adc.c" "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_adc.c" new file mode 100644 index 0000000000000000000000000000000000000000..8c88212ffdeb655b17f24bd48a67a51c421191ba --- /dev/null +++ "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_adc.c" @@ -0,0 +1,57 @@ +/** + **************************************************************************************************** + * @file bsp_adc.c + * @author 普中科技 + * @version V1.0 + * @date 2024-06-05 + * @brief ADC实验 + * @license Copyright (c) 2024-2034, 深圳市普中科技有限公司 + **************************************************************************************************** + * @attention + * + * 实验平台:普中-Hi3861 + * 在线视频:https://space.bilibili.com/2146492485 + * 公司网址:www.prechin.cn + * 购买地址: + * + */ + +#include "bsp_adc.h" +#include +#include "hi_adc.h" +//ADC初始化 +void adc2_init(void) +{ + hi_gpio_init(); // GPIO初始化 + hi_io_set_pull(ADC2_PIN, HI_IO_PULL_UP); // 设置GPIO上拉 +} + +//ADC初始化 +void adc5_init(void) +{ + hi_gpio_init(); // GPIO初始化 + hi_io_set_pull(ADC5_PIN, HI_IO_PULL_UP); // 设置GPIO上拉 +} + +//读取AD值 +uint16_t get_adc5_value(void) +{ + uint16_t data; + hi_adc_read(HI_ADC_CHANNEL_5,&data,HI_ADC_EQU_MODEL_8,HI_ADC_CUR_BAIS_DEFAULT,0xff); + return data; +} + +//读取AD值 +uint16_t get_adc2_value(void) +{ + uint16_t data; + hi_adc_read(HI_ADC_CHANNEL_2,&data,HI_ADC_EQU_MODEL_8,HI_ADC_CUR_BAIS_DEFAULT,0xff); + return data; +} + +//读取电压 +float get_adc5_voltage(void) +{ + return hi_adc_convert_to_voltage(get_adc5_value()); +} + diff --git "a/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_adc_1.c" "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_adc_1.c" new file mode 100644 index 0000000000000000000000000000000000000000..8c88212ffdeb655b17f24bd48a67a51c421191ba --- /dev/null +++ "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_adc_1.c" @@ -0,0 +1,57 @@ +/** + **************************************************************************************************** + * @file bsp_adc.c + * @author 普中科技 + * @version V1.0 + * @date 2024-06-05 + * @brief ADC实验 + * @license Copyright (c) 2024-2034, 深圳市普中科技有限公司 + **************************************************************************************************** + * @attention + * + * 实验平台:普中-Hi3861 + * 在线视频:https://space.bilibili.com/2146492485 + * 公司网址:www.prechin.cn + * 购买地址: + * + */ + +#include "bsp_adc.h" +#include +#include "hi_adc.h" +//ADC初始化 +void adc2_init(void) +{ + hi_gpio_init(); // GPIO初始化 + hi_io_set_pull(ADC2_PIN, HI_IO_PULL_UP); // 设置GPIO上拉 +} + +//ADC初始化 +void adc5_init(void) +{ + hi_gpio_init(); // GPIO初始化 + hi_io_set_pull(ADC5_PIN, HI_IO_PULL_UP); // 设置GPIO上拉 +} + +//读取AD值 +uint16_t get_adc5_value(void) +{ + uint16_t data; + hi_adc_read(HI_ADC_CHANNEL_5,&data,HI_ADC_EQU_MODEL_8,HI_ADC_CUR_BAIS_DEFAULT,0xff); + return data; +} + +//读取AD值 +uint16_t get_adc2_value(void) +{ + uint16_t data; + hi_adc_read(HI_ADC_CHANNEL_2,&data,HI_ADC_EQU_MODEL_8,HI_ADC_CUR_BAIS_DEFAULT,0xff); + return data; +} + +//读取电压 +float get_adc5_voltage(void) +{ + return hi_adc_convert_to_voltage(get_adc5_value()); +} + diff --git "a/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_beep.c" "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_beep.c" new file mode 100644 index 0000000000000000000000000000000000000000..fa9ee90a56548dc6ef0deeb3a71daba015ea5706 --- /dev/null +++ "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_beep.c" @@ -0,0 +1,41 @@ +/** + **************************************************************************************************** + * @file bsp_beep.c + * @author 普中科技 + * @version V1.0 + * @date 2024-06-05 + * @brief 蜂鸣器实验 + * @license Copyright (c) 2024-2034, 深圳市普中科技有限公司 + **************************************************************************************************** + * @attention + * + * 实验平台:普中-Hi3861 + * 在线视频:https://space.bilibili.com/2146492485 + * 公司网址:www.prechin.cn + * 购买地址: + * + */ + +#include "bsp_beep.h" + + +//蜂鸣器初始化 +void beep_init(void) +{ + hi_gpio_init(); // GPIO初始化 + hi_io_set_pull(BEEP_PIN, HI_IO_PULL_UP); // 设置GPIO上拉 + hi_io_set_func(BEEP_PIN, BEEP_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(BEEP_PIN, HI_GPIO_DIR_OUT); // 设置GPIO为输出模式 +} + +//蜂鸣器报警 +void beep_alarm(uint16_t cnt,uint16_t time) +{ + while(cnt--) + { + BEEP(1); + usleep(time); + BEEP(0); + usleep(time); + } +} diff --git "a/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_beep_1.c" "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_beep_1.c" new file mode 100644 index 0000000000000000000000000000000000000000..fa9ee90a56548dc6ef0deeb3a71daba015ea5706 --- /dev/null +++ "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_beep_1.c" @@ -0,0 +1,41 @@ +/** + **************************************************************************************************** + * @file bsp_beep.c + * @author 普中科技 + * @version V1.0 + * @date 2024-06-05 + * @brief 蜂鸣器实验 + * @license Copyright (c) 2024-2034, 深圳市普中科技有限公司 + **************************************************************************************************** + * @attention + * + * 实验平台:普中-Hi3861 + * 在线视频:https://space.bilibili.com/2146492485 + * 公司网址:www.prechin.cn + * 购买地址: + * + */ + +#include "bsp_beep.h" + + +//蜂鸣器初始化 +void beep_init(void) +{ + hi_gpio_init(); // GPIO初始化 + hi_io_set_pull(BEEP_PIN, HI_IO_PULL_UP); // 设置GPIO上拉 + hi_io_set_func(BEEP_PIN, BEEP_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(BEEP_PIN, HI_GPIO_DIR_OUT); // 设置GPIO为输出模式 +} + +//蜂鸣器报警 +void beep_alarm(uint16_t cnt,uint16_t time) +{ + while(cnt--) + { + BEEP(1); + usleep(time); + BEEP(0); + usleep(time); + } +} diff --git "a/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_dc_motor.c" "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_dc_motor.c" new file mode 100644 index 0000000000000000000000000000000000000000..b34cc6c608689314a91b958838b26af43e23e82a --- /dev/null +++ "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_dc_motor.c" @@ -0,0 +1,87 @@ +/** + **************************************************************************************************** + * @file bsp_dc_motor.c + * @author 普中科技 + * @version V1.0 + * @date 2024-06-05 + * @brief 直流电机实验 + * @license Copyright (c) 2024-2034, 深圳市普中科技有限公司 + **************************************************************************************************** + * @attention + * + * 实验平台:普中-Hi3861 + * 在线视频:https://space.bilibili.com/2146492485 + * 公司网址:www.prechin.cn + * 购买地址: + * + */ + +#include "bsp_dc_motor.h" +void MOTOR1_FWD()//正转 +{ + MOTOR1_FWD_SET(); + MOTOR1_RVS_CLR(); +} +void MOTOR1_RVS()//反转 +{ + MOTOR1_FWD_CLR(); + MOTOR1_RVS_SET(); +} +void MOTOR1_STOP()//停止 +{ + MOTOR1_FWD_CLR(); + MOTOR1_RVS_CLR(); +} + + +void MOTOR2_FWD()//正转 +{ + MOTOR2_FWD_SET(); + MOTOR2_RVS_CLR(); +} +void MOTOR2_RVS()//反转 +{ + MOTOR2_FWD_CLR(); + MOTOR2_RVS_SET(); +} +void MOTOR2_STOP()//停止 +{ + MOTOR2_FWD_CLR(); + MOTOR2_RVS_CLR(); +} + +//LED初始化 +void MOTOR_FWD_RVS_GPIO_CFG(void) +{ + hi_gpio_init(); // GPIO初始化 + hi_io_set_pull(MOTOR1_FWD_GPIO_PIN, HI_IO_PULL_DOWN); // 设置GPIO下拉 + hi_io_set_func(MOTOR1_FWD_GPIO_PIN, MOTOR1_FWD_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(MOTOR1_FWD_GPIO_PIN, HI_GPIO_DIR_OUT); // 设置GPIO为输出模式 + + hi_io_set_pull(MOTOR1_RVS_GPIO_PIN, HI_IO_PULL_DOWN); // 设置GPIO下拉 + hi_io_set_func(MOTOR1_RVS_GPIO_PIN, MOTOR1_RVS_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(MOTOR1_RVS_GPIO_PIN, HI_GPIO_DIR_OUT); // 设置GPIO为输出模式 + + hi_io_set_pull(MOTOR2_FWD_GPIO_PIN, HI_IO_PULL_DOWN); // 设置GPIO下拉 + hi_io_set_func(MOTOR2_FWD_GPIO_PIN, MOTOR2_FWD_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(MOTOR2_FWD_GPIO_PIN, HI_GPIO_DIR_OUT); // 设置GPIO为输出模式 + + hi_io_set_pull(MOTOR2_RVS_GPIO_PIN, HI_IO_PULL_DOWN); // 设置GPIO下拉 + hi_io_set_func(MOTOR2_RVS_GPIO_PIN, MOTOR2_RVS_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(MOTOR2_RVS_GPIO_PIN, HI_GPIO_DIR_OUT); // 设置GPIO为输出模式 +} + + + + + + +// //直流电机初始化 +// void dc_motor_init(void) +// { +// hi_gpio_init(); // GPIO初始化 +// hi_io_set_pull(DC_MOTOR_PIN, HI_IO_PULL_DOWN); // 设置GPIO下拉 +// hi_io_set_func(DC_MOTOR_PIN, DC_MOTOR_GPIO_FUN); // 设置IO为GPIO功能 +// hi_gpio_set_dir(DC_MOTOR_PIN, ); // 设置GPIO为输出模式 +// } + diff --git "a/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_dc_motor_1.c" "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_dc_motor_1.c" new file mode 100644 index 0000000000000000000000000000000000000000..b34cc6c608689314a91b958838b26af43e23e82a --- /dev/null +++ "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_dc_motor_1.c" @@ -0,0 +1,87 @@ +/** + **************************************************************************************************** + * @file bsp_dc_motor.c + * @author 普中科技 + * @version V1.0 + * @date 2024-06-05 + * @brief 直流电机实验 + * @license Copyright (c) 2024-2034, 深圳市普中科技有限公司 + **************************************************************************************************** + * @attention + * + * 实验平台:普中-Hi3861 + * 在线视频:https://space.bilibili.com/2146492485 + * 公司网址:www.prechin.cn + * 购买地址: + * + */ + +#include "bsp_dc_motor.h" +void MOTOR1_FWD()//正转 +{ + MOTOR1_FWD_SET(); + MOTOR1_RVS_CLR(); +} +void MOTOR1_RVS()//反转 +{ + MOTOR1_FWD_CLR(); + MOTOR1_RVS_SET(); +} +void MOTOR1_STOP()//停止 +{ + MOTOR1_FWD_CLR(); + MOTOR1_RVS_CLR(); +} + + +void MOTOR2_FWD()//正转 +{ + MOTOR2_FWD_SET(); + MOTOR2_RVS_CLR(); +} +void MOTOR2_RVS()//反转 +{ + MOTOR2_FWD_CLR(); + MOTOR2_RVS_SET(); +} +void MOTOR2_STOP()//停止 +{ + MOTOR2_FWD_CLR(); + MOTOR2_RVS_CLR(); +} + +//LED初始化 +void MOTOR_FWD_RVS_GPIO_CFG(void) +{ + hi_gpio_init(); // GPIO初始化 + hi_io_set_pull(MOTOR1_FWD_GPIO_PIN, HI_IO_PULL_DOWN); // 设置GPIO下拉 + hi_io_set_func(MOTOR1_FWD_GPIO_PIN, MOTOR1_FWD_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(MOTOR1_FWD_GPIO_PIN, HI_GPIO_DIR_OUT); // 设置GPIO为输出模式 + + hi_io_set_pull(MOTOR1_RVS_GPIO_PIN, HI_IO_PULL_DOWN); // 设置GPIO下拉 + hi_io_set_func(MOTOR1_RVS_GPIO_PIN, MOTOR1_RVS_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(MOTOR1_RVS_GPIO_PIN, HI_GPIO_DIR_OUT); // 设置GPIO为输出模式 + + hi_io_set_pull(MOTOR2_FWD_GPIO_PIN, HI_IO_PULL_DOWN); // 设置GPIO下拉 + hi_io_set_func(MOTOR2_FWD_GPIO_PIN, MOTOR2_FWD_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(MOTOR2_FWD_GPIO_PIN, HI_GPIO_DIR_OUT); // 设置GPIO为输出模式 + + hi_io_set_pull(MOTOR2_RVS_GPIO_PIN, HI_IO_PULL_DOWN); // 设置GPIO下拉 + hi_io_set_func(MOTOR2_RVS_GPIO_PIN, MOTOR2_RVS_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(MOTOR2_RVS_GPIO_PIN, HI_GPIO_DIR_OUT); // 设置GPIO为输出模式 +} + + + + + + +// //直流电机初始化 +// void dc_motor_init(void) +// { +// hi_gpio_init(); // GPIO初始化 +// hi_io_set_pull(DC_MOTOR_PIN, HI_IO_PULL_DOWN); // 设置GPIO下拉 +// hi_io_set_func(DC_MOTOR_PIN, DC_MOTOR_GPIO_FUN); // 设置IO为GPIO功能 +// hi_gpio_set_dir(DC_MOTOR_PIN, ); // 设置GPIO为输出模式 +// } + diff --git "a/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_dht11.c" "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_dht11.c" new file mode 100644 index 0000000000000000000000000000000000000000..fb68b3ca1eaf6d567a34df2b83e906773ec2b8b8 --- /dev/null +++ "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_dht11.c" @@ -0,0 +1,158 @@ +/** + **************************************************************************************************** + * @file bsp_dht11.c + * @author 普中科技 + * @version V1.0 + * @date 2024-06-05 + * @brief DHT11温湿度传感器实验 + * @license Copyright (c) 2024-2034, 深圳市普中科技有限公司 + **************************************************************************************************** + * @attention + * + * 实验平台:普中-Hi3861 + * 在线视频:https://space.bilibili.com/2146492485 + * 公司网址:www.prechin.cn + * 购买地址: + * + */ + +#include "bsp_dht11.h" +#include +#include "hi_time.h" + + +//DHT11输出配置 +void dht11_io_out(void) +{ + hi_gpio_init(); // GPIO初始化 + hi_io_set_pull(DHT11_PIN, HI_IO_PULL_UP); // 设置GPIO上拉 + hi_io_set_func(DHT11_PIN, DHT11_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(DHT11_PIN, HI_GPIO_DIR_OUT); // 设置GPIO为输出模式 +} + +//DHT11输入配置 +void dht11_io_in(void) +{ + hi_io_set_pull(DHT11_PIN, HI_IO_PULL_NONE); // 设置GPIO浮空 + hi_gpio_set_dir(DHT11_PIN, HI_GPIO_DIR_IN); // 设置GPIO为输入模式 +} + +/****************************************************** + * 函数名 :GPIO_GetInputValue + * 功能 :获取GPIO输入状态 + * 输入 :id, *val + * 输出 :0/1 + *******************************************************/ +hi_gpio_value DHT11_DQ_IN = {0}; +uint8_t GPIO_GetInputValue(hi_gpio_idx id,hi_gpio_value *val) +{ + hi_gpio_get_input_val(id,val); + return *val; +} + +//dht11复位 +void dht11_reset(void) +{ + hi_gpio_set_dir(DHT11_PIN, HI_GPIO_DIR_OUT); // 设置GPIO为输出模式 + DHT11_DQ_OUT(0); //拉低DQ + hi_udelay(20*1000); //拉低至少18ms + DHT11_DQ_OUT(1); //DQ=1 + hi_udelay(30); //30US +} + +//等待DHT11的回应 +//返回1:未检测到DHT11的存在 +//返回0:存在 +uint8_t dht11_check(void) +{ + uint8_t retry=0; + dht11_io_in(); + while (GPIO_GetInputValue(DHT11_PIN,&DHT11_DQ_IN)&&retry<100)//DHT11会拉低40~50us + { + retry++; + hi_udelay(1); + }; + if(retry>=100)return 1; + else retry=0; + while ((!GPIO_GetInputValue(DHT11_PIN,&DHT11_DQ_IN))&&retry<100)//DHT11拉低后会再次拉高40~50us + { + retry++; + hi_udelay(1); + }; + if(retry>=100)return 1; + return 0; +} + +//从DHT11读取一个位 +//返回值:1/0 +uint8_t dht11_read_bit(void) +{ + uint8_t retry=0; + dht11_io_in(); + while(GPIO_GetInputValue(DHT11_PIN,&DHT11_DQ_IN)&&retry<100)//等待变为低电平 12-14us 开始 + { + retry++; + hi_udelay(1); + } + retry=0; + while((!GPIO_GetInputValue(DHT11_PIN,&DHT11_DQ_IN))&&retry<100)//等待变高电平 26-28us表示0,116-118us表示1 + { + retry++; + hi_udelay(1); + } + hi_udelay(40);//等待40us + if(GPIO_GetInputValue(DHT11_PIN,&DHT11_DQ_IN))return 1; + else return 0; +} + +//从DHT11读取一个字节 +//返回值:读到的数据 +uint8_t dht11_read_byte(void) +{ + uint8_t i,dat; + dat=0; + for (i=0;i<8;i++) + { + dat<<=1; + dat|=dht11_read_bit(); + } + return dat; +} + +//从DHT11读取一次数据 +//temp:温度值(范围:0~50°) +//humi:湿度值(范围:20%~90%) +//返回值:0,正常;1,读取失败 +uint8_t dht11_read_data(uint8_t *temp,uint8_t *humi) +{ + uint8_t buf[5]; + uint8_t i; + dht11_reset(); + if(dht11_check()==0) + { + for(i=0;i<5;i++)//读取40位数据 + { + buf[i]=dht11_read_byte(); + } + if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]) + { + *humi=buf[0]; + *temp=buf[2]; + } + + }else return 1; + return 0; +} + +//DHT11初始化 +//返回0:初始化成功,1:失败 +uint8_t dht11_init(void) +{ + hi_gpio_init(); // GPIO初始化 + hi_io_set_pull(DHT11_PIN, HI_IO_PULL_UP); // 设置GPIO上拉 + hi_io_set_func(DHT11_PIN, DHT11_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(DHT11_PIN, HI_GPIO_DIR_OUT); // 设置GPIO为输出模式 + + dht11_reset(); + return dht11_check(); +} diff --git "a/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_dht11_1.c" "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_dht11_1.c" new file mode 100644 index 0000000000000000000000000000000000000000..fb68b3ca1eaf6d567a34df2b83e906773ec2b8b8 --- /dev/null +++ "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_dht11_1.c" @@ -0,0 +1,158 @@ +/** + **************************************************************************************************** + * @file bsp_dht11.c + * @author 普中科技 + * @version V1.0 + * @date 2024-06-05 + * @brief DHT11温湿度传感器实验 + * @license Copyright (c) 2024-2034, 深圳市普中科技有限公司 + **************************************************************************************************** + * @attention + * + * 实验平台:普中-Hi3861 + * 在线视频:https://space.bilibili.com/2146492485 + * 公司网址:www.prechin.cn + * 购买地址: + * + */ + +#include "bsp_dht11.h" +#include +#include "hi_time.h" + + +//DHT11输出配置 +void dht11_io_out(void) +{ + hi_gpio_init(); // GPIO初始化 + hi_io_set_pull(DHT11_PIN, HI_IO_PULL_UP); // 设置GPIO上拉 + hi_io_set_func(DHT11_PIN, DHT11_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(DHT11_PIN, HI_GPIO_DIR_OUT); // 设置GPIO为输出模式 +} + +//DHT11输入配置 +void dht11_io_in(void) +{ + hi_io_set_pull(DHT11_PIN, HI_IO_PULL_NONE); // 设置GPIO浮空 + hi_gpio_set_dir(DHT11_PIN, HI_GPIO_DIR_IN); // 设置GPIO为输入模式 +} + +/****************************************************** + * 函数名 :GPIO_GetInputValue + * 功能 :获取GPIO输入状态 + * 输入 :id, *val + * 输出 :0/1 + *******************************************************/ +hi_gpio_value DHT11_DQ_IN = {0}; +uint8_t GPIO_GetInputValue(hi_gpio_idx id,hi_gpio_value *val) +{ + hi_gpio_get_input_val(id,val); + return *val; +} + +//dht11复位 +void dht11_reset(void) +{ + hi_gpio_set_dir(DHT11_PIN, HI_GPIO_DIR_OUT); // 设置GPIO为输出模式 + DHT11_DQ_OUT(0); //拉低DQ + hi_udelay(20*1000); //拉低至少18ms + DHT11_DQ_OUT(1); //DQ=1 + hi_udelay(30); //30US +} + +//等待DHT11的回应 +//返回1:未检测到DHT11的存在 +//返回0:存在 +uint8_t dht11_check(void) +{ + uint8_t retry=0; + dht11_io_in(); + while (GPIO_GetInputValue(DHT11_PIN,&DHT11_DQ_IN)&&retry<100)//DHT11会拉低40~50us + { + retry++; + hi_udelay(1); + }; + if(retry>=100)return 1; + else retry=0; + while ((!GPIO_GetInputValue(DHT11_PIN,&DHT11_DQ_IN))&&retry<100)//DHT11拉低后会再次拉高40~50us + { + retry++; + hi_udelay(1); + }; + if(retry>=100)return 1; + return 0; +} + +//从DHT11读取一个位 +//返回值:1/0 +uint8_t dht11_read_bit(void) +{ + uint8_t retry=0; + dht11_io_in(); + while(GPIO_GetInputValue(DHT11_PIN,&DHT11_DQ_IN)&&retry<100)//等待变为低电平 12-14us 开始 + { + retry++; + hi_udelay(1); + } + retry=0; + while((!GPIO_GetInputValue(DHT11_PIN,&DHT11_DQ_IN))&&retry<100)//等待变高电平 26-28us表示0,116-118us表示1 + { + retry++; + hi_udelay(1); + } + hi_udelay(40);//等待40us + if(GPIO_GetInputValue(DHT11_PIN,&DHT11_DQ_IN))return 1; + else return 0; +} + +//从DHT11读取一个字节 +//返回值:读到的数据 +uint8_t dht11_read_byte(void) +{ + uint8_t i,dat; + dat=0; + for (i=0;i<8;i++) + { + dat<<=1; + dat|=dht11_read_bit(); + } + return dat; +} + +//从DHT11读取一次数据 +//temp:温度值(范围:0~50°) +//humi:湿度值(范围:20%~90%) +//返回值:0,正常;1,读取失败 +uint8_t dht11_read_data(uint8_t *temp,uint8_t *humi) +{ + uint8_t buf[5]; + uint8_t i; + dht11_reset(); + if(dht11_check()==0) + { + for(i=0;i<5;i++)//读取40位数据 + { + buf[i]=dht11_read_byte(); + } + if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]) + { + *humi=buf[0]; + *temp=buf[2]; + } + + }else return 1; + return 0; +} + +//DHT11初始化 +//返回0:初始化成功,1:失败 +uint8_t dht11_init(void) +{ + hi_gpio_init(); // GPIO初始化 + hi_io_set_pull(DHT11_PIN, HI_IO_PULL_UP); // 设置GPIO上拉 + hi_io_set_func(DHT11_PIN, DHT11_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(DHT11_PIN, HI_GPIO_DIR_OUT); // 设置GPIO为输出模式 + + dht11_reset(); + return dht11_check(); +} diff --git "a/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_ds18b20.c" "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_ds18b20.c" new file mode 100644 index 0000000000000000000000000000000000000000..a7f7eee58e177959ca8df646441297516cabd773 --- /dev/null +++ "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_ds18b20.c" @@ -0,0 +1,217 @@ +/** + **************************************************************************************************** + * @file bsp_ds18b20.c + * @author 普中科技 + * @version V1.0 + * @date 2024-06-05 + * @brief DS18B20温度传感器实验 + * @license Copyright (c) 2024-2034, 深圳市普中科技有限公司 + **************************************************************************************************** + * @attention + * + * 实验平台:普中-Hi3861 + * 在线视频:https://space.bilibili.com/2146492485 + * 公司网址:www.prechin.cn + * 购买地址: + * + */ + +#include "bsp_ds18b20.h" +#include +#include "hi_time.h" + + +//DS18B20输出配置 +void ds18b20_io_out(void) +{ + hi_gpio_init(); // GPIO初始化 + hi_io_set_pull(DS18B20_PIN, HI_IO_PULL_UP); // 设置GPIO上拉 + hi_io_set_func(DS18B20_PIN, DS18B20_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(DS18B20_PIN, HI_GPIO_DIR_OUT); // 设置GPIO为输出模式 +} + +//DS18B20输入配置 +void ds18b20_io_in(void) +{ + hi_io_set_pull(DS18B20_PIN, HI_IO_PULL_NONE); // 设置GPIO浮空 + hi_gpio_set_dir(DS18B20_PIN, HI_GPIO_DIR_IN); // 设置GPIO为输入模式 +} + +/****************************************************** + * 函数名 :GPIO_GetInputValue + * 功能 :获取GPIO输入状态 + * 输入 :id, *val + * 输出 :0/1 + *******************************************************/ +hi_gpio_value DS18B20_DQ_IN = {0}; +uint8_t GPIO_GetInputValue(hi_gpio_idx id,hi_gpio_value *val) +{ + hi_gpio_get_input_val(id,val); + return *val; +} + +//ds18b20复位 +void ds18b20_reset(void) +{ + hi_gpio_set_dir(DS18B20_PIN, HI_GPIO_DIR_OUT); // 设置GPIO为输出模式 + DS18B20_DQ_OUT(0); //拉低DQ + hi_udelay(750); //拉低750us + DS18B20_DQ_OUT(1); //DQ=1 + hi_udelay(15); //15US +} + +/******************************************************************************* +* 函 数 名 : ds18b20_check +* 函数功能 : 检测DS18B20是否存在 +* 输 入 : 无 +* 输 出 : 1:未检测到DS18B20的存在,0:存在 +*******************************************************************************/ +uint8_t ds18b20_check(void) +{ + uint8_t retry=0; + ds18b20_io_in(); + while (GPIO_GetInputValue(DS18B20_PIN,&DS18B20_DQ_IN)&&retry<200) + { + retry++; + hi_udelay(1); + }; + if(retry>=200)return 1; + else retry=0; + while ((!GPIO_GetInputValue(DS18B20_PIN,&DS18B20_DQ_IN))&&retry<240) + { + retry++; + hi_udelay(1); + }; + if(retry>=240)return 1; + return 0; +} + +/******************************************************************************* +* 函 数 名 : ds18b20_read_bit +* 函数功能 : 从DS18B20读取一个位 +* 输 入 : 无 +* 输 出 : 1/0 +*******************************************************************************/ +uint8_t ds18b20_read_bit(void) // read one bit +{ + uint8_t data; + + hi_gpio_set_dir(DS18B20_PIN, HI_GPIO_DIR_OUT); + DS18B20_DQ_OUT(0); + hi_udelay(2); + DS18B20_DQ_OUT(1); + ds18b20_io_in(); + hi_udelay(12); + if(GPIO_GetInputValue(DS18B20_PIN,&DS18B20_DQ_IN))data=1; + else data=0; + hi_udelay(50); + return data; +} + +/******************************************************************************* +* 函 数 名 : ds18b20_read_byte +* 函数功能 : 从DS18B20读取一个字节 +* 输 入 : 无 +* 输 出 : 一个字节数据 +*******************************************************************************/ +uint8_t ds18b20_read_byte(void) // read one byte +{ + uint8_t i,j,dat; + dat=0; + for (i=0;i<8;i++) + { + j=ds18b20_read_bit(); + dat=(j<<7)|(dat>>1); + } + return dat; +} + +/******************************************************************************* +* 函 数 名 : ds18b20_write_byte +* 函数功能 : 写一个字节到DS18B20 +* 输 入 : dat:要写入的字节 +* 输 出 : 无 +*******************************************************************************/ +void ds18b20_write_byte(uint8_t dat) +{ + uint8_t j; + uint8_t testb; + hi_gpio_set_dir(DS18B20_PIN, HI_GPIO_DIR_OUT); + for (j=1;j<=8;j++) + { + testb=dat&0x01; + dat=dat>>1; + if (testb) + { + DS18B20_DQ_OUT(0);// Write 1 + hi_udelay(2); + DS18B20_DQ_OUT(1); + hi_udelay(60); + } + else + { + DS18B20_DQ_OUT(0);// Write 0 + hi_udelay(60); + DS18B20_DQ_OUT(1); + hi_udelay(2); + } + } +} + +/******************************************************************************* +* 函 数 名 : ds18b20_start +* 函数功能 : 开始温度转换 +* 输 入 : 无 +* 输 出 : 无 +*******************************************************************************/ +void ds18b20_start(void)// ds1820 start convert +{ + ds18b20_reset(); + ds18b20_check(); + ds18b20_write_byte(0xcc);// skip rom + ds18b20_write_byte(0x44);// convert +} + +//DS18B20初始化 +uint8_t ds18b20_init(void) +{ + hi_gpio_init(); // GPIO初始化 + hi_io_set_pull(DS18B20_PIN, HI_IO_PULL_UP); // 设置GPIO上拉 + hi_io_set_func(DS18B20_PIN, DS18B20_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(DS18B20_PIN, HI_GPIO_DIR_OUT); // 设置GPIO为输出模式 + + ds18b20_reset(); + return ds18b20_check(); +} + +/******************************************************************************* +* 函 数 名 : ds18b20_gettemperture +* 函数功能 : 从ds18b20得到温度值 +* 输 入 : 无 +* 输 出 : 温度数据 +*******************************************************************************/ +float ds18b20_gettemperture(void) +{ + uint16_t temp; + uint8_t a,b; + float value; + ds18b20_start(); // ds1820 start convert + ds18b20_reset(); + ds18b20_check(); + ds18b20_write_byte(0xcc);// skip rom + ds18b20_write_byte(0xbe);// convert + a=ds18b20_read_byte(); // LSB + b=ds18b20_read_byte(); // MSB + temp=b; + temp=(temp<<8)+a; + if((temp&0xf800)==0xf800) + { + temp=(~temp)+1; + value=temp*(-0.0625); + } + else + { + value=temp*0.0625; + } + return value; +} diff --git "a/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_ds18b20_1.c" "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_ds18b20_1.c" new file mode 100644 index 0000000000000000000000000000000000000000..a7f7eee58e177959ca8df646441297516cabd773 --- /dev/null +++ "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_ds18b20_1.c" @@ -0,0 +1,217 @@ +/** + **************************************************************************************************** + * @file bsp_ds18b20.c + * @author 普中科技 + * @version V1.0 + * @date 2024-06-05 + * @brief DS18B20温度传感器实验 + * @license Copyright (c) 2024-2034, 深圳市普中科技有限公司 + **************************************************************************************************** + * @attention + * + * 实验平台:普中-Hi3861 + * 在线视频:https://space.bilibili.com/2146492485 + * 公司网址:www.prechin.cn + * 购买地址: + * + */ + +#include "bsp_ds18b20.h" +#include +#include "hi_time.h" + + +//DS18B20输出配置 +void ds18b20_io_out(void) +{ + hi_gpio_init(); // GPIO初始化 + hi_io_set_pull(DS18B20_PIN, HI_IO_PULL_UP); // 设置GPIO上拉 + hi_io_set_func(DS18B20_PIN, DS18B20_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(DS18B20_PIN, HI_GPIO_DIR_OUT); // 设置GPIO为输出模式 +} + +//DS18B20输入配置 +void ds18b20_io_in(void) +{ + hi_io_set_pull(DS18B20_PIN, HI_IO_PULL_NONE); // 设置GPIO浮空 + hi_gpio_set_dir(DS18B20_PIN, HI_GPIO_DIR_IN); // 设置GPIO为输入模式 +} + +/****************************************************** + * 函数名 :GPIO_GetInputValue + * 功能 :获取GPIO输入状态 + * 输入 :id, *val + * 输出 :0/1 + *******************************************************/ +hi_gpio_value DS18B20_DQ_IN = {0}; +uint8_t GPIO_GetInputValue(hi_gpio_idx id,hi_gpio_value *val) +{ + hi_gpio_get_input_val(id,val); + return *val; +} + +//ds18b20复位 +void ds18b20_reset(void) +{ + hi_gpio_set_dir(DS18B20_PIN, HI_GPIO_DIR_OUT); // 设置GPIO为输出模式 + DS18B20_DQ_OUT(0); //拉低DQ + hi_udelay(750); //拉低750us + DS18B20_DQ_OUT(1); //DQ=1 + hi_udelay(15); //15US +} + +/******************************************************************************* +* 函 数 名 : ds18b20_check +* 函数功能 : 检测DS18B20是否存在 +* 输 入 : 无 +* 输 出 : 1:未检测到DS18B20的存在,0:存在 +*******************************************************************************/ +uint8_t ds18b20_check(void) +{ + uint8_t retry=0; + ds18b20_io_in(); + while (GPIO_GetInputValue(DS18B20_PIN,&DS18B20_DQ_IN)&&retry<200) + { + retry++; + hi_udelay(1); + }; + if(retry>=200)return 1; + else retry=0; + while ((!GPIO_GetInputValue(DS18B20_PIN,&DS18B20_DQ_IN))&&retry<240) + { + retry++; + hi_udelay(1); + }; + if(retry>=240)return 1; + return 0; +} + +/******************************************************************************* +* 函 数 名 : ds18b20_read_bit +* 函数功能 : 从DS18B20读取一个位 +* 输 入 : 无 +* 输 出 : 1/0 +*******************************************************************************/ +uint8_t ds18b20_read_bit(void) // read one bit +{ + uint8_t data; + + hi_gpio_set_dir(DS18B20_PIN, HI_GPIO_DIR_OUT); + DS18B20_DQ_OUT(0); + hi_udelay(2); + DS18B20_DQ_OUT(1); + ds18b20_io_in(); + hi_udelay(12); + if(GPIO_GetInputValue(DS18B20_PIN,&DS18B20_DQ_IN))data=1; + else data=0; + hi_udelay(50); + return data; +} + +/******************************************************************************* +* 函 数 名 : ds18b20_read_byte +* 函数功能 : 从DS18B20读取一个字节 +* 输 入 : 无 +* 输 出 : 一个字节数据 +*******************************************************************************/ +uint8_t ds18b20_read_byte(void) // read one byte +{ + uint8_t i,j,dat; + dat=0; + for (i=0;i<8;i++) + { + j=ds18b20_read_bit(); + dat=(j<<7)|(dat>>1); + } + return dat; +} + +/******************************************************************************* +* 函 数 名 : ds18b20_write_byte +* 函数功能 : 写一个字节到DS18B20 +* 输 入 : dat:要写入的字节 +* 输 出 : 无 +*******************************************************************************/ +void ds18b20_write_byte(uint8_t dat) +{ + uint8_t j; + uint8_t testb; + hi_gpio_set_dir(DS18B20_PIN, HI_GPIO_DIR_OUT); + for (j=1;j<=8;j++) + { + testb=dat&0x01; + dat=dat>>1; + if (testb) + { + DS18B20_DQ_OUT(0);// Write 1 + hi_udelay(2); + DS18B20_DQ_OUT(1); + hi_udelay(60); + } + else + { + DS18B20_DQ_OUT(0);// Write 0 + hi_udelay(60); + DS18B20_DQ_OUT(1); + hi_udelay(2); + } + } +} + +/******************************************************************************* +* 函 数 名 : ds18b20_start +* 函数功能 : 开始温度转换 +* 输 入 : 无 +* 输 出 : 无 +*******************************************************************************/ +void ds18b20_start(void)// ds1820 start convert +{ + ds18b20_reset(); + ds18b20_check(); + ds18b20_write_byte(0xcc);// skip rom + ds18b20_write_byte(0x44);// convert +} + +//DS18B20初始化 +uint8_t ds18b20_init(void) +{ + hi_gpio_init(); // GPIO初始化 + hi_io_set_pull(DS18B20_PIN, HI_IO_PULL_UP); // 设置GPIO上拉 + hi_io_set_func(DS18B20_PIN, DS18B20_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(DS18B20_PIN, HI_GPIO_DIR_OUT); // 设置GPIO为输出模式 + + ds18b20_reset(); + return ds18b20_check(); +} + +/******************************************************************************* +* 函 数 名 : ds18b20_gettemperture +* 函数功能 : 从ds18b20得到温度值 +* 输 入 : 无 +* 输 出 : 温度数据 +*******************************************************************************/ +float ds18b20_gettemperture(void) +{ + uint16_t temp; + uint8_t a,b; + float value; + ds18b20_start(); // ds1820 start convert + ds18b20_reset(); + ds18b20_check(); + ds18b20_write_byte(0xcc);// skip rom + ds18b20_write_byte(0xbe);// convert + a=ds18b20_read_byte(); // LSB + b=ds18b20_read_byte(); // MSB + temp=b; + temp=(temp<<8)+a; + if((temp&0xf800)==0xf800) + { + temp=(~temp)+1; + value=temp*(-0.0625); + } + else + { + value=temp*0.0625; + } + return value; +} diff --git "a/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_exti.c" "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_exti.c" new file mode 100644 index 0000000000000000000000000000000000000000..bdbf307cfeb8a18737c2a0fdb39572dc19c4f9a5 --- /dev/null +++ "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_exti.c" @@ -0,0 +1,70 @@ +/** + **************************************************************************************************** + * @file bsp_exti.c + * @author 普中科技 + * @version V1.0 + * @date 2024-06-05 + * @brief 外部中断实验 + * @license Copyright (c) 2024-2034, 深圳市普中科技有限公司 + **************************************************************************************************** + * @attention + * + * 实验平台:普中-Hi3861 + * 在线视频:https://space.bilibili.com/2146492485 + * 公司网址:www.prechin.cn + * 购买地址: + * + */ + +#include "bsp_exti.h" +#include +#include "bsp_led.h" + + +//key1按键回调函数 +hi_void key1_exti_callback(void) +{ + static uint8_t key1=0; + usleep(10*1000);//消抖 + hi_gpio_get_input_val(KEY1_PIN,&key1); + if(key1==0) + { + LED(1); + } +} + +//key2按键回调函数 +hi_void key2_exti_callback(void) +{ + static uint8_t key2=0; + usleep(10*1000);//消抖 + hi_gpio_get_input_val(KEY2_PIN,&key2); + if(key2==0) + { + LED(0); + } +} + +//外部中断初始化 +void exti_init(void) +{ + hi_gpio_init(); // GPIO初始化 + hi_io_set_pull(KEY1_PIN, HI_IO_PULL_UP); // 设置GPIO上拉 + hi_io_set_func(KEY1_PIN, KEY1_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(KEY1_PIN, HI_GPIO_DIR_IN); // 设置GPIO为输入模式 + hi_gpio_register_isr_function(KEY1_PIN, // 按键引脚 + HI_INT_TYPE_EDGE, // 下降沿检测 + HI_GPIO_EDGE_FALL_LEVEL_LOW, // 低电平时触发 + &key1_exti_callback, // 触发后调用的回调函数 + NULL); // 回调函数的传参值 + + hi_io_set_pull(KEY2_PIN, HI_IO_PULL_UP); // 设置GPIO上拉 + hi_io_set_func(KEY2_PIN, KEY2_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(KEY2_PIN, HI_GPIO_DIR_IN); // 设置GPIO为输入模式 + hi_gpio_register_isr_function(KEY2_PIN, // 按键引脚 + HI_INT_TYPE_EDGE, // 下降沿检测 + HI_GPIO_EDGE_FALL_LEVEL_LOW, // 低电平时触发 + &key2_exti_callback, // 触发后调用的回调函数 + NULL); // 回调函数的传参值 +} + diff --git "a/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_exti_1.c" "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_exti_1.c" new file mode 100644 index 0000000000000000000000000000000000000000..bdbf307cfeb8a18737c2a0fdb39572dc19c4f9a5 --- /dev/null +++ "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_exti_1.c" @@ -0,0 +1,70 @@ +/** + **************************************************************************************************** + * @file bsp_exti.c + * @author 普中科技 + * @version V1.0 + * @date 2024-06-05 + * @brief 外部中断实验 + * @license Copyright (c) 2024-2034, 深圳市普中科技有限公司 + **************************************************************************************************** + * @attention + * + * 实验平台:普中-Hi3861 + * 在线视频:https://space.bilibili.com/2146492485 + * 公司网址:www.prechin.cn + * 购买地址: + * + */ + +#include "bsp_exti.h" +#include +#include "bsp_led.h" + + +//key1按键回调函数 +hi_void key1_exti_callback(void) +{ + static uint8_t key1=0; + usleep(10*1000);//消抖 + hi_gpio_get_input_val(KEY1_PIN,&key1); + if(key1==0) + { + LED(1); + } +} + +//key2按键回调函数 +hi_void key2_exti_callback(void) +{ + static uint8_t key2=0; + usleep(10*1000);//消抖 + hi_gpio_get_input_val(KEY2_PIN,&key2); + if(key2==0) + { + LED(0); + } +} + +//外部中断初始化 +void exti_init(void) +{ + hi_gpio_init(); // GPIO初始化 + hi_io_set_pull(KEY1_PIN, HI_IO_PULL_UP); // 设置GPIO上拉 + hi_io_set_func(KEY1_PIN, KEY1_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(KEY1_PIN, HI_GPIO_DIR_IN); // 设置GPIO为输入模式 + hi_gpio_register_isr_function(KEY1_PIN, // 按键引脚 + HI_INT_TYPE_EDGE, // 下降沿检测 + HI_GPIO_EDGE_FALL_LEVEL_LOW, // 低电平时触发 + &key1_exti_callback, // 触发后调用的回调函数 + NULL); // 回调函数的传参值 + + hi_io_set_pull(KEY2_PIN, HI_IO_PULL_UP); // 设置GPIO上拉 + hi_io_set_func(KEY2_PIN, KEY2_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(KEY2_PIN, HI_GPIO_DIR_IN); // 设置GPIO为输入模式 + hi_gpio_register_isr_function(KEY2_PIN, // 按键引脚 + HI_INT_TYPE_EDGE, // 下降沿检测 + HI_GPIO_EDGE_FALL_LEVEL_LOW, // 低电平时触发 + &key2_exti_callback, // 触发后调用的回调函数 + NULL); // 回调函数的传参值 +} + diff --git "a/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_key.c" "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_key.c" new file mode 100644 index 0000000000000000000000000000000000000000..c541b13878fc8df410b8d74ce8c6b113b3f529c3 --- /dev/null +++ "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_key.c" @@ -0,0 +1,77 @@ +/** + **************************************************************************************************** + * @file bsp_key.c + * @author 普中科技 + * @version V1.0 + * @date 2024-06-05 + * @brief 按键控制实验 + * @license Copyright (c) 2024-2034, 深圳市普中科技有限公司 + **************************************************************************************************** + * @attention + * + * 实验平台:普中-Hi3861 + * 在线视频:https://space.bilibili.com/2146492485 + * 公司网址:www.prechin.cn + * 购买地址: + * + */ + +#include "bsp_key.h" +#include + +//按键初始化 +void key_init(void) +{ + hi_gpio_init(); // GPIO初始化 + hi_io_set_pull(KEY1_PIN, HI_IO_PULL_UP); // 设置GPIO上拉 + hi_io_set_func(KEY1_PIN, KEY1_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(KEY1_PIN, HI_GPIO_DIR_IN); // 设置GPIO为输入模式 + + hi_io_set_pull(KEY2_PIN, HI_IO_PULL_UP); // 设置GPIO上拉 + hi_io_set_func(KEY2_PIN, KEY2_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(KEY2_PIN, HI_GPIO_DIR_IN); // 设置GPIO为输入模式 +} + +/******************************************************************************* +* 函 数 名 : key_scan +* 函数功能 : 检测独立按键是否按下,按下则返回对应键值 +* 输 入 : mode=0:单次扫描按键 + mode=1:连续扫描按键 +* 输 出 : KEY1_PRESS:K1按下 + KEY2_PRESS:K2按下 + KEY_UNPRESS:未有按键按下 +*******************************************************************************/ +uint8_t key_scan(uint8_t mode) +{ + static uint8_t key1=0; + hi_gpio_get_input_val(KEY1_PIN,&key1); + if(key1==0 ) + { + usleep(10*1000);//消抖 + hi_gpio_get_input_val(KEY1_PIN,&key1); + if(key1==0) + { + if(key1==0)return KEY1_PRESS; + } + } + + return KEY_UNPRESS; +} +uint8_t key2_get() +{ + + static uint8_t key2 = 0; + hi_gpio_get_input_val(KEY2_PIN,&key2); + if(key2==0 ) + { + usleep(10*1000);//消抖 + hi_gpio_get_input_val(KEY2_PIN,&key2); + if(key2==0) + { + if(key2==0)return KEY2_PRESS; + } + } + + return KEY_UNPRESS; + +} diff --git "a/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_key_1.c" "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_key_1.c" new file mode 100644 index 0000000000000000000000000000000000000000..c541b13878fc8df410b8d74ce8c6b113b3f529c3 --- /dev/null +++ "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_key_1.c" @@ -0,0 +1,77 @@ +/** + **************************************************************************************************** + * @file bsp_key.c + * @author 普中科技 + * @version V1.0 + * @date 2024-06-05 + * @brief 按键控制实验 + * @license Copyright (c) 2024-2034, 深圳市普中科技有限公司 + **************************************************************************************************** + * @attention + * + * 实验平台:普中-Hi3861 + * 在线视频:https://space.bilibili.com/2146492485 + * 公司网址:www.prechin.cn + * 购买地址: + * + */ + +#include "bsp_key.h" +#include + +//按键初始化 +void key_init(void) +{ + hi_gpio_init(); // GPIO初始化 + hi_io_set_pull(KEY1_PIN, HI_IO_PULL_UP); // 设置GPIO上拉 + hi_io_set_func(KEY1_PIN, KEY1_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(KEY1_PIN, HI_GPIO_DIR_IN); // 设置GPIO为输入模式 + + hi_io_set_pull(KEY2_PIN, HI_IO_PULL_UP); // 设置GPIO上拉 + hi_io_set_func(KEY2_PIN, KEY2_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(KEY2_PIN, HI_GPIO_DIR_IN); // 设置GPIO为输入模式 +} + +/******************************************************************************* +* 函 数 名 : key_scan +* 函数功能 : 检测独立按键是否按下,按下则返回对应键值 +* 输 入 : mode=0:单次扫描按键 + mode=1:连续扫描按键 +* 输 出 : KEY1_PRESS:K1按下 + KEY2_PRESS:K2按下 + KEY_UNPRESS:未有按键按下 +*******************************************************************************/ +uint8_t key_scan(uint8_t mode) +{ + static uint8_t key1=0; + hi_gpio_get_input_val(KEY1_PIN,&key1); + if(key1==0 ) + { + usleep(10*1000);//消抖 + hi_gpio_get_input_val(KEY1_PIN,&key1); + if(key1==0) + { + if(key1==0)return KEY1_PRESS; + } + } + + return KEY_UNPRESS; +} +uint8_t key2_get() +{ + + static uint8_t key2 = 0; + hi_gpio_get_input_val(KEY2_PIN,&key2); + if(key2==0 ) + { + usleep(10*1000);//消抖 + hi_gpio_get_input_val(KEY2_PIN,&key2); + if(key2==0) + { + if(key2==0)return KEY2_PRESS; + } + } + + return KEY_UNPRESS; + +} diff --git "a/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_led.c" "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_led.c" new file mode 100644 index 0000000000000000000000000000000000000000..972b76ccc6f538d0b6b008fa39b3cdccac46d449 --- /dev/null +++ "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_led.c" @@ -0,0 +1,29 @@ +/** + **************************************************************************************************** + * @file bsp_led.c + * @author 普中科技 + * @version V1.0 + * @date 2024-06-05 + * @brief LED实验 + * @license Copyright (c) 2024-2034, 深圳市普中科技有限公司 + **************************************************************************************************** + * @attention + * + * 实验平台:普中-Hi3861 + * 在线视频:https://space.bilibili.com/2146492485 + * 公司网址:www.prechin.cn + * 购买地址: + * + */ + +#include "bsp_led.h" + + +//LED初始化 +void led_init(void) +{ + hi_gpio_init(); // GPIO初始化 + hi_io_set_pull(LED_PIN, HI_IO_PULL_DOWN); // 设置GPIO下拉 + hi_io_set_func(LED_PIN, LED_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(LED_PIN, HI_GPIO_DIR_OUT); // 设置GPIO为输出模式 +} diff --git "a/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_led_1.c" "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_led_1.c" new file mode 100644 index 0000000000000000000000000000000000000000..972b76ccc6f538d0b6b008fa39b3cdccac46d449 --- /dev/null +++ "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_led_1.c" @@ -0,0 +1,29 @@ +/** + **************************************************************************************************** + * @file bsp_led.c + * @author 普中科技 + * @version V1.0 + * @date 2024-06-05 + * @brief LED实验 + * @license Copyright (c) 2024-2034, 深圳市普中科技有限公司 + **************************************************************************************************** + * @attention + * + * 实验平台:普中-Hi3861 + * 在线视频:https://space.bilibili.com/2146492485 + * 公司网址:www.prechin.cn + * 购买地址: + * + */ + +#include "bsp_led.h" + + +//LED初始化 +void led_init(void) +{ + hi_gpio_init(); // GPIO初始化 + hi_io_set_pull(LED_PIN, HI_IO_PULL_DOWN); // 设置GPIO下拉 + hi_io_set_func(LED_PIN, LED_GPIO_FUN); // 设置IO为GPIO功能 + hi_gpio_set_dir(LED_PIN, HI_GPIO_DIR_OUT); // 设置GPIO为输出模式 +} diff --git "a/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_mqtt.c" "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_mqtt.c" new file mode 100644 index 0000000000000000000000000000000000000000..6f28d7b4a9fad3d1b55b6ad88b38c7b91e366848 --- /dev/null +++ "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_mqtt.c" @@ -0,0 +1,272 @@ +/** + **************************************************************************************************** + * @file bsp_mqtt.c + * @author 普中科技 + * @version V1.0 + * @date 2024-06-05 + * @brief WIFI MQTT实验 + * @license Copyright (c) 2024-2034, 深圳市普中科技有限公司 + **************************************************************************************************** + * @attention + * + * 实验平台:普中-Hi3861 + * 在线视频:https://space.bilibili.com/2146492485 + * 公司网址:www.prechin.cn + * 购买地址: + * + */ + +#include +#include +#include +#include +#include "lwip/netifapi.h" +#include "lwip/sockets.h" +#include "wifi_device.h" +#include "ohos_init.h" +#include "MQTTPacket.h" +#include "bsp_mqtt.h" + +#define MQTT_BUFF_MAX_SIZE 512 + +int g_tcp_socket_fd = 0; // 网络套接字 +unsigned char mqttBuff[MQTT_BUFF_MAX_SIZE] = {0}; + +// 发送网络数据 +static int transport_sendPacketBuffer(unsigned char *buf, int buflen) +{ + int rc = send(g_tcp_socket_fd, buf, buflen, 0); + + return (rc <= 0) ? 0 : 1; +} +// 接收网络数据 +static int transport_getdata(unsigned char *buf, int count) +{ + int rc = recv(g_tcp_socket_fd, buf, count, 0); + return rc; +} + +// 连接服务器 +int MQTTClient_connectServer(const char *ip_addr, int ip_port) +{ + if (ip_addr == NULL) { + return -1; + } + + int res = 0; // 函数返回值 + struct sockaddr_in tcpServerConfig; // tcp服务器信息 + + // 创建TCP套接字 + g_tcp_socket_fd = socket(AF_INET, SOCK_STREAM, 0); + if (g_tcp_socket_fd < 0) { + printf("Failed to create Socket\r\n"); + } + + // 连接TCP服务器 + tcpServerConfig.sin_family = AF_INET; // IPV4 + tcpServerConfig.sin_port = htons(ip_port); // 填写服务器的IP端口号 + tcpServerConfig.sin_addr.s_addr = inet_addr(ip_addr); // 填写服务器的IP地址 + + res = connect(g_tcp_socket_fd, (struct sockaddr *)&tcpServerConfig, sizeof(tcpServerConfig)); // 连接服务器 + if (res == -1) { + printf("Failed to connect to the server\r\n"); + return -1; + } + printf("Connection to server successful\r\n"); + + return 0; +} + +// 断开TCP服务器 0:成功, -1:失败 +int MQTTClient_unConnectServer(void) +{ + int ret = 0; + printf("Server shut down successfully\r\n"); + ret = close(g_tcp_socket_fd); + g_tcp_socket_fd = 0; + return ret; +} + +// mqtt客户端 订阅主题 +int MQTTClient_subscribe(char *subTopic) +{ + if (subTopic == NULL) { + printf("Incorrect parameters\r\n"); + return -1; + } + + int len = 0, res = 0; + int subcount = 0, granted_qos = 0, req_qos = 0; + unsigned short submsgid = 0; + MQTTString topicString = MQTTString_initializer; + + /* subscribe */ + topicString.cstring = subTopic; + len = MQTTSerialize_subscribe(mqttBuff, sizeof(mqttBuff), 0, 1, 1, &topicString, &req_qos); + if (len <= 0) { + printf("MQTTSerialize_subscribe Error %d\r\n", len); + return -1; + } + res = transport_sendPacketBuffer(mqttBuff, len); + if (res != 1) { + printf("transport_sendPacketBuffer Error %d\r\n", res); + return -1; + } + + sleep(1); + memset_s(mqttBuff, sizeof(mqttBuff), 0, sizeof(mqttBuff)); + + /* wait for suback */ + if (MQTTPacket_read(mqttBuff, sizeof(mqttBuff), transport_getdata) != SUBACK) { + printf("MQTTPacket_read Error\r\n"); + return -1; + } + + if (MQTTDeserialize_suback(&submsgid, 1, &subcount, &granted_qos, mqttBuff, sizeof(mqttBuff)) != 1) { + printf("MQTTDeserialize_suback Error\r\n"); + return -1; + } + + printf("MQTT subscribed to topics successfully\r\n"); + + return 0; +} + +// 保持在线时长 60s +#define MQTT_KEEP_ALIVE 60 +#define MQTT_DELAY_TIME 3 + +// mqtt客户端 初始化 +int MQTTClient_init(char *clientID, char *userName, char *password) +{ + if (clientID == NULL || userName == NULL || password == NULL) { + printf("Incorrect parameters\r\n"); + return -1; + } + + int res = 0, len = 0, i = 0; + int mqtt_read_len = 10; + + unsigned char sessionPresent = 0, connack_rc = 0; + MQTTPacket_connectData mqttData = MQTTPacket_connectData_initializer; + + // 初始化MQTT客户端 + mqttData.clientID.cstring = clientID; + mqttData.username.cstring = userName; + mqttData.password.cstring = password; + mqttData.cleansession = true; // 是否初始化的时候,清除上一次的对话 + mqttData.keepAliveInterval = MQTT_KEEP_ALIVE; + + // 组MQTT消息包 + len = MQTTSerialize_connect(mqttBuff, sizeof(mqttBuff), &mqttData); + if (len <= 0) { + printf("MQTTSerialize_connect Error %d\r\n", res); + return -1; + } + res = transport_sendPacketBuffer(mqttBuff, len); + if (res != 1) { + printf("transport_sendPacketBuffer Error %d\r\n", res); + return -1; + } + + sleep(MQTT_DELAY_TIME); + + /* 打印发送出去的数据帧,调试用 */ + printf("MQTT_sendPacket: \r\n"); + for (i = 0; i < len; i++) { + printf("%x ", mqttBuff[i]); + } + printf("\r\n"); + + memset_s(mqttBuff, sizeof(mqttBuff), 0, sizeof(mqttBuff)); + + /* wait for connack */ + if (MQTTPacket_read(mqttBuff, sizeof(mqttBuff), transport_getdata) != CONNACK) { + printf("MQTTPacket_read != CONNACK\r\n"); + } + + printf("MQTT_recvPacket: \r\n"); + /* 打印服务器返回的消息,调试用 */ + for (i = 0; i < mqtt_read_len; i++) { + printf("%x ", mqttBuff[i]); + } + printf("\r\n"); + + if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, mqttBuff, sizeof(mqttBuff)) != 1 || connack_rc != 0) { + printf("Unable to connect, return code %d\r\n", connack_rc); + memset_s(mqttBuff, sizeof(mqttBuff), 0, sizeof(mqttBuff)); + return -1; + } else { + printf("MQTT initialized successfully\r\n"); + } + memset_s(mqttBuff, sizeof(mqttBuff), 0, sizeof(mqttBuff)); + return 0; +} + +#define MQTT_PUB_DATA_TIME (100 * 1000) + +int MQTTClient_pub(char *pub_Topic, unsigned char *payloadData, int payloadLen) +{ + if (payloadData == NULL) { + printf("Incorrect parameters\r\n"); + return -1; + } + + printf("pubTopic: %s\n", pub_Topic); + printf("pubData: %s\n", payloadData); + + int ret = 0, len = 0; + unsigned short retry_count = 5; // 重发次数 + unsigned char sendBuff[MQTT_BUFF_MAX_SIZE] = {0}; + MQTTString topicString = MQTTString_initializer; + + topicString.cstring = pub_Topic; + len = MQTTSerialize_publish(sendBuff, sizeof(sendBuff), 0, 0, 0, 0, topicString, + payloadData, + payloadLen); + while (--retry_count > 0) { + ret = transport_sendPacketBuffer(sendBuff, len); + if (ret == 1) { + break; + } + + printf("Send MQTT_Data Fail\r\n"); + usleep(MQTT_PUB_DATA_TIME); + } + + if (!retry_count && ret != 1) { + printf("transport_sendPacketBuffer Error %d\r\n", ret); + return -1; + } + + // printf("send==>%s", payloadData); + return 0; +} +unsigned char mqtt_topic[200]; +int8_t (*p_MQTTClient_sub_callback)(unsigned char *topic, unsigned char *payload); + +int MQTTClient_sub(void) +{ + int qos, payloadlen_in; + unsigned char dup, retained; + unsigned short msgid; + unsigned char *payload_in; + MQTTString receivedTopic; + + memset_s(mqttBuff, sizeof(mqttBuff), 0, sizeof(mqttBuff)); + // $oc/devices/63ad5a6cc4efcc747bd75973_lamp/sys/commands/request_id=42c20ffb-0885-4f6e-97b5-45d8f613efaf + if (MQTTPacket_read(mqttBuff, sizeof(mqttBuff), transport_getdata) == PUBLISH) { + MQTTDeserialize_publish(&dup, &qos, &retained, &msgid, &receivedTopic, + &payload_in, &payloadlen_in, mqttBuff, sizeof(mqttBuff)); + + printf("data: %s\n", receivedTopic.lenstring.data); + printf("length: %d\n", strlen(receivedTopic.lenstring.data) - payloadlen_in); + printf("payload_length: %d\n", payloadlen_in); + memcpy_s(mqtt_topic, sizeof(mqtt_topic), + receivedTopic.lenstring.data, strlen(receivedTopic.lenstring.data) - payloadlen_in); + printf("topic: %s\n", mqtt_topic); + printf("payload: %s\n", payload_in); + + p_MQTTClient_sub_callback(mqtt_topic, payload_in); + } +} diff --git "a/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_mqtt_1.c" "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_mqtt_1.c" new file mode 100644 index 0000000000000000000000000000000000000000..6f28d7b4a9fad3d1b55b6ad88b38c7b91e366848 --- /dev/null +++ "b/11538_hi3861_home_server/code/\344\273\243\347\240\201\347\232\204\344\270\273\350\246\201\351\200\273\350\276\221/\351\251\261\345\212\250\344\273\243\347\240\201/bsp_mqtt_1.c" @@ -0,0 +1,272 @@ +/** + **************************************************************************************************** + * @file bsp_mqtt.c + * @author 普中科技 + * @version V1.0 + * @date 2024-06-05 + * @brief WIFI MQTT实验 + * @license Copyright (c) 2024-2034, 深圳市普中科技有限公司 + **************************************************************************************************** + * @attention + * + * 实验平台:普中-Hi3861 + * 在线视频:https://space.bilibili.com/2146492485 + * 公司网址:www.prechin.cn + * 购买地址: + * + */ + +#include +#include +#include +#include +#include "lwip/netifapi.h" +#include "lwip/sockets.h" +#include "wifi_device.h" +#include "ohos_init.h" +#include "MQTTPacket.h" +#include "bsp_mqtt.h" + +#define MQTT_BUFF_MAX_SIZE 512 + +int g_tcp_socket_fd = 0; // 网络套接字 +unsigned char mqttBuff[MQTT_BUFF_MAX_SIZE] = {0}; + +// 发送网络数据 +static int transport_sendPacketBuffer(unsigned char *buf, int buflen) +{ + int rc = send(g_tcp_socket_fd, buf, buflen, 0); + + return (rc <= 0) ? 0 : 1; +} +// 接收网络数据 +static int transport_getdata(unsigned char *buf, int count) +{ + int rc = recv(g_tcp_socket_fd, buf, count, 0); + return rc; +} + +// 连接服务器 +int MQTTClient_connectServer(const char *ip_addr, int ip_port) +{ + if (ip_addr == NULL) { + return -1; + } + + int res = 0; // 函数返回值 + struct sockaddr_in tcpServerConfig; // tcp服务器信息 + + // 创建TCP套接字 + g_tcp_socket_fd = socket(AF_INET, SOCK_STREAM, 0); + if (g_tcp_socket_fd < 0) { + printf("Failed to create Socket\r\n"); + } + + // 连接TCP服务器 + tcpServerConfig.sin_family = AF_INET; // IPV4 + tcpServerConfig.sin_port = htons(ip_port); // 填写服务器的IP端口号 + tcpServerConfig.sin_addr.s_addr = inet_addr(ip_addr); // 填写服务器的IP地址 + + res = connect(g_tcp_socket_fd, (struct sockaddr *)&tcpServerConfig, sizeof(tcpServerConfig)); // 连接服务器 + if (res == -1) { + printf("Failed to connect to the server\r\n"); + return -1; + } + printf("Connection to server successful\r\n"); + + return 0; +} + +// 断开TCP服务器 0:成功, -1:失败 +int MQTTClient_unConnectServer(void) +{ + int ret = 0; + printf("Server shut down successfully\r\n"); + ret = close(g_tcp_socket_fd); + g_tcp_socket_fd = 0; + return ret; +} + +// mqtt客户端 订阅主题 +int MQTTClient_subscribe(char *subTopic) +{ + if (subTopic == NULL) { + printf("Incorrect parameters\r\n"); + return -1; + } + + int len = 0, res = 0; + int subcount = 0, granted_qos = 0, req_qos = 0; + unsigned short submsgid = 0; + MQTTString topicString = MQTTString_initializer; + + /* subscribe */ + topicString.cstring = subTopic; + len = MQTTSerialize_subscribe(mqttBuff, sizeof(mqttBuff), 0, 1, 1, &topicString, &req_qos); + if (len <= 0) { + printf("MQTTSerialize_subscribe Error %d\r\n", len); + return -1; + } + res = transport_sendPacketBuffer(mqttBuff, len); + if (res != 1) { + printf("transport_sendPacketBuffer Error %d\r\n", res); + return -1; + } + + sleep(1); + memset_s(mqttBuff, sizeof(mqttBuff), 0, sizeof(mqttBuff)); + + /* wait for suback */ + if (MQTTPacket_read(mqttBuff, sizeof(mqttBuff), transport_getdata) != SUBACK) { + printf("MQTTPacket_read Error\r\n"); + return -1; + } + + if (MQTTDeserialize_suback(&submsgid, 1, &subcount, &granted_qos, mqttBuff, sizeof(mqttBuff)) != 1) { + printf("MQTTDeserialize_suback Error\r\n"); + return -1; + } + + printf("MQTT subscribed to topics successfully\r\n"); + + return 0; +} + +// 保持在线时长 60s +#define MQTT_KEEP_ALIVE 60 +#define MQTT_DELAY_TIME 3 + +// mqtt客户端 初始化 +int MQTTClient_init(char *clientID, char *userName, char *password) +{ + if (clientID == NULL || userName == NULL || password == NULL) { + printf("Incorrect parameters\r\n"); + return -1; + } + + int res = 0, len = 0, i = 0; + int mqtt_read_len = 10; + + unsigned char sessionPresent = 0, connack_rc = 0; + MQTTPacket_connectData mqttData = MQTTPacket_connectData_initializer; + + // 初始化MQTT客户端 + mqttData.clientID.cstring = clientID; + mqttData.username.cstring = userName; + mqttData.password.cstring = password; + mqttData.cleansession = true; // 是否初始化的时候,清除上一次的对话 + mqttData.keepAliveInterval = MQTT_KEEP_ALIVE; + + // 组MQTT消息包 + len = MQTTSerialize_connect(mqttBuff, sizeof(mqttBuff), &mqttData); + if (len <= 0) { + printf("MQTTSerialize_connect Error %d\r\n", res); + return -1; + } + res = transport_sendPacketBuffer(mqttBuff, len); + if (res != 1) { + printf("transport_sendPacketBuffer Error %d\r\n", res); + return -1; + } + + sleep(MQTT_DELAY_TIME); + + /* 打印发送出去的数据帧,调试用 */ + printf("MQTT_sendPacket: \r\n"); + for (i = 0; i < len; i++) { + printf("%x ", mqttBuff[i]); + } + printf("\r\n"); + + memset_s(mqttBuff, sizeof(mqttBuff), 0, sizeof(mqttBuff)); + + /* wait for connack */ + if (MQTTPacket_read(mqttBuff, sizeof(mqttBuff), transport_getdata) != CONNACK) { + printf("MQTTPacket_read != CONNACK\r\n"); + } + + printf("MQTT_recvPacket: \r\n"); + /* 打印服务器返回的消息,调试用 */ + for (i = 0; i < mqtt_read_len; i++) { + printf("%x ", mqttBuff[i]); + } + printf("\r\n"); + + if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, mqttBuff, sizeof(mqttBuff)) != 1 || connack_rc != 0) { + printf("Unable to connect, return code %d\r\n", connack_rc); + memset_s(mqttBuff, sizeof(mqttBuff), 0, sizeof(mqttBuff)); + return -1; + } else { + printf("MQTT initialized successfully\r\n"); + } + memset_s(mqttBuff, sizeof(mqttBuff), 0, sizeof(mqttBuff)); + return 0; +} + +#define MQTT_PUB_DATA_TIME (100 * 1000) + +int MQTTClient_pub(char *pub_Topic, unsigned char *payloadData, int payloadLen) +{ + if (payloadData == NULL) { + printf("Incorrect parameters\r\n"); + return -1; + } + + printf("pubTopic: %s\n", pub_Topic); + printf("pubData: %s\n", payloadData); + + int ret = 0, len = 0; + unsigned short retry_count = 5; // 重发次数 + unsigned char sendBuff[MQTT_BUFF_MAX_SIZE] = {0}; + MQTTString topicString = MQTTString_initializer; + + topicString.cstring = pub_Topic; + len = MQTTSerialize_publish(sendBuff, sizeof(sendBuff), 0, 0, 0, 0, topicString, + payloadData, + payloadLen); + while (--retry_count > 0) { + ret = transport_sendPacketBuffer(sendBuff, len); + if (ret == 1) { + break; + } + + printf("Send MQTT_Data Fail\r\n"); + usleep(MQTT_PUB_DATA_TIME); + } + + if (!retry_count && ret != 1) { + printf("transport_sendPacketBuffer Error %d\r\n", ret); + return -1; + } + + // printf("send==>%s", payloadData); + return 0; +} +unsigned char mqtt_topic[200]; +int8_t (*p_MQTTClient_sub_callback)(unsigned char *topic, unsigned char *payload); + +int MQTTClient_sub(void) +{ + int qos, payloadlen_in; + unsigned char dup, retained; + unsigned short msgid; + unsigned char *payload_in; + MQTTString receivedTopic; + + memset_s(mqttBuff, sizeof(mqttBuff), 0, sizeof(mqttBuff)); + // $oc/devices/63ad5a6cc4efcc747bd75973_lamp/sys/commands/request_id=42c20ffb-0885-4f6e-97b5-45d8f613efaf + if (MQTTPacket_read(mqttBuff, sizeof(mqttBuff), transport_getdata) == PUBLISH) { + MQTTDeserialize_publish(&dup, &qos, &retained, &msgid, &receivedTopic, + &payload_in, &payloadlen_in, mqttBuff, sizeof(mqttBuff)); + + printf("data: %s\n", receivedTopic.lenstring.data); + printf("length: %d\n", strlen(receivedTopic.lenstring.data) - payloadlen_in); + printf("payload_length: %d\n", payloadlen_in); + memcpy_s(mqtt_topic, sizeof(mqtt_topic), + receivedTopic.lenstring.data, strlen(receivedTopic.lenstring.data) - payloadlen_in); + printf("topic: %s\n", mqtt_topic); + printf("payload: %s\n", payload_in); + + p_MQTTClient_sub_callback(mqtt_topic, payload_in); + } +}