版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
项目1初识人工智能与智能家居项目1初识人工智能与智能家居教学目标教学目标本章主要介绍人工智能与智能家居的概念、特点、发展等,以及人工智能在智能家居中的应用。【知识目标】【知识目标】【能力目标】了解人工智能概念、特点、常用工具和发展历程【能力目标】了解智能家居概念、智能家居常用技术熟悉智能家居的常见架构、发展趋势掌握人工智能在智能家居中的应用能够使用人工智能工具能够完成智能家居主要硬件的选型能够设计智能家居的系统架构图【素质目标】【素质目标】培养学生的团队协助、团队互助等意识培养学生自我学习的习惯和爱好培养学生依法规范自己行为的意识和习惯培养学生的创新意识和科学精神.5.1设备选型与准备在设备选型与准备阶段,对于基于NB-IoT的智能浇花系统,我们需要考虑多个方面,包括执行设备的选择、传感器的类型、通信模块、控制器以及电源供应等。以下是设备选型与准备方案:1.控制器控制器是智能化、自动化控制系统中的核心部件,对系统的工作状态进行监控、调节和控制,以确保系统能够按照预定的目标和规律运行。在基于NB-IoT的智能浇花系统场景下,需选择具有强大处理能力和低功耗特性的控制器,比如采用STM32F103系列处理器。STM32F103控制器具备数据采集、处理、决策和通信等功能,能够接收传感器数据,根据预设逻辑控制水泵等执行机构,并通过通信模块将数据上传至云端或手机APP。2.土壤湿度传感器土壤湿度传感器用于检测土壤湿度,是判断是否需要浇水的关键依据,应选择精度高、响应速度快、防水防腐的传感器。土壤传感器做土壤湿度的检测,表面采用镀镍处理,有加宽的感应面积,可以提高导电性能,防止接触土壤容易生锈的问题,延长使用寿命。4线制土壤湿度传感器模块可以宽范围控制土壤的湿度,通过电位器调节控制相应阀值,湿度低于设定值时,DO引脚输出高电平,高于设定值时,DO输出低电平;AO引脚可以和AD模块相连,通过AD转换,可以获得土壤湿度更精确的数值。4线制土壤湿度传感器模块接线如图3-46所示。图3-464线制土壤湿度传感器模块接线图3.执行机构(1)水泵水泵用于为植物提供水源。可以根据植物种类和花盆大小选择合适的水泵型号和功率。常见的低功率水泵如图3-46所示。图3-46低功率静音水泵(2)电磁继电器电磁继电器用于控制水泵开关,与水泵配合使用实现自动浇水。常见的8脚AC220V电磁继电器如图3-47所示。图3-478脚AC220V电磁继电器4.通信模块NB-IoT模块选用移远通信技术有限公司的BC260Y核心板,适用于远距离、低功耗的无线通信场景,适合远程浇花系统。BC260Y核心板接口如图3-48所示,BC260Y核心板引脚功能如表3-10所示。BC260Y核心板提供丰富的外部接口和协议栈,同时可支持中国移动OneNET平台、中国移动Andlink平台、中国电信AEP平台和中国电信IoT平台等物联网云平台。图3-48BC260Y核心板接口表3-10BC260Y核心板引脚功能引脚序号引脚定义描述1VIN外部供电引脚电压:DC4.5V-6V电流:0.5A2GND电源地3RST复位引脚,拉高有效,不用则悬空4ENT模块睡眠唤醒引脚,拉高唤醒,不用则悬空5RX主串口收引脚,3.3V电平6TX主串口发引脚,3.3V电平7GND电源地8BAT电池供电引脚。电压:3.4V-4.2V不可与VIN同时供电,用此引脚供电EN不可用。5.电源供应(1)电源适配器电源适配器可以为控制器、传感器等提供稳定的电源供应。(2)太阳能电池板加蓄电池这种电源搭配适用于户外或无法接入市电的场景,提供绿色、可持续的电源解决方案。3.5.2NB-IoT网络接入将智能浇花设备连接到NB-IoT网络,可通过运营商提供的NB-IoT物联网卡实现。NB-IoT设备接入OneNET平台是一个涉及多个步骤的过程,主要包括注册与配置OneNET平台、连接NB-IoT设备以及上传数据等。以下是接入流程:1.访问登录OneNET平台访问OneNET平台官网(),进行账号登录。2.创建产品登录OneNET平台后,进入开发者中心,依次选择“全部产品服务”->“物联网开放平台”->“产品开发”->“创建产品”。在创建产品窗口中填写产品信息,包括产品名称、接入协议(建议选择LwM2M协议,因为NB-IoT设备需通过NB基站接入平台)、数据协议(如OneJson,以便使用物模型)等。选择NB-IoT作为联网方式,并设置其他相关参数,如数据协议、开发方案等。点击“确定”完成产品创建,并记录产品的用户ID和相关信息。创建产品相关信息如图3-49所示。图3-49创建产品相关信息填写3.设置物模型在产品创建成功后,点击“产品开发”,如图3-50所示。在“功能定义”中点击“设置物模型”,如图3-51所示;根据实际需求创建物模型,包括添加自定义功能节点、设置数据属性等,这里首先添加名为“湿度”的自定义功能点,相关参数如图3-52所示。然后添加名为“远程开关”的自定义功能点,相关参数如图3-53所示。完成后点击“保存”,将物模型保存到平台中。图3-50点击“产品开发”图3-51点击“设置物模型”图3-52添加“湿度”功能图3-53添加“远程开关”功能4.添加设备在产品页面依次选择“设备接入管理”->“设备管理”->“添加设备”,如图3-54所示。图3-54在设备管理页面中点击“添加设备”在“添加设备”页面中选择已创建的产品,并输入设备名称。然后利用USB转TTL模块将NB-IoT模块与电脑连接,并打开串口调试助手,通过发送AT指令(如AT+CGSN=1获取IMEI,AT+CIMI获取IMSI)到NB-IoT模块,获取设备的IMEI和IMSI信息,如图3-55所示。图3-55通过发送AT指令获取设备的IMEI和IMSI信息将获取的IMEI和IMSI信息填写到设备添加页面,并点击“确定”,如图3-56所示。设备即被添加到平台中,并显示设备ID和PSK码等信息。图3-56将获取的IMEI和IMSI信息填入并点击“确定”5.连接NB-IoT设备(1)模块初始化通过发送AT指令(如AT+CEREG?查询网络注册状态,AT+CGATT?查询PS附着状态等)查询模块的网络状态、信号强度等信息。如果模块未连接到网络或信号不佳,需要进行相应的配置或调整。不同的NB模块命令可能会有所不同,具体命令参考模组厂商的资料。BC260Y模块初始化指令如下:ATAT//确认模块能正常响应AT命令OKAT+CGMR//查询模块固件版本号+CGMR:N306_C1-E05-STD-BZ-001OKAT+CPIN?//确认模块能识别到SIM卡+CPIN:READYOKAT+CSQ//确认信号良好12<CSQ<31+CSQ:31,99OKAT+ECPMUCFG=1,1//主动关闭低功耗模式OKAT+CGATT?//查询网络附着情况+CGATT:1OKAT+CEREG?//查询网络注册情况+CEREG:0,1OKAT+CGPADDR//查询PDP是否激活成功+CGPADDR:0,“9”OKAT+ECPMUCFG=1,1AT+ECPMUCFG=1,1//主动关闭低功耗模式OKAT+QSCLK=0//禁用休眠模式OKAT+CGATT?//查询网络附着情况+CGATT:1OKAT+CEREG?//查询网络注册情况+CEREG:0,1OKAT+CGPADDR//查询PDP是否激活成功+CGPADDR:0,“9”OK图3-56发送AT指令完成模块初始化(2)创建与OneNET的连接发送AT指令(如AT+MIPLCREATE)创建与OneNET的基础通信套件,AT+MIPLCREATE指令说明如表3-11所示。表3-11AT+MIPLCREATE指令AT+MIPLCREATE创建OneNET通信套件实例执行命令:AT+MIPLCREATE响应:+MIPLCREATE:<ref>OK若出现任何错误:ERROR或+CISERROR:<err>参数说明<ref>OneNET通信套件的实例ID。范围:0~65535。当前仅支持0。发送AT指令(如AT+MIPLADDOBJ=0,3304,1,“1”,2,3)添加对象实例(其中参数根据实际情况调整),AT+MIPLADDOBJ指令说明如表3-12所示。AT+MIPLADDOBJ添加LwM2M对象测试命令:AT+MIPLADDOBJ=?响应:+MIPLADDOBJ:(支持的<ref>范围),(支持的<objId>范围),(支持的<insCount>范围),<insBitmap>,(支持的<attrCount>范围),(支持的<actCount>范围)OK设置命令:AT+MIPLADDOBJ=<ref>,<objId>,<insCount>,<insBitmap>,<attrCount>,<actCount>响应:OK若出现任何错误:ERROR或+CISERROR:<err>参数说明<ref>OneNET通信套件的实例ID。范围:0~65535。当前仅支持0。<objId>整型。LwM2M对象ID。若不存在,则返回错误。范围:0~65535(0~0xFFFF)。<insCount>整型。实例个数。范围:0~65535(0~0xFFFF)。<insBitmap>带双引号的字符串型。实例位图。例如,若共有4个实例(<insCount>=4),ID分别为0、1、2、3,<insBitmap>="1101"表示第1、2、4位ID(即ID0、1、3)<attrCount>(0~0xFFFF)整型。属性个数,表示可读和/或可写资源的个数。范围:0~65535(0~0xFFFF)。<actCount>整型。动作个数,表示可执行的资源个数。范围:0~65535(0~0xFFFF)。表3-12AT+MIPLADDOBJ指令发送AT指令(如AT+MIPLOPEN=0,3600)向OneNET发送注册请求,并设置注册周期(如3600秒),AT+MIPLOPEN指令说明如表3-13所示。表3-13AT+MIPLOPEN指令AT+MIPLOPEN发送注册请求测试命令:AT+MIPLOPEN=?响应:+MIPLOPEN:(支持的<ref>范围),(支持的<lifetime>范围),(支持的<timeout>范围)OK设置命令:AT+MIPLOPEN=<ref>,<lifetime>[,<timeout>]响应:OK若出现任何错误:ERROR或+CISERROR:<err>参数说明<ref>OneNET通信套件的实例ID。范围:0~65535。当前仅支持0。<lifetime>整型。用于设置设备的生命周期,实际生命周期为<lifetime>×0.9。范围:15~268435455,若设置为0,则表示3600秒;单位:秒。<timeout>整型。注册请求的超时时间。范围:1~65535;单位:秒。默认值:30。在串口调试助手中发送以上指令,等待OneNET平台的注册成功响应,通常会有相应的AT指令返回结果,如图3-57所示。图3-57发送AT指令返回结果通过以上配置,NB-IoT设备成功接入OneNET平台,打开OneNET平台查看设备状态为在线,如图3-58所示。图3-58打开OneNET平台查看设备状态为在线3.5.3远程浇花控制指令设计1.STM32F103初始化(1)定时器初始化新建timer.c文件,将其保存并添加到HARDWARE\TIMER目录下,新建timer.h文件并保存到HARDWARE\TIMER目录中,并在工程配置C/C++的头文件路径中添加“..\HARDWARE\TIMER”路径。在timer.c文件中添加如下代码:#include"timer.h"#include"timer.h"#include"led.h"#include"usart.h"#include"stm32f10x_tim.h"#include"bc260y.h"unsignedcharTimeout;unsignedcharrestflag;externBC260YBC260Y_Status; //通用定时器3中断初始化。arr:自动重装值。psc:时钟预分频数。voidTIM3_Int_Init(u16arr,u16psc){TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure; NVIC_InitTypeDefNVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//时钟使能//设置在下一个更新事件装入活动的自动重装载寄存器周期的。计数到5000为500ms。 TIM_TimeBaseStructure.TIM_Period=arr; TIM_TimeBaseStructure.TIM_Prescaler=psc;//设置用来作为TIMx时钟频率除数的预分频值10Khz的计数频率 TIM_TimeBaseStructure.TIM_ClockDivision=0;//设置时钟分割:TDTS=Tck_tim TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//TIM向上计数模式 TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);//根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//使能指定的TIM3中断,允许更新中断 NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;//TIM3中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//先占优先级0级 NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;//从优先级3级 NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//IRQ通道被使能 NVIC_Init(&NVIC_InitStructure);//根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 TIM_Cmd(TIM3,DISABLE);//不使能TIMx外设 }NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;//TIM3中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//先占优先级0级 NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;//从优先级3级 NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;//TIM3中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//先占优先级0级 NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;//从优先级3级 NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//IRQ通道被使能 NVIC_Init(&NVIC_InitStructure);//根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 TIM_Cmd(TIM3,DISABLE);//不使能TIMx外设 }//定时器3中断服务程序voidTIM3_IRQHandler(void)//TIM3中断{//检查指定的TIM中断发生与否:TIM中断源 if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET) {//清除TIMx的中断待处理位:TIM中断源 TIM_ClearITPendingBit(TIM3,TIM_IT_Update); Timeout++; if(Timeout>=30)//300ms内没有数据,表明模块休眠了。 { Timeout=0;restflag=1;//复位标志将模块复位 TIM_Cmd(TIM3,DISABLE);//不使能TIMx外设 } }}#ifndef__TIMER_H#define__TIMER_H#ifndef__TIMER_H#define__TIMER_H#include"sys.h"voidTIM3_Int_Init(u16arr,u16psc);#endif新建usart.c文件,将其保存并添加到\SYSTEM\usart目录下,新建usart.h文件并保存到\SYSTEM\usart目录中,并在工程配置C/C++的头文件路径中添加“..\SYSTEM\usart”路径。在usart.c文件中添加如下代码:#include"sys.h"#include"sys.h"#include"usart.h" #include"stdio.h"#include"string.h"#include"stm32f10x_tim.h"unsignedcharuart1_getok;//加入以下代码,支持printf函数,而不需要选择useMicroLIB #if1#pragmaimport(__use_no_semihosting)//标准库需要的支持函数struct__FILE{ inthandle;};FILE__stdout;//定义_sys_exit()以避免使用半主机模式void_sys_exit(intx){ x=x;}//重定义fputc函数intfputc(intch,FILE*f){ while((USART2->SR&0X40)==0){}//循环发送,直到发送完毕USART2->DR=(u8)ch; returnch;}#endifvoidUART1_send_byte(chardata){ while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); USART_SendData(USART1,data);}voidUART2_send_byte(chardata){ while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET); USART_SendData(USART2,data);}//串口1中断服务程序//注意,读取USARTx->SR能避免莫名其妙的错误 charRxCounter,RxBuffer[100];//接收缓冲,最大USART_REC_LEN个字节.charRxCounter1,RxBuffer1[100];//接收缓冲,最大USART_REC_LEN个字节.//接收状态//bit15, 接收完成标志//bit14, 接收到0x0d//bit13~0, 接收到的有效字节数目u16USART_RX_STA=0;//接收状态标记 externu8Timeout; inthandle;};FILE__stdout;//定义_sys_exit()以避免使用半主机模式void_sys_exit(intx){ x=x;}//重定义fputc函数intfputc(intch,FILE*f){ while((USART2->SR&0X40)==0){}//循环发送,直到发送完毕USART2->DR=(u8)ch; returnch;}#endif//串口2发送函数voidUART2_send_byte(chardata){ while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET); USART_SendData(USART2,data);} charRxCounter,RxBuffer[100];//接收缓冲,最大USART_REC_LEN个字节.charRxCounter1,RxBuffer1[100];//接收缓冲,最大USART_REC_LEN个字节.//接收状态。bit15:接收完成标志;bit14:接收到0x0d;bit13~0:接收到的有效字节数目u16USART_RX_STA=0;//接收状态标记 externu8Timeout;//初始化串口2IO口,bound:波特率。voiduart2_init(u32bound){//GPIO端口设置GPIO_InitTypeDefGPIO_InitStructure; USART_InitTypeDefUSART_InitStructure; NVIC_InitTypeDefNVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIOA时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//USART2 USART_DeInit(USART2);//复位串口2GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;//USART2_TXPA.2GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//通信速率50MHzGPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //复用推挽输出GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化PA2GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3;//USART2_RX PA.3GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化PA3//Usart2NVIC配置NVIC_InitStructure.NVIC_IRQChannel=USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//抢占优先级0 NVIC_InitStructure.NVIC_IRQChannelSubPriority=1; //子优先级3 NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; //IRQ通道使能 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器//USART初始化设置 USART_InitStructure.USART_BaudRate=bound;//115200 USART_InitStructure.USART_WordLength=USART_WordLength_8b;//字长为8位 USART_InitStructure.USART_StopBits=USART_StopBits_1;//一个停止位 USART_InitStructure.USART_Parity=USART_Parity_No;//无奇偶校验位 USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//无硬件数据流控制 USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx; //收发模式USART_Init(USART2,&USART_InitStructure);//初始化串口 USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);//开启中断USART_Cmd(USART2,ENABLE);//使能串口}在usart.h文件中声明串口相关函数,代码如下: USART_InitStructure.USART_Parity=USART_Parity_No;//无奇偶校验位 USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//无硬件数据流控制 USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx; //收发模式USART_Init(USART2,&USART_InitStructure);//初始化串口USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);//开启中断USART_Cmd(USART2,ENABLE);//使能串口}//串口2发送函数voidUart2_SendDATA(u8*data,u8len){ u8i; for(i=0;i<len;i++) { while((USART2->SR&0X40)==0){}//等待发送完成USART2->DR=(u8)data[i]; }}//串口2中断服务程序voidUSART2_IRQHandler(void){charRes;//接收模块返回的数据if(USART_GetITStatus(USART2,USART_IT_RXNE)!=RESET){Res=USART_ReceiveData(USART2);//接收模块的数据;RxBuffer[RxCounter++]=USART_ReceiveData(USART2);//接收模块的数据if(RxCounter>99)//长度自行设定RxCounter=0;}}#ifndef__USART_H#define__USART_H#ifndef__USART_H#define__USART_H#include"stdio.h" #include"sys.h" voiduart_init(u32bound);voiduart2_init(u32bound);voiduart3_init(u32bound);voidUART1_send_byte(chardata);voidUART2_send_byte(chardata);voidUart1_SendStr(char*SendBuf);voidUart3_SendStr(char*SendBuf);voidUart2_SendDATA(u8*data,u8len);#endif新建sys.c文件,将其保存并添加到\SYSTEM\sys目录下,新建sys.h文件并保存到\SYSTEM\sys目录中,并在工程配置C/C++的头文件路径中添加“..\SYSTEM\sys”路径。在sys.c文件中添加如下代码:#include"sys.h"voidNVIC_Configuration(void){//设置NVIC中断分组2:2位抢占优先级,2位响应优先级NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);#include"sys.h"voidNVIC_Configuration(void){//设置NVIC中断分组2:2位抢占优先级,2位响应优先级NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); }#ifndef__SYS_H#ifndef__SYS_H#define__SYS_H #include"stm32f10x.h" //IO口操作宏定义#defineBITBAND(addr,bitnum)((addr&0xF0000000)+0x2000000+((addr&0xFFFFF)<<5)+(bitnum<<2))#defineMEM_ADDR(addr)*((volatileunsignedlong*)(addr))#defineBIT_ADDR(addr,bitnum)MEM_ADDR(BITBAND(addr,bitnum))//IO口地址映射#defineGPIOA_ODR_Addr(GPIOA_BASE+12)//0x4001080C#defineGPIOB_ODR_Addr(GPIOB_BASE+12)//0x40010C0C#defineGPIOC_ODR_Addr(GPIOC_BASE+12)//0x4001100C#defineGPIOD_ODR_Addr(GPIOD_BASE+12)//0x4001140C#defineGPIOE_ODR_Addr(GPIOE_BASE+12)//0x4001180C#defineGPIOF_ODR_Addr(GPIOF_BASE+12)//0x40011A0C#defineGPIOG_ODR_Addr(GPIOG_BASE+12)//0x40011E0C#defineGPIOA_IDR_Addr(GPIOA_BASE+8)//0x40010808#defineGPIOB_IDR_Addr(GPIOB_BASE+8)//0x40010C08#defineGPIOC_IDR_Addr(GPIOC_BASE+8)//0x40011008#defineGPIOD_IDR_Addr(GPIOD_BASE+8)//0x40011408#defineGPIOE_IDR_Addr(GPIOE_BASE+8)//0x40011808#defineGPIOF_IDR_Addr(GPIOF_BASE+8)//0x40011A08#defineGPIOG_IDR_Addr(GPIOG_BASE+8)//0x40011E08//IO口操作,只对单一的IO口!确保n的值小于16!#definePAout(n)BIT_ADDR(GPIOA_ODR_Addr,n)//输出#definePAin(n)BIT_ADDR(GPIOA_IDR_Addr,n)//输入#definePBout(n)BIT_ADDR(GPIOB_ODR_Addr,n)//输出#definePBin(n)BIT_ADDR(GPIOB_IDR_Addr,n)//输入#definePCout(n)BIT_ADDR(GPIOC_ODR_Addr,n)//输出#definePCin(n)BIT_ADDR(GPIOC_IDR_Addr,n)//输入#definePDout(n)BIT_ADDR(GPIOD_ODR_Addr,n)//输出#definePDin(n)BIT_ADDR(GPIOD_IDR_Addr,n)//输入#definePEout(n)BIT_ADDR(GPIOE_ODR_Addr,n)//输出#definePEin(n)BIT_ADDR(GPIOE_IDR_Addr,n)//输入#definePFout(n)BIT_ADDR(GPIOF_ODR_Addr,n)//输出#definePFin(n)BIT_ADDR(GPIOF_IDR_Addr,n)//输入#definePGout(n)BIT_ADDR(GPIOG_ODR_Addr,n)//输出#definePGin(n)BIT_ADDR(GPIOG_IDR_Addr,n)//输入voidNVIC_Configuration(void);#endif(4)延时函数新建delay.c文件,将其保存并添加到\SYSTEM\delay目录下,新建delay.h文件并保存到\SYSTEM\delay目录中,并在工程配置C/C++的头文件路径中添加“..\SYSTEM\delay路径”。在delay.c文件中添加如下代码:在delay.h文件#include"delay.h"#include"sys.h"#include"delay.h"#include"sys.h"staticu8fac_us=0;//us延时倍乘数staticu16fac_ms=0;//ms延时倍乘数//初始化延迟函数,SYSTICK(系统时钟)的时钟固定为HCLK时钟的1/8voiddelay_init() { SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//选择外部时钟HCLK/8 fac_us=SystemCoreClock/8000000; //为系统时钟的1/8 fac_ms=(u16)fac_us*1000;//非ucos下,代表每个ms需要的systick时钟数} //微妙延时函数,nus为要延时的us数. voiddelay_us(u32nus){ u32temp; SysTick->LOAD=nus*fac_us;//时间加载 SysTick->VAL=0x00;//清空计数器 SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;//开始倒数 do { temp=SysTick->CTRL; } while(temp&0x01&&!(temp&(1<<16)));//等待时间到达 SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;//关闭计数器 SysTick->VAL=0X00;//清空计数器 }//毫秒延时函数//因为SysTick->LOAD为24位寄存器,所以,最大延时为:nms<=0xffffff*8*1000/SYSCLK//对72M条件下,nms<=1864voiddelay_ms(u16nms){ u32temp; SysTick->LOAD=(u32)nms*fac_ms;//时间加载(SysTick->LOAD为24bit) SysTick->VAL=0x00;//清空计数器 SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;//开始倒数 do { temp=SysTick->CTRL; } while(temp&0x01&&!(temp&(1<<16)));//等待时间到达 SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;//关闭计数器 SysTick->VAL=0X00;//清空计数器 }2.NB-IoT模块配置新建BC260Y.c文件将其保存到HARDWARE/BC260Y目录下,新建BC260Y.h文件保存到HARDWARE\BC260Y目录中,并在工程配置C/C++的头文件路径中添加“..\HARDWARE\BC260Y”路径。在BC260Y.c文件中添加如下代码:#include"bc260y.h"#include"bc260y.h"#include"string.h"#include"usart.h"#include"led.h"char*strx,*extstrx;externunsignedcharRxBuffer[255],RxCounter;BC260YBC260Y_Status;////OneNET平台参数,在设备管理界面里面都可以查询到#defineProductID"D8w2b9t42M"//产品ID#defineDeviceName"BC260Y"//设备名称#defineDeviceSecret"eFJmUlQ0ajRld2xEYzNZd0pRZG9scldQV1A1TklEUUQ="//设备秘钥#definePubTopic"$sys/D8w2b9t42M/BC260Y/thing/property/post"//发布主题#defineSubTopic"$sys/D8w2b9t42M/BC260Y/thing/property/post/reply"//订阅主题//清缓存函数voidClear_Buffer(void){ u8i; Uart1_SendStr((char*)RxBuffer); for(i=0;i<255;i++) RxBuffer[i]=0;//缓存 RxCounter=0;}//BC260Y模块初始化函数voidBC260Y_Init(void){printf("AT\r\n");delay_ms(300);strx=strstr((constchar*)RxBuffer,(constchar*)"OK");//返回OKClear_Buffer(); while(strx==NULL){Clear_Buffer(); printf("AT\r\n");delay_ms(300);strx=strstr((constchar*)RxBuffer,(constchar*)"OK");//返回OK} printf("AT+QMTDISC=0\r\n"); delay_ms(300);printf("AT+CFUN=1\r\n");//获取卡号,类似是否存在卡的意思,比较重要。delay_ms(300);printf("AT+CIMI\r\n");//获取卡号,类似是否存在卡的意思,比较重要。delay_ms(300);strx=strstr((constchar*)RxBuffer,(constchar*)"460");//返460,表明识别到卡了Clear_Buffer(); while(strx==NULL){Clear_Buffer(); printf("AT+CIMI\r\n");//获取卡号,类似是否存在卡的意思,比较重要。delay_ms(300);strx=strstr((constchar*)RxBuffer,(constchar*)"460");//返回OK,说明卡是存在的}printf("AT+CGATT=1\r\n");//激活网络,PDPdelay_ms(300);strx=strstr((constchar*)RxBuffer,(constchar*)"OK");//返OKClear_Buffer(); printf("AT+CGATT?\r\n");//查询激活状态delay_ms(300);strx=strstr((constchar*)RxBuffer,(constchar*)"+CGATT:1");//返1Clear_Buffer(); while(strx==NULL) {Clear_Buffer(); printf("AT+CGATT?\r\n");//获取激活状态delay_ms(300);strx=strstr((constchar*)RxBuffer,(constchar*)"+CGATT:1");//返回1,表明注网成功 } printf("AT+CSQ\r\n");//查看获取CSQ值delay_ms(300);Clear_Buffer(); }voidBC260Y_ConTCP(void){ printf("AT+QICLOSE=0\r\n");//关闭socekt连接 delay_ms(300);Clear_Buffer();IWDG_Feed();//喂狗}voidBC260Y_CreateTCPSokcet(void)//创建sokcet{printf("AT+QIOPEN=1,0,\"TCP\",\"9\",14269,1234,1\r\n");//创建连接TCP,输入IP以及服务器端口号码,采用直接吐出的方式delay_ms(300);strx=strstr((constchar*)RxBuffer,(constchar*)"+QIOPEN:0,0");//检查是否登陆成功 while(strx==NULL) {strx=strstr((constchar*)RxBuffer,(constchar*)"+QIOPEN:0,0");//检查是否登陆成功delay_ms(100); }Clear_Buffer(); }voidBC260Y_Senddata(uint8_t*len,uint8_t*data)//字符串形式{printf("AT+QSOSEND=0,%s,%s\r\n",len,data);}voidBC260Y_Senddatahex(uint8_t*len,uint8_t*data)//发送十六进制数据{printf("AT+QISENDEX=0,%s,%s\r\n",len,data);delay_ms(300); while(strx==NULL) {strx=strstr((constchar*)RxBuffer,(constchar*)"SENDOK");//检查是否发送成功delay_ms(100); }Clear_Buffer(); }voidBC260Y_RECData(void){}voidMQTT_Init(void){printf("AT+QMTCFG=\"version\",0,1\r\n");//MQTT版本设置为v3.1.1delay_ms(500); printf("AT+QMTOPEN=0,\"\",1883\r\n");//通过TCP方式去连接MQTT服务器delay_ms(500);strx=strstr((constchar*)RxBuffer,(constchar*)"+QMTOPEN:0,0");//看下返回状态while(strx==NULL){strx=strstr((constchar*)RxBuffer,(constchar*)"+QMTOPEN:0,0");//确认返回值正确}Clear_Buffer(); //登录MQTT服务器,设备ID,产品ID,鉴权.用户根据实际需要进行更改。(转义字符\"为打印一个",%%为打印一个%)printf("AT+QMTCONN=0,\"BC260Y\",\"D8w2b9t42M\",\"version=2018-10-31&res=products%%2FD8w2b9t42M%%2Fdevices%%2FBC260Y&et=1785070342&method=md5&sign=BoZpbdZqGGX%%2FCSUqRbdBVw%%3D%%3D\"\r\n"); delay_ms(500);strx=strstr((constchar*)RxBuffer,(constchar*)"+QMTCONN:0,0,0");//看下返回状态while(strx==NULL){strx=strstr((constchar*)RxBuffer,(constchar*)"+QMTCONN:0,0,0");//看下返回状态}Clear_Buffer();}//访问ONENET需要提交JSON数据u8MqttOnenet_Savedata(u8*t_payload,u8temp,u8humi){ charjson[]="{\"id\":\"123\",\"version\":\"1.0\",\"params\":{\"humility\":{\"value\":58.9}}}";chart_json[200];//intpayload_len;unsignedshortjson_len; sprintf(t_json,json,temp,humi);//payload_len=1+2+strlen(t_json)/sizeof(char);json_len=strlen(t_json)/sizeof(char);//typet_payload[0]='\x01';//lengtht_payload[1]=(json_len&0xFF00)>>8;t_payload[2]=json_len&0xFF; //json memcpy(t_payload+3,t_json,json_len);returnjson_len+3;}printf("AT+CIMI\r\n");//获取卡号,类似是否存在卡的意思,比较重要。printf("AT+CIMI\r\n");//获取卡号,类似是否存在卡的意思,比较重要。delay_ms(300);strx=strstr((constchar*)RxBuffer,(constchar*)"460");//返回OK,说明卡是存在的}printf("AT+CGATT=1\r\n");//激活网络,PDPdelay_ms(300);strx=strstr((constchar*)RxBuffer,(constchar*)"OK");//返OKClear_Buffer(); printf("AT+CGATT?\r\n");//查询激活状态delay_ms(300);strx=strstr((constchar*)RxBuffer,(constchar*)"+CGATT:1");//返1Clear_Buffer(); while(strx==NULL) {Clear_Buffer(); printf("AT+CGATT?\r\n");//获取激活状态delay_ms(300);strx=strstr((constchar*)RxBuffer,(constchar*)"+CGATT:1");//返回1,注网成功} printf("AT+CSQ\r\n");//查看获取CSQ值delay_ms(300);Clear_Buffer(); }//关闭socekt连接函数voidBC260Y_ConTCP(void){ printf("AT+QICLOSE=0\r\n");//关闭socekt连接 delay_ms(300);Clear_Buffer();}//字符串发送函数voidBC260Y_Senddata(uint8_t*len,uint8_t*data)//字符串形式{printf("AT+QSOSEND=0,%s,%s\r\n",len,data);}//十六进制发送函数voidBC260Y_Senddatahex(uint8_t*len,uint8_t*data)//发送十六进制数据{printf("AT+QISENDEX=0,%s,%s\r\n",len,data);delay_ms(300); while(strx==NULL) {strx=strstr((constchar*)RxBuffer,(constchar*)"SENDOK");//检查是否发送成功delay_ms(100);}Clear_Buffer(); }//MQTT初始化函数voidMQTT_Init(void){printf("AT+QMTCFG=\"version\",0,1\r\n");//MQTT版本设置为v3.1.1delay_ms(500);printf("AT+QMTOPEN=0,\"\",1883\r\n");//通过TCP方式去连接MQTT服务器delay_ms(500);strx=strstr((constchar*)RxBuffer,(constchar*)"+QMTOPEN:0,0");//看下返回状态while(strx==NULL){strx=strstr((constchar*)RxBuffer,(constchar*)"+QMTOPEN:0,0");//确认返回值正确}Clear_Buffer(); //登录MQTT服务器,设备ID,产品ID,鉴权.用户根据实际需要进行更改。(转义字符\"为打印一个",%%为打印一个%)printf("AT+QMTCONN=0,\"BC260Y\",\"D8w2b9t42M\",\"version=2018-10-31&res=products%%2FD8w2b9t42M%%2Fdevices%%2FBC260Y&et=1785070342&method=md5&sign=BoZpbdZqGGX%%2FCSUqRbdBVw%%3D%%3D\"\r\n"); delay_ms(500);strx=strstr((constchar*)RxBuffer,(constchar*)"+QMTCONN:0,0,0");//看下返回状态while(strx==NULL){strx=strstr((constchar*)RxBuffer,(constchar*)"+QMTCONN:0,0,0");//看下返回状态}Clear_Buffer();}//访问ONENET需要提交JSON数据u8MqttOnenet_Savedata(u8*t_payload,u8temp,u8humi){ charjson[]="{\"id\":\"123\",\"version\":\"1.0\",\"params\":{\"humility\":{\"value\":58.9}}}";chart_json[200];//intpayload_len;unsignedshortjson_len; sprintf(t_json,json,temp,humi);//payload_len=1+2+strlen(t_json)/sizeof(char);json_len=strlen(t_json)/sizeof(char);//typet_payload[0]='\x01';//lengtht_payload[1]=(json_len&0xFF00)>>8;t_payload[2]=json_len&0xFF; //json memcpy(t_payload+3,t_json,json_len);returnjson_len+3;}在BC260Y.h文件中while(strx==NULL){while(strx==NULL){strx=strstr((constchar*)RxBuffer,(constchar*)"+QMTOPEN:0,0");//确认返回值正确}Clear_Buffer();//登录MQTT服务器,设备ID,产品ID,鉴权.用户根据实际需要进行更改。(转义字符\"为打印一个",%%为打印一个%)printf("AT+QMTCONN=0,\"BC260Y\",\"D8w2b9t42M\",\"version=2018-10-31&res=products%%2FD8w2b9t42M%%2Fdevices%%2FBC260Y&et=1785070342&method=md5&sign=BoZpbdZqGGX%%2FCSUqRbdBVw%%3D%%3D\"\r\n"); delay_ms(500);strx=strstr((constchar*)RxBuffer,(constchar*)"+QMTCONN:0,0,0");//看下返回状态while(strx==NULL){strx=strstr((constchar*)RxBuffer,(constchar*)"+QMTCONN:0,0,0");//看下返回状态}Clear_Buffer();}//访问ONENET需要提交JSON数据u8MqttOnenet_Savedata(u8*t_payload,u8temp,u8humi){charjson[]="{\"id\":\"123\",\"version\":\"1.0\",\"params\":{\"humility\":{\"value\":58.9}}}";chart_json[200];//intpayload_len;unsignedshortjson_len; sprintf(t_json,json,temp,humi);//payload_len=1+2+strlen(t_json)/sizeof(char);json_len=strlen(t_json)/sizeof(char);//typet_payload[0]='\x01';//lengtht_payload[1]=(json_len&0xFF00)>>8;t_payload[2]=json_len&0xFF; //json memcpy(t_payload+3,t_json,json_len);returnjson_len+3;}#ifndef__BC260Y_H#ifndef__BC260Y_H#define__BC260Y_H #include"usart.h"#include<stm32f10x.h>#include"delay.h"voidClear_Buffer(void);//清空缓存 voidBC260Y_Init(void);voidBC260Y_PDPACT(void);voidBC260Y_ConTCP(void);voidBC260Y_CreateTCPSokcet(void);voidBC260Y_RECData(void);voidBC260Y_Senddata(uint8_t*len,uint8_t*data);voidBC260Y_Senddatahex(uint8_t*len,uint8_t*data);voidClear_Buffer(void);voidBC260Y_ChecekConStatus(void);voidBC260Y_ChecekConStatus(void);voidMQTT_Init(void);u8Mqttaliyun_Savedata(u8*t_payload,u8temp,u8humi);u8MqttOnenet_Savedata(u8*t_payload,u8temp,u8humi);voidBC260Y_ChecekConStatus(void);voidMQTT_Init(void);u8Mqttaliyun_Savedata(u8*t_payload,u8temp,u8humi);u8MqttOnenet_Savedata(u8*t_payload,u8temp,u8humi);typedefstruct{uint8_tCSQ;uint8_tSocketnum;//编号uint8_treclen;//获取到数据的长度uint8_tres;uint8_trecdatalen[10];uint8_trecdata[100];uint8_tnetstatus;//网络指示灯}BC260Y;#endif新建dht11.c文件将其保存到HARDWARE\DHT11目录下,新建dht11.h文件保存到HARDWARE\DHT11目录中,并在工程配置C/C++的头文件路径中添加“..\HARDWARE\DHT11”路径。在dht11.c文件中添加如下代码:#include"dht11.h"#include"dht11.h"#include"delay.h"//复位DHT11voidDHT11_Rst(void) { DHT11_IO_OUT(); //SETOUTPUTDHT11_DQ_OUT=0; //拉低DQdelay_ms(20); //拉低至少18msDHT11_DQ_OUT=1; //DQ=1 delay_us(30); //主机拉高20~40us}//等待DHT11的回应,返回1:未检测到DHT11的存在,返回0:存在u8DHT11_Check(void) { u8retry=0; DHT11_IO_IN();//SETINPUT while(DHT11_DQ_IN&&retry<100)//DHT11会拉低40~80us { retry++; delay_us(1); }; if(retry>=100)return1; elseretry=0;while(!DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高40~80us { retry++; delay_us(1); }; if(retry>=100)return1; return0;}//从DHT11读取一个位//返回值:1/0u8DHT11_Read_Bit(void) { u8retry=0; while(DHT11_DQ_IN&&retry<100)//等待变为低电平 { retry++; delay_us(1); } retry=0; while(!DHT11_DQ_IN&&retry<100)//等待变高电平 { retry++; delay_us(1); } delay_us(40);//等待40us if(DHT11_DQ_IN)return1; elsereturn0; }//从DHT11读取一个字节//返回值:读到的数据u8DHT11_Read_Byte(void){u8i,dat;dat=0; for(i=0;i<8;i++) { dat<<=1; dat|=DHT11_Read_Bit();} returndat;}//从DHT11读取一次数据//temp:温度值(范围:0~50°)//humi:湿度值(范围:20%~90%)//返回值:0,正常;1,读取失败u8DHT11_Read_Data(u8*temp,u8*humi){ u8buf[5]; u8i; DHT11_Rst(); 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]; } }elsereturn1; return0; }//初始化DHT11的IO口DQ同时检测DHT11的存在//返回1:不存在//返回0:存在 u8DHT11_Init(void){ RCC->APB2ENR|=1<<3;//使能PORTB口时钟 GPIOB->CRL&=0X0FFFFFFF;//PORTB1推挽输出 GPIOB->CRL|=0X00000030; DHT11_Rst(); returnDHT11_Check();}//从DHT11读取一个位//从DHT11读取一个位,返回值:1/0u8DHT11_Read_Bit(void) { u8retry=0; while(DHT11_DQ_IN&&retry<100)//等待变为低电平 { retry++; delay_us(1); } retry=0; while(!DHT11_DQ_IN&&retry<100)//等待变高电平 { retry++; delay_us(1); } delay_us(40);/
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 智能网联汽车电池管理协同系统研发项目可行性研究报告
- 喷射器项目可行性研究报告
- 农村服装半价活动方案策划(3篇)
- 企业营销思维调整方案(3篇)
- 八一舞蹈活动策划方案模板(3篇)
- 海南省三亚市重点学校高一入学数学分班考试试题及答案
- 贵州省安顺市重点学校高一英语分班考试试题及答案
- 2026年青海小升初(语文)真题考试试题及答案
- 2026年四川小升初(数学)考试真题(含答案)
- 三年级上册语文必背课文内容闯关表
- 2026江苏连云港市金融控股集团有限公司招聘17人笔试备考题库及答案详解
- 2026四川雅安市雨城区考试招募医疗卫生辅助岗位人员13人笔试模拟试题及答案详解
- 2026-2030中国戏曲音乐文化行业运行态势及前景动态预测报告
- 初中数学尺规作图全解|五种基本作图与综合应用
- 2026年湖南省中考英语真题含答案
- GB 47501-2026旋转电机安全技术规范
- 急性缺血性卒中再灌注治疗质量改进建议2026
- 施工现场高空作业专项施工方案
- 2026年护理专业英语测试题及答案
- 采购新员工培训课件
- 全国计算机二级WPS Office一次通关必刷题库(附答案解析)
评论
0/150
提交评论