简介:
项目包含对下位机(MCU对外设数据读取与控制),上位机(APP端),云端(云服务平台)的设计。下位机选取正点原子STM32MINI板作为MCU;外设有LED灯,DS18B20温度传感器,ESP8266,OLED;上位机为制作APP;云端选用中国移动旗下的OneNet平台作为服务器。
引脚:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| LED: PA8(自带)
DS18B20: VCC --> 3.3V GND --> GND DATA-->PA0
ESP8266: VCC --> 3.3V GND --> GND RX--> PA2 TX --> PA3 RST --> PC13 EN --> 3.3V
OLED: VCC --> 3.3V GND --> GND SCL --> PC0 SDA --> PC1 RES --> PC2 DC --> PC3
|
接线图:
OneNet平台使用
注册OneNet平台账号
登入后选择控制台,进入后点击全部产品服务,选择多协议接入;(我们使用MQTT,既可以上传数据也可以下发数据控制,而且都是免费的)
选择MQTT(旧版)之后添加产品,按照自己实际需求填写产品内容;
点击所创建的产品,添加几个设备(免费版用户上限10个设备)
(主要获取信息根据产品概况和设备列表的详情查看)
驱动代码
.c文件只截取关键信息函数功能不一一实现,.h文件有函数功能。
led.c
1 2 3 4 5 6 7 8 9 10 11 12 13
| void LED_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_ResetBits(GPIOA,GPIO_Pin_8); }
|
led.h
1 2 3 4 5 6 7 8 9 10 11
| #ifndef __LED_H #define __LED_H #include "sys.h"
#define LED0 PAout(8) #define LED1 PDout(2)
void LED_Init(void);
#endif
|
ds18b20.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| u8 DS18B20_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_0);
DS18B20_Rst();
return DS18B20_Check(); }
|
ds18b20.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #define DS18B20_IO_IN() {GPIOA->CRL&=0XFFFFFFF0;GPIOA->CRL|=8<<0;} #define DS18B20_IO_OUT() {GPIOA->CRL&=0XFFFFFFF0;GPIOA->CRL|=3<<0;}
#define DS18B20_DQ_OUT PAout(0) #define DS18B20_DQ_IN PAin(0) u8 DS18B20_Init(void); short DS18B20_Get_Temp(void); void DS18B20_Start(void); void DS18B20_Write_Byte(u8 dat); u8 DS18B20_Read_Byte(void); u8 DS18B20_Read_Bit(void); u8 DS18B20_Check(void); void DS18B20_Rst(void);
|
oled.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| void OLED_Init(void) { GPIO_InitTypeDef GPIO_OLEDInitStruct; RCC_APB2PeriphClockCmd(GPIO_OLED_CLK, ENABLE); GPIO_OLEDInitStruct.GPIO_Pin = GPIO_OLED_SCLK_Pin | GPIO_OLED_PIN_Pin | GPIO_OLED_RES_Pin | GPIO_OLED_DC_Pin; GPIO_OLEDInitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_OLEDInitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_OLEDInitStruct); GPIO_SetBits(GPIOC,GPIO_OLED_SCLK_Pin|GPIO_OLED_PIN_Pin|GPIO_OLED_RES_Pin|GPIO_OLED_DC_Pin);
OLED_RST_Set(); delay_ms(100); OLED_RST_Clr(); delay_ms(100); OLED_RST_Set(); OLED_WR_Byte(0xAE,OLED_CMD); OLED_WR_Byte(0x00,OLED_CMD); OLED_WR_Byte(0x10,OLED_CMD); OLED_WR_Byte(0x40,OLED_CMD); OLED_WR_Byte(0x81,OLED_CMD); OLED_WR_Byte(0xCF,OLED_CMD); OLED_WR_Byte(0xA1,OLED_CMD); OLED_WR_Byte(0xC8,OLED_CMD); OLED_WR_Byte(0xA6,OLED_CMD); OLED_WR_Byte(0xA8,OLED_CMD); OLED_WR_Byte(0x3f,OLED_CMD); OLED_WR_Byte(0xD3,OLED_CMD); OLED_WR_Byte(0x00,OLED_CMD); OLED_WR_Byte(0xd5,OLED_CMD); OLED_WR_Byte(0x80,OLED_CMD); OLED_WR_Byte(0xD9,OLED_CMD); OLED_WR_Byte(0xF1,OLED_CMD); OLED_WR_Byte(0xDA,OLED_CMD); OLED_WR_Byte(0x12,OLED_CMD); OLED_WR_Byte(0xDB,OLED_CMD); OLED_WR_Byte(0x40,OLED_CMD); OLED_WR_Byte(0x20,OLED_CMD); OLED_WR_Byte(0x02,OLED_CMD); OLED_WR_Byte(0x8D,OLED_CMD); OLED_WR_Byte(0x14,OLED_CMD); OLED_WR_Byte(0xA4,OLED_CMD); OLED_WR_Byte(0xA6,OLED_CMD); OLED_WR_Byte(0xAF,OLED_CMD); OLED_WR_Byte(0xAF,OLED_CMD); OLED_Clear(); OLED_Set_Pos(0,0); }
|
oled.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| #ifndef __OLED_H #define __OLED_H #include "sys.h" #include "stdlib.h"
#define OLED_MODE 0 #define GPIO_OLED_CLK RCC_APB2Periph_GPIOC #define GPIO_OLED_SCLK_Pin GPIO_Pin_0 #define GPIO_OLED_PIN_Pin GPIO_Pin_1 #define GPIO_OLED_RES_Pin GPIO_Pin_2 #define GPIO_OLED_DC_Pin GPIO_Pin_3
#define DATAOUT(x) GPIO_Write(GPIOB,x); #define OLED_RST_Clr() GPIO_ResetBits(GPIOC,GPIO_Pin_2) #define OLED_RST_Set() GPIO_SetBits(GPIOC,GPIO_Pin_2)
#define OLED_DC_Clr() GPIO_ResetBits(GPIOC,GPIO_Pin_3) #define OLED_DC_Set() GPIO_SetBits(GPIOC,GPIO_Pin_3)
#define OLED_SCLK_Clr() GPIO_ResetBits(GPIOC,GPIO_Pin_0) #define OLED_SCLK_Set() GPIO_SetBits(GPIOC,GPIO_Pin_0)
#define OLED_SDIN_Clr() GPIO_ResetBits(GPIOC,GPIO_Pin_1) #define OLED_SDIN_Set() GPIO_SetBits(GPIOC,GPIO_Pin_1)
#define OLED_CMD 0 #define OLED_DATA 1
void OLED_WR_Byte(u8 dat,u8 cmd); void OLED_Display_On(void); void OLED_Display_Off(void); void OLED_Refresh_Gram(void); void OLED_Init(void); void OLED_Clear(void); void OLED_DrawPoint(u8 x,u8 y,u8 t); void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 dot); void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode); void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size); void OLED_ShowString(u8 x,u8 y,const u8 *p,u8 size); void OLED_ShowChinese(u16 x,u16 y,u8 index,u8 size); #endif
|
esp8266.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| #define ESP8266_WIFI_INFO "AT+CWJAP=\"wy\",\"18770080824\"\r\n"
#define ESP8266_ONENET_INFO "AT+CIPSTART=\"TCP\",\"183.230.40.39\",6002\r\n"
void ESP8266_Init(void) { ESP8266_Clear(); UsartPrintf(USART_DEBUG, "0. AT\r\n"); while(ESP8266_SendCmd("AT\r\n", "OK")) delay_ms(500); UsartPrintf(USART_DEBUG,"1.rst\r\n"); ESP8266_SendCmd("AT+RST\r\n",""); delay_ms(500); ESP8266_SendCmd("AT+CIPCLOSE\r\n",""); delay_ms(500); UsartPrintf(USART_DEBUG, "2. CWMODE\r\n"); while(ESP8266_SendCmd("AT+CWMODE=1\r\n", "OK")) delay_ms(500); UsartPrintf(USART_DEBUG, "3. AT+CWDHCP\r\n"); while(ESP8266_SendCmd("AT+CWDHCP=1,1\r\n", "OK")) delay_ms(500); UsartPrintf(USART_DEBUG, "4. CWJAP\r\n"); while(ESP8266_SendCmd(ESP8266_WIFI_INFO, "GOT IP")) delay_ms(500); UsartPrintf(USART_DEBUG, "5. CIPSTART\r\n"); while(ESP8266_SendCmd(ESP8266_ONENET_INFO, "CONNECT")) delay_ms(500); UsartPrintf(USART_DEBUG, "6. ESP8266 Init OK\r\n");
}
|
esp8266.h
1 2 3 4 5 6 7 8 9 10 11 12 13
| #ifndef _ESP8266_H_ #define _ESP8266_H_
void ESP8266_Init(void);
void ESP8266_Clear(void);
void ESP8266_SendData(unsigned char *data, unsigned short len);
unsigned char *ESP8266_GetIPD(unsigned short timeOut);
#endif
|
onenet.c
1 2 3 4 5 6
| #define PROID "617134"
#define AUTH_INFO "led"
#define DEVID "1151407832"
|
onenet.h
1 2 3 4 5 6 7 8 9 10 11 12 13
| #ifndef _ONENET_H_ #define _ONENET_H_
_Bool OneNet_DevLink(void);
void OneNet_Subscribe(const char *topics[], unsigned char topic_cnt);
void OneNet_Publish(const char *topic, const char *msg);
void OneNet_RevPro(unsigned char *cmd);
#endif
|
main.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| #include "stm32f10x.h"
#include "delay.h" #include "usart.h" #include "led.h" #include "oled.h" #include "dht11.h" #include "lsens.h" #include "esp8266.h" #include "onenet.h" #include "ds18b20.h"
unsigned char usart1Len = 0; unsigned char usart1Buf[64];
int main(void) { const char *deviceSubTopic[]={"/1/sub"}; const char devicePubTopic[]="/1/pub"; char PUB_BUF[256]; char tmp[20]={0}; unsigned short timeCount=0; unsigned char *dataPtr=NULL; u8 temperature; u8 humidity; u8 adcx; delay_init(); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); Usart1_Init(115200); Usart2_Init(115200); LED_Init(); OLED_Init(); DS18B20_Init(); UsartPrintf(USART_DEBUG," Hardware init OK\r\n"); ESP8266_Init(); while(OneNet_DevLink()) delay_ms(500); OneNet_Subscribe(deviceSubTopic,1); while(1) { if(timeCount%40==0) { temperature=DS18B20_Get_Temp(); OLED_ShowChinese(0,0,30,16); OLED_ShowChinese(16,0,31,16); sprintf(tmp,":%d",temperature); OLED_ShowString(32,0,tmp,16); OLED_ShowChinese(60,0,32,16); OLED_Refresh_Gram(); UsartPrintf(USART_DEBUG,"温度:%d ,temperature); } if(++timeCount>=300) { UsartPrintf(USART_DEBUG,"OneNet_Publish\r\n"); OneNet_Publish(devicePubTopic,PUB_BUF); timeCount=0; ESP8266_Clear(); } dataPtr=ESP8266_GetIPD(3); if(dataPtr!=NULL) { OneNet_RevPro(dataPtr); } delay_ms(10); } }
|
在串口中断函数中实现开关灯
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| void USART2_IRQHandler(void) {
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) { if(esp8266_cnt >= sizeof(esp8266_buf)) esp8266_cnt = 0; esp8266_buf[esp8266_cnt++] = USART2->DR; if(USART2->DR==1) GPIO_SetBits(GPIOA,GPIO_Pin_8); else GPIO_ResetBits(GPIOA,GPIO_Pin_8); USART_ClearFlag(USART2, USART_FLAG_RXNE); }
}
|
下位机与云端实现效果
数据可视化可以进入此处进行配置
上位机APP