网站建设与设计学了做什么的,网站登录注册页面模板下载,冷门缺人却高薪的职业,哪个网站可以免费做简历目录
前言#xff1a;
项目效果演示#xff1a;
一、简介
二、硬件需求准备
三、硬件框图
四、CubeMX配置
4.1、按键、蜂鸣器GPIO口配置
4.2、ADC输入配置
4.3、IIC——驱动OLED
4.4、DHT11温湿度读取
4.5、PWM配置——光照灯、水泵、风扇
4.6、串口——esp8266模…目录
前言
项目效果演示
一、简介
二、硬件需求准备
三、硬件框图
四、CubeMX配置
4.1、按键、蜂鸣器GPIO口配置
4.2、ADC输入配置
4.3、IIC——驱动OLED
4.4、DHT11温湿度读取
4.5、PWM配置——光照灯、水泵、风扇
4.6、串口——esp8266模块
4.7、定时器配置——按键消抖所需
五、部分代码实现思路
5.1、菜单实现思路
5.2、OLED驱动
5.3、按键消抖
5.4、DHT11温湿度驱动
5.5、光照强度、土壤湿度ADC转换
5.6、esp8266连接阿里云
六、功能拓展 前言
注意事项本项目使用的是u8g2库进行显示驱动OLED需要学会移植或者直接使用我的模板具体可以看我的这个博文手把手移植基于STM移植U8g2图形库教程——0.96寸OLED附送整理资料
买来的esp8266模可能不支持连接阿里云需要烧写MQTT固件具体操作可以看看我的这个博文手把手连接阿里云教程
里面都会有所需的固件和工具和教程
项目效果演示 智能农业大棚 一、简介
这可以作为一个简单的课设或者用来水毕设的一个小项目总体来说挺简单的我做完后就打算开源出来大家一起学习一下具体功能如下 1、按键 按键一切换菜单 按键二切换选项 按键三-或调节风扇 | 水泵 | 灯光 按键四确认 | 连接阿里云平台 2、液晶屏幕显示 菜单1主界面显示空气温湿度土壤湿度光照强度检测是否超过或低于临界值 菜单2临界值调节 菜单3风扇手动开关 菜单4灯光手动开关 菜单5水泵手动开关 菜单6阿里云连接菜单界面 3、土壤湿度、空气温湿度、光照强度高于或低于临界值蜂鸣器就会响 4、土壤湿度过低自动打开水泵 5、光照强度过低自动打开照明灯 6、空气温度过高会自动打开风扇 7、连接阿里云平台可以在电脑上面查看各个数据 二、硬件需求准备 1、STM32F103最小核心开发板 2、0.96寸OLED屏幕 3、按键X4 4、TB6612FNG点击驱动模块 5、水泵 6、电机带小风扇 7、DHT11温湿度模块 8、esp8266模块 9、蜂鸣器 10、土壤湿度传感器 11、光照强度传感器 12、照明灯模块 三、硬件框图 四、CubeMX配置
这里只演示配置使用的外设配置过程
4.1、按键、蜂鸣器GPIO口配置
按键配置为上拉模式、蜂鸣器低电平输出有效 4.2、ADC输入配置
ADC为读取土壤湿度和光照强度的ADC数值这里开启两个ADC分别读取
ADC1——读取土壤湿度 ADC2——读取光照强度 4.3、IIC——驱动OLED 4.4、DHT11温湿度读取
这个使用过程中会对弈随意变动上下拉模式所以这里就不配置了使用的GPIO口为PB8
4.5、PWM配置——光照灯、水泵、风扇 4.6、串口——esp8266模块 开启中断
4.7、定时器配置——按键消抖所需 开启中断 最后生成工程即可。
五、部分代码实现思路
5.1、菜单实现思路
最常用的就是菜单索引法还有链表法我这里菜单结构非常简单所以我就使用索引法了这里简单说一下就是每一个菜单都对应一个结构体这个项目没有二级界面所以用不到进入索引和返回索引
typedef struct
{int current_index;//当前索引int last_index; //下一索引int enter_index; //进入索引int back_index; //返回索引void(*current)(u8g2_t u8g2);}Menu;
结构体成员包括以上的几个。
这个小项目有5个菜单页面所以定义5个结构体这个项目没有二级界面所以用不到进入索引和返回索引
Menu Menu_Table[30]
{
// 当 下 进 返{0, 1, 0, 0,(*Home_Menu)}, //主页显示界面{1, 2, 0, 0,(*Set_Menu)}, //设置临界值界面{2, 3, 0, 0,(*Fan_Menu)}, //风扇控制界面{3, 4, 0, 0,(*Light_Menu)},//灯光控制界面{4, 5, 0, 0,(*Water_Menu)},//水泵控制界面{5, 0, 0, 0,(*Wifi_Menu)},//连接阿里云控制界面};
然后定义一个当前显示菜单的索引值和当前菜单显示绘制函数
int Current_Menu_index 0;//当前菜单索引
void(*Current)(u8g2_t u8g2);//当前菜单索引执行绘制函数
然后初始化好按键按下后执行跳转
切换下一菜单使用例子如果是其他的可以八next换成其他的结构体成员
Current_Menu_index Menu_Table[Current_Menu_index].last_index;//变换索引值Current Menu_Table[Current_Menu_index].current;//函数复制
(*Current)(u8g2);//执行绘制函数
在举一个例子帮助大家理解一下比如我们当前程序处在索引号为2临界值界面就会执行Set_Menu函数。此时如果按下next按键程序当前索引号就会变为3并且执行索引号为3时候的Fan_Menu函数。以此类推
5.2、OLED驱动
这里我是使用开源的u8g2库进行开发这个库显示效果很好而且也很好移植具体可以参考我的这个博文移植u8g2库移植成功后使用也可以看看我的另外要给博文u8g2库函数使用
5.3、按键消抖
我这里使用的是中断消抖
unsigned char Key_PIN_Read()
{unsigned char Temp0;if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12) GPIO_PIN_RESET) Temp 1;if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_13) GPIO_PIN_RESET) Temp 2;if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_14) GPIO_PIN_RESET) Temp 3;if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_15) GPIO_PIN_RESET) Temp 4;return Temp;} void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) //中断回调函数
{Key_Slow;if(Key_Slow 10) Key_Slow 0;//按键消抖
}void Key_Pro()
{if(Key_Slow) return;//按键减速Key_Slow1;Key_ValKey_PIN_Read();Key_DownKey_Val (Key_Val ^ Key_Old);//捕捉下降沿Key_Up ~Key_Val (Key_Old ^ Key_Val);//捕捉按键上降沿Key_OldKey_Val;switch(Key_Up){case 1:break;case 2:break;case 3:break;case 4:break;}}
5.4、DHT11温湿度驱动
手动配置GPIO模式
#define DHT_HIGHT HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET)
#define DHT_LOW HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET)
#define DHT_VALUE HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_8)uint8_t datas[5];//空气温湿度数据void delay_us(uint16_t cnt)
{uint8_t i;while(cnt){for (i 0; i 10; i){} cnt--;}
}void DHT_GPIO_Init(uint32_t Mode)
{GPIO_InitTypeDef GPIO_InitStruct {0};__HAL_RCC_GPIOB_CLK_ENABLE();GPIO_InitStruct.Pin GPIO_PIN_8;GPIO_InitStruct.Mode Mode;GPIO_InitStruct.Speed GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOB, GPIO_InitStruct);
}void DHT11_Start(void)
{DHT_GPIO_Init(GPIO_MODE_OUTPUT_PP);DHT_HIGHT;DHT_LOW;HAL_Delay(30);DHT_HIGHT;DHT_GPIO_Init(GPIO_MODE_INPUT);while(DHT_VALUE);while(!DHT_VALUE);while(DHT_VALUE);
}void Read_Data_From_DHT()
{int i;//轮int j;//每一轮读多少次char tmp;char flag;DHT11_Start();DHT_GPIO_Init(GPIO_MODE_INPUT);for(i 0;i 5;i){for(j0;j8;j){while(!DHT_VALUE);//等待卡g点delay_us(40);if(DHT_VALUE 1){flag 1;while(DHT_VALUE);}else{flag 0;}tmp tmp 1;tmp | flag;}datas[i] tmp;}
}
数据显示以及文字显示
void Printf_DHT11(u8g2_t u8g2,u8g2_uint_t x, u8g2_uint_t y, const uint8_t *font)
{char var_buf[100];char var_buf1[100];Read_Data_From_DHT();//读取温湿度数据u8g2_DrawXBMP(u8g2, x, y, 16, 16, kong);u8g2_DrawXBMP(u8g2, x16, y, 16, 16, qi);u8g2_DrawXBMP(u8g2, x32, y, 16, 16, wen);u8g2_DrawXBMP(u8g2, x48, y, 16, 16, du);u8g2_DrawXBMP(u8g2, x, y16, 16, 16, kong);u8g2_DrawXBMP(u8g2, x16, y16, 16, 16, qi);u8g2_DrawXBMP(u8g2, x32, y16, 16, 16, wen);u8g2_DrawXBMP(u8g2, x48, y16, 16, 16, du);sprintf(var_buf , : %d.%d C,datas[2],datas[3]);sprintf(var_buf1, : %d.%d,datas[0],datas[1]);u8g2_SetFont(u8g2, font);u8g2_DrawStr(u8g2, x64, y16, var_buf);u8g2_DrawStr(u8g2, x64, y32, var_buf1);
}
5.5、光照强度、土壤湿度ADC转换
int Printf_Soil(u8g2_t u8g2,u8g2_uint_t x, u8g2_uint_t y, const uint8_t *font)
{char var[100];int value;HAL_ADC_Start(hadc1); //启动ADC单次转换HAL_ADC_PollForConversion(hadc1, 50); //等待ADC转换完成value HAL_ADC_GetValue(hadc1); //读取ADC转换数据value 100 - value * 100 / 4096;
// Soil value;u8g2_DrawXBMP(u8g2, x, y, 16, 16, tu);u8g2_DrawXBMP(u8g2, x16, y, 16, 16, rang);u8g2_DrawXBMP(u8g2, x32, y, 16, 16, shi);u8g2_DrawXBMP(u8g2, x48, y, 16, 16, du);sprintf(var , : %d %%, value);u8g2_SetFont(u8g2, font);u8g2_DrawStr(u8g2, x64, y16, var);return value;}int Printf_Light(u8g2_t u8g2,u8g2_uint_t x, u8g2_uint_t y, const uint8_t *font)
{char var[100];int value;HAL_ADC_Start(hadc2); //启动ADC单次转换HAL_ADC_PollForConversion(hadc2, 50); //等待ADC转换完成value HAL_ADC_GetValue(hadc2); //读取ADC转换数据value 100 - value * 100 / 4096;
// Light value;u8g2_DrawXBMP(u8g2, x, y, 16, 16, guang);u8g2_DrawXBMP(u8g2, x16, y, 16, 16, zhao);u8g2_DrawXBMP(u8g2, x32, y, 16, 16, qiang);u8g2_DrawXBMP(u8g2, x48, y, 16, 16, du);sprintf(var , : %d %%, value);u8g2_SetFont(u8g2, font);u8g2_DrawStr(u8g2, x64, y16, var);return value;}
5.6、esp8266连接阿里云
这里我为了保险起见就是用了很多的延迟时间连接时间过长你们可以自己调节时间
#define USERNAME testk28qfTAtkBg //用户名
// testk28qfTAtkBg
#define PASSWORD d7c3b27a5d8ca954487de1e1946a4a08439a2c2508242268e9d90ce178178f39 //密码
// d7c3b27a5d8ca954487de1e1946a4a08439a2c2508242268e9d90ce178178f39
#define CLIENTID k28qfTAtkBg.test|securemode2\\,signmethodhmacsha256\\,timestamp1736673123047| //设备名称
// k28qfTAtkBg.test|securemode2\\,signmethodhmacsha256\\,timestamp1736673123047|
#define PRODUCTID k28qfTAtkBg //产品ID
// k28qfTAtkBg
#define DOMAINNAME iot-06z00fj5kcoes6j.mqtt.iothub.aliyuncs.com //域名
// iot-06z00fj5kcoes6j.mqtt.iothub.aliyuncs.com
#define DEVICENAME test//WiFi连接函数
void Wifi_Connect()
{printf(AT\r\n);//避免报错HAL_Delay(500);printf(ATRESTORE\r\n);//恢复出厂HAL_Delay(5000);// printf(ATRST\r\n);//复位
// HAL_Delay(5000);printf(ATE0\r\n);//关闭回显HAL_Delay(5000);printf(ATCWMODE3\r\n);//设置双模式HAL_Delay(5000);printf(ATCWJAP\USER_E191B0\,\98599714\\r\n);//设置WIFI密码和账号HAL_Delay(5000);printf(ATMQTTUSERCFG0,1,\NULL\,\%s\,\%s\,0,0,\\\r\n,USERNAME,PASSWORD);//设置MQTT的username和passwordHAL_Delay(5000);printf(ATMQTTCLIENTID0,\%s\\r\n,CLIENTID); //设置CLIENTIDHAL_Delay(5000);printf(ATMQTTCONN0,\%s\,1883,1\r\n,DOMAINNAME);//设置域名HAL_Delay(5000);printf(ATMQTTSUB0,\/%s/%s/user/get\,1\r\n,PRODUCTID,DEVICENAME);//订阅}
六、功能拓展 后续拓展 1、电脑阿里云平台控制单片机 2、添加语音模块 。。。。。。。。。。。。其他 后续打了PCB板子后有空会实现给大家觉得有帮助的可以点点关注