多点温控[[Onenet]+[Esp8266]+[Stm32[F4/F1]+[Pyqt5]+[Flutter[App]]系列笔记【三】(后接第四期)。

往期目录

Onenet部分(第一期):
https://blog.csdn.net/nja12/article/details/105648774.
Esp8266部分(第二期):
https://blog.csdn.net/nja12/article/details/105660222.
Stm32部分(第三期):
https://blog.csdn.net/nja12/article/details/105751015.
Stm32Wifi接收部分+++(第四期):
https://blog.csdn.net/nja12/article/details/105852408.

04/25

材料清单

前前后后搞了很多,先汇总一下我有啥

开发板
开发板Stm32F103C8t6小系统板
开发板Stm32F412ZG(其他项目)
开发板Stm32F407**(型号不记得了)
模块
温度模块Ds18b20
按钮自己焊了四个
显示Oled(我觉得好丑,但是打的时候用的这个,啧啧啧,一脸嫌弃)
下载器St-link(咳咳咳现在没了,我突然发现快递邮成了USB_TTL,啧啧啧,大家以后买东西看清楚啊,太聒噪了)
下载器J-link
串口USB
Wifi模块Esp8266-01
杜邦线姆对姆若干,父对父不多
Tec驱动还没打出来啧啧啧,又要虚构数据啧啧啧啧
还有啥劳累的灵魂
还有啥不多的头发
还有啥刚熬的绿豆汤

开发用程序和工程说明

工程生成STM32CubeMX
软件编译Keil5_MDK(破解版【啧啧啧】)
C代码库HAL库(其实有段时间打算放弃改用SPL库,因为网上历程真的大部分都是SPL库,HAL库写起来有些地方令人费解)

Stm32F103C8t6小系统板

先来看看板子长啥样子:
在这里插入图片描述
其实功能还是挺够的。先不看要做啥功能的,因为功能啥的后来都可以加。

话不多说先来点个灯
STM32CUBE

在这里插入图片描述
在这里插入图片描述
我们既然是点灯那么,我们还是需要知道那里有灯吧:
原理图:
在这里插入图片描述
很明显就可以发现PA15就是我要找的LED灯。
开始配置:
PA15 - GPIO_Output - Led
在这里插入图片描述
这个GPIO output level需要简单注意下
然后配置基础的RCC和SYS

RCC
在这里插入图片描述
SYS
在这里插入图片描述
差不多了
配置时钟频率
在这里插入图片描述
这个按需,因为我之后还需要用到PWM波,所以我把频率调大一点
我晶振是8.000000MHZ
在这里插入图片描述
仅供参考

好了可以生成了
Project Manager配置
在这里插入图片描述
生成:
在这里插入图片描述
它可以关了。

Keil5

我刚刚打开的时候惊了
在这里插入图片描述

Keil5居然自动更新了,啧啧啧,这样就不用我来回删这两个部分了,还是挺开心的。

弄个用户文件
我想大概是卡了在这里插入图片描述
可怕的无响应(重启一下再来)

led.h

#ifndef  __LED_H__
#define  __LED_H__
#include "stm32f1xx_hal.h"

//LED
#define  HAL_RCC_LED_GPIOX_CLK_EN()	__HAL_RCC_GPIOB_CLK_ENABLE()
#define  LED_PIN					GPIO_PIN_15
#define  LED_GPIOx					GPIOA
#define  LED_ON()					HAL_GPIO_WritePin(LED_GPIOx, LED_PIN, GPIO_PIN_SET)
#define  LED_OFF()					HAL_GPIO_WritePin(LED_GPIOx, LED_PIN, GPIO_PIN_RESET)
#define  LED_TOGGLE() 				HAL_GPIO_TogglePin(LED_GPIOx, LED_PIN)
#define  LED_Read()   				HAL_GPIO_ReadPin(LED_GPIOx, LED_PIN)

void  LED_GPIO_Init(void);

#endif

led.c

 void  LED_GPIO_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_RCC_LED_GPIOX_CLK_EN(); 
	GPIO_InitStruct.Pin  = LED_PIN;
	HAL_GPIO_Init(LED_GPIOx, &GPIO_InitStruct);
}

主函数导包 #include “led.h”
初始化 LED_GPIO_Init();
卑微的延时点灯

  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
		LED_ON();
		HAL_Delay(1000);
		LED_OFF();
		HAL_Delay(1000);
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
烧录一下,J-link

在这里插入图片描述
在这里插入图片描述
好的,很棒,点灯成功。

接下来做什么

需求分析

我们最初并不需要把所有东西都加进去,像PWM波,TEC驱动,甚至是键盘都不用加,那么做什么?

还记得上期是Esp8266, 所以不妨我们把Esp8266给搞了,这样搞定Wifi其他不都迎刃而解了嘛。

那么单纯的Esp8266第一期也说,我就加一个串口就好了,但是,我们怎么确定我们收到的是对的呢,或者说,我们怎么确定我们发送和接收是对的呢?

  • 我这里有两条路
    1. 搞两个串口,一个串口通过Usb做打印,一个串口过Esp8266接收和发送信息。分析:需求合理,但是,毕竟以后我们不用搞这块,单独加一个串口其实也没这个必要,(我们硬件部分根本没设计打印串口)
    2. Oled,用Oled显示串口信息也好,Esp8266信息也好。分析:需求更合理,因为,这个项目后期也是需要添加显示的。

所以
我打算先搞Oled显示屏,把函数写完,再写Esp8266的函数。写完这些,基本就项目闭环了。

OLED

先来展示一下这个丑丑的屏幕
在这里插入图片描述
在这里插入图片描述
参考资料其实是分两种的,对于这类屏幕其实就是到底选用SPI还是IIC
不过还好,我基本没怎么处理,这个模块的库网上还是很多的,并不需要自己完全按照规格书去摸索,那可太难受了。

说明----
GND接地
VCC接3.3V电源
D0(SCl)(SPI1_SCK===>LCD_SCK) 串行时钟总线
D1(SDA)(SPI1_MOSI===>LCD_MOSI) 串行数据线
RES硬复位OLED
DC命令/数据标志(写0命令,写1数据)
CS片选信号
STM32CUBE

在这里插入图片描述
简单命名:
在这里插入图片描述
因为只用了GPIO做这块,所以直接就可以用了。

Keil

先简单弄了一个:
oled.h:
(啧啧啧复制过来的注释是乱码emmmmmm, 不急,等这部分搞完我直接上传到Github上,到时候整个项目都在里面,供大家下载参考)

#ifndef __OLED__H
#define __OLED__H
#include "main.h"
#include "stm32f1xx_hal.h"

//-----------------OLED¶Ë¿Ú¶¨Òå----------------

#define OLED_SCLK_Clr() 	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET)//SCL
#define OLED_SCLK_Set() 	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET)

#define OLED_SDIN_Clr() 	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET)//SDA
#define OLED_SDIN_Set() 	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET)

#define OLED_RST_Clr() 		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET)//RES
#define OLED_RST_Set() 		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET)

#define OLED_DC_Clr() 		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET)//DC
#define OLED_DC_Set() 		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET)
 		     
#define OLED_CS_Clr()  		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET)//CS
#define OLED_CS_Set()  		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET)

#define OLED_CMD  0	//дÃüÁî
#define OLED_DATA 1	//дÊý¾Ý

//¸ù¾ÝÊý¾ÝÊÖ²áÌṩ¶ÔÓ¦µÄºê¶¨Òå
#define	    BRIGHTNESS	  0xCF			//ÁÁ¶È
#define     X_WIDTH       128				//¿í¶È
#define     Y_WIDTH       64				//³¤¶È
#define		  PAGE			    8					//Ò³Êý
#define			MAX_CHAR_POSX X_WIDTH-6 //×Ö·û¿í¶ÈÐèÒª-6
#define			MAX_CHAR_POSY Y_WIDTH-6 //×Ö·û³¤¶ÈÐèÒª-6

//º¯Êý¶¨Òå

void OLED_Init(void);												//OLEDµÄ³õʼ»¯
void OLED_WR_Byte(uint8_t dat, uint8_t cmd);//дÊý¾Ý
void OLED_DisPlay_On(void);									//¿ªÆôOLEDÏÔʾ
void OLED_DisPlay_Off(void);								//¹Ø±ÕOLEDÏÔʾ

void OLED_Refresh(void);										//¸üÐÂÏÔ´æµ½OLED
void OLED_Clear(void);											//ÇåÆÁº¯Êý

//»æͼº¯Êý

//»­µã(½÷¼ÇXYµÄ·¶Î§)
//x:0~127
//y:0~63
void OLED_DrawPoint(uint8_t x,uint8_t y);

//Çå³ýÒ»¸öµã(½÷¼ÇXYµÄ·¶Î§)
//x:0~127
//y:0~63
void OLED_ClearPoint(uint8_t x,uint8_t y);

//»­Ïß
//x:0~127
//y:0~63
//x1,y1£ºÆðµã×ø±ê
//x2,y2£ºÖÕµã×ø±ê
void OLED_DrawLine(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2);

//x,y:Ô²ÐÄ×ø±ê
//r:Ô²µÄ°ë¾¶
void OLED_DrawCircle(uint8_t x,uint8_t y,uint8_t r);

//ÔÚÖ¸¶¨Î»ÖÃÏÔʾһ¸ö×Ö·û,°üÀ¨²¿·Ö×Ö·û
//x:0~127
//y:0~63
//size:Ñ¡Ôñ×ÖÌå 12/16/24
void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t size1);

//ÏÔʾ×Ö·û´®
//x,y:Æðµã×ø±ê  
//size1:×ÖÌå´óС 
//*chr:×Ö·û´®ÆðʼµØÖ· 
void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t size1);

ÏÔʾ2¸öÊý×Ö
x,y :Æðµã×ø±ê	 
len :Êý×ÖµÄλÊý
size:×ÖÌå´óС
void OLED_ShowNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t size1);

//ÏÔʾºº×Ö
//x,y:Æðµã×ø±ê
//num:ºº×Ö¶ÔÓ¦µÄÐòºÅ
void OLED_ShowChinese(uint8_t x,uint8_t y,uint8_t num,uint8_t size1);

//num ÏÔʾºº×ֵĸöÊý
//space ÿһ±éÏÔʾµÄ¼ä¸ô
void OLED_ScrollDisplay(uint8_t num,uint8_t space);

//ÅäÖÃдÈëÊý¾ÝµÄÆðʼλÖÃ
void OLED_WR_BP(uint8_t x,uint8_t y);

//x0,y0£ºÆðµã×ø±ê
//x1,y1£ºÖÕµã×ø±ê
//BMP[]£ºÒªÐ´ÈëµÄͼƬÊý×é
void OLED_ShowPicture(uint8_t x0,uint8_t y0,uint8_t x1,uint8_t y1,uint8_t BMP[]);

//·´ÏÔº¯Êý
void OLED_ColorTurn(uint8_t i);

//ÆÁÄ»Ðýת180¶È
void OLED_DisplayTurn(uint8_t i);

//m^n
uint32_t OLED_Pow(uint8_t m,uint8_t n);

#endif //__OLED__H

oled.c:

#include "oled.h"
#include "oledfont.h" 

uint8_t OLED_GRAM [144][8];

//OLEDµÄ³õʼ»¯-----------
void OLED_Init(void)
{
	OLED_RST_Set();
	HAL_Delay(100);
	OLED_RST_Clr();//¸´Î»
	HAL_Delay(200);
	OLED_RST_Set();
	
	OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel
	OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
	OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
	OLED_WR_Byte(0x40,OLED_CMD);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
	OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register
	OLED_WR_Byte(0xCF,OLED_CMD);// Set SEG Output Current Brightness
	OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping     0xa0×óÓÒ·´ÖÃ 0xa1Õý³£
	OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction   0xc0ÉÏÏ·´Öà 0xc8Õý³£
	OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display
	OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
	OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty
	OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset	Shift Mapping RAM Counter (0x00~0x3F)
	OLED_WR_Byte(0x00,OLED_CMD);//-not offset
	OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
	OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
	OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period
	OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
	OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration
	OLED_WR_Byte(0x12,OLED_CMD);
	OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh
	OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level
	OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
	OLED_WR_Byte(0x02,OLED_CMD);//
	OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
	OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable
	OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
	OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7) 
	OLED_WR_Byte(0xAF,OLED_CMD);
	OLED_Clear();
}

//OLEDдÊý¾Ý-----------------------------
void OLED_WR_Byte(uint8_t dat, uint8_t cmd)
{
	uint8_t i;
	if(cmd)
	  OLED_DC_Set();
	else 
	  OLED_DC_Clr();		  
	OLED_CS_Clr();
	for(i=0;i<8;i++)
	{			  
		OLED_SCLK_Clr();
		if(dat&0x80)
		   OLED_SDIN_Set();
		else 
		   OLED_SDIN_Clr();
		OLED_SCLK_Set();
		dat<<=1;   
	}				 		  
	OLED_CS_Set();
	OLED_DC_Set();
}

//¿ªÆôOLEDÏÔʾ---------------------------
void OLED_DisPlay_On(void)	
{
	OLED_WR_Byte(0x8D,OLED_CMD);//µçºÉ±ÃʹÄÜ
	OLED_WR_Byte(0x14,OLED_CMD);//¿ªÆôµçºÉ±Ã
	OLED_WR_Byte(0xAF,OLED_CMD);//µãÁÁÆÁÄ»
}

//¹Ø±ÕOLEDÏÔʾ 
void OLED_DisPlay_Off(void)
{
	OLED_WR_Byte(0x8D,OLED_CMD);//µçºÉ±ÃʹÄÜ
	OLED_WR_Byte(0x10,OLED_CMD);//¹Ø±ÕµçºÉ±Ã
	OLED_WR_Byte(0xAF,OLED_CMD);//¹Ø±ÕÆÁÄ»
}

//¸üÐÂÏÔ´æµ½OLED-----------------------------	
void OLED_Refresh(void)
{
	uint8_t i,n;
	for(i = 0;i < 8;i++)
	{
	   OLED_WR_Byte(0xb0+i,OLED_CMD); //ÉèÖÃÐÐÆðʼµØÖ·
	   OLED_WR_Byte(0x00,OLED_CMD);   //ÉèÖõÍÁÐÆðʼµØÖ·
	   OLED_WR_Byte(0x10,OLED_CMD);   //ÉèÖøßÁÐÆðʼµØÖ·
	   for(n = 0;n < 128;n++)
		 OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA);
  }
}

//ÇåÆÁº¯Êý-----------------------------------------
void OLED_Clear(void)
{
	uint8_t i,n;
	for(i=0;i<8;i++)
	{
	   for(n=0;n<128;n++)
			{
			 OLED_GRAM[n][i]=0;//Çå³ýËùÓÐÊý¾Ý
			}
  }
	OLED_Refresh();//¸üÐÂÏÔʾ
}

//»­µã(½÷¼ÇXYµÄ·¶Î§)
//x:0~127
//y:0~63
void OLED_DrawPoint(uint8_t x,uint8_t y)
{
	uint8_t i,m,n;
	i=y/8;
	m=y%8;
	n=1<<m;
	OLED_GRAM[x][i]|=n;
}

//Çå³ýÒ»¸öµã(½÷¼ÇXYµÄ·¶Î§)
//x:0~127
//y:0~63
void OLED_ClearPoint(uint8_t x,uint8_t y)
{
	uint8_t i,m,n;
	i=y/8;
	m=y%8;
	n=1<<m;
	OLED_GRAM[x][i]=~OLED_GRAM[x][i];
	OLED_GRAM[x][i]|=n;
	OLED_GRAM[x][i]=~OLED_GRAM[x][i];
}


//»­Ïß
//x:0~127
//y:0~63
//x1,y1£ºÆðµã×ø±ê
//x2,y2£ºÖÕµã×ø±ê
void OLED_DrawLine(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2)
{
	uint8_t i,k,k1,k2;
	if(x1==x2)    //»­ÊúÏß
	{
			for(i=0;i<(y2-y1);i++)
			{
				OLED_DrawPoint(x1,y1+i);
			}
  }
	else if(y1==y2)   //»­ºáÏß
	{
			for(i=0;i<(x2-x1);i++)
			{
				OLED_DrawPoint(x1+i,y1);
			}
  }
	else      //»­Ð±Ïß
	{
		k1=y2-y1;
		k2=x2-x1;
		k=k1*10/k2;
		for(i=0;i<(x2-x1);i++)
			{
			  OLED_DrawPoint(x1+i,y1+i*k/10);
			}
	}
}

//x,y:Ô²ÐÄ×ø±ê
//r:Ô²µÄ°ë¾¶
void OLED_DrawCircle(uint8_t x,uint8_t y,uint8_t r)
{
	int a, b,num;
    a = 0;
    b = r;
    while(2 * b * b >= r * r)      
    {
        OLED_DrawPoint(x + a, y - b);
        OLED_DrawPoint(x - a, y - b);
        OLED_DrawPoint(x - a, y + b);
        OLED_DrawPoint(x + a, y + b);
 
        OLED_DrawPoint(x + b, y + a);
        OLED_DrawPoint(x + b, y - a);
        OLED_DrawPoint(x - b, y - a);
        OLED_DrawPoint(x - b, y + a);
        
        a++;
        num = (a * a + b * b) - r*r;//¼ÆËã»­µÄµãÀëÔ²ÐĵľàÀë
        if(num > 0)
        {
            b--;
            a--;
        }
    }
}

//ÔÚÖ¸¶¨Î»ÖÃÏÔʾһ¸ö×Ö·û,°üÀ¨²¿·Ö×Ö·û
//x:0~127
//y:0~63
//size:Ñ¡Ôñ×ÖÌå 12/16/24
void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t size1)
{
	uint8_t i,m,temp,size2,chr1;
	uint8_t y0=y;
	size2=(size1/8+((size1%8)?1:0))*(size1/2);  //µÃµ½×ÖÌåÒ»¸ö×Ö·û¶ÔÓ¦µãÕó¼¯ËùÕ¼µÄ×Ö½ÚÊý
	chr1=chr-' ';  //¼ÆËãÆ«ÒƺóµÄÖµ
	for(i=0;i<size2;i++)
	{
		if(size1==12)
        {temp=asc2_1206[chr1][i];} //µ÷ÓÃ1206×ÖÌå
		else if(size1==16)
        {temp=asc2_1608[chr1][i];} //µ÷ÓÃ1608×ÖÌå
		else if(size1==24)
        {temp=asc2_2412[chr1][i];} //µ÷ÓÃ2412×ÖÌå
		else return;
				for(m=0;m<8;m++)           //дÈëÊý¾Ý
				{
					if(temp&0x80)OLED_DrawPoint(x,y);
					else OLED_ClearPoint(x,y);
					temp<<=1;
					y++;
					if((y-y0)==size1)
					{
						y=y0;
						x++;
						break;
          }
				}
  }
}

//ÏÔʾ×Ö·û´®
//x,y:Æðµã×ø±ê  
//size1:×ÖÌå´óС 
//*chr:×Ö·û´®ÆðʼµØÖ· 
void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t size1)
{
	while((*chr>=' ')&&(*chr<='~'))//ÅжÏÊDz»ÊÇ·Ç·¨×Ö·û!
	{
		OLED_ShowChar(x,y,*chr,size1);
		x+=size1/2;
		if(x>128-size1)  //»»ÐÐ
		{
			x=0;
			y+=2;
    }
		chr++;
  }
}

ÏÔʾ2¸öÊý×Ö
x,y :Æðµã×ø±ê	 
len :Êý×ÖµÄλÊý
size:×ÖÌå´óС
void OLED_ShowNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t size1)
{
	uint8_t t,temp;
	for(t=0;t<len;t++)
	{
		temp=(num/OLED_Pow(10,len-t-1))%10;
			if(temp==0)
			{
				OLED_ShowChar(x+(size1/2)*t,y,'0',size1);
      }
			else 
			{
			  OLED_ShowChar(x+(size1/2)*t,y,temp+'0',size1);
			}
  }
}

//m^n
uint32_t OLED_Pow(uint8_t m,uint8_t n)
{
	uint32_t result=1;
	while(n--)
	{
	  result*=m;
	}
	return result;
}


//ÏÔʾºº×Ö
//x,y:Æðµã×ø±ê
//num:ºº×Ö¶ÔÓ¦µÄÐòºÅ
void OLED_ShowChinese(uint8_t x,uint8_t y,uint8_t num,uint8_t size1)
{
	uint8_t i,m,n=0,temp,chr1;
	uint8_t x0=x,y0=y;
	uint8_t size3=size1/8;
	while(size3--)
	{
		chr1=num*size1/8+n;
		n++;
			for(i=0;i<size1;i++)
			{
				if(size1==16)
						{temp=Hzk1[chr1][i];}//µ÷ÓÃ16*16×ÖÌå
				else if(size1==24)
						{temp=Hzk2[chr1][i];}//µ÷ÓÃ24*24×ÖÌå
				else if(size1==32)       
						{temp=Hzk3[chr1][i];}//µ÷ÓÃ32*32×ÖÌå
				else if(size1==64)
						{temp=Hzk4[chr1][i];}//µ÷ÓÃ64*64×ÖÌå
				else return;
							
						for(m=0;m<8;m++)
							{
								if(temp&0x01)OLED_DrawPoint(x,y);
								else OLED_ClearPoint(x,y);
								temp>>=1;
								y++;
							}
							x++;
							if((x-x0)==size1)
							{x=x0;y0=y0+8;}
							y=y0;
			 }
	}
}

//num ÏÔʾºº×ֵĸöÊý
//space ÿһ±éÏÔʾµÄ¼ä¸ô
void OLED_ScrollDisplay(uint8_t num,uint8_t space)
{
	uint8_t i,n,t=0,m=0,r;
	while(1)
	{
		if(m==0)
		{
	    OLED_ShowChinese(128,24,t,16); //дÈëÒ»¸öºº×Ö±£´æÔÚOLED_GRAM[][]Êý×éÖÐ
			t++;
		}
		if(t==num)
			{
				for(r=0;r<16*space;r++)      //ÏÔʾ¼ä¸ô
				 {
					for(i=0;i<144;i++)
						{
							for(n=0;n<8;n++)
							{
								OLED_GRAM[i-1][n]=OLED_GRAM[i][n];
							}
						}
           OLED_Refresh();
				 }
        t=0;
      }
		m++;
		if(m==16){m=0;}
		for(i=0;i<144;i++)   //ʵÏÖ×óÒÆ
		{
			for(n=0;n<8;n++)
			{
				OLED_GRAM[i-1][n]=OLED_GRAM[i][n];
			}
		}
		OLED_Refresh();
	}
}

//ÅäÖÃдÈëÊý¾ÝµÄÆðʼλÖÃ
void OLED_WR_BP(uint8_t x,uint8_t y)
{
	OLED_WR_Byte(0xb0+y,OLED_CMD);//ÉèÖÃÐÐÆðʼµØÖ·
	OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);//ÉèÖõÍÁÐÆðʼµØÖ·
	OLED_WR_Byte((x&0x0f)|0x01,OLED_CMD);//ÉèÖøßÁÐÆðʼµØÖ·
}

//x0,y0£ºÆðµã×ø±ê
//x1,y1£ºÖÕµã×ø±ê
//BMP[]£ºÒªÐ´ÈëµÄͼƬÊý×é
void OLED_ShowPicture(uint8_t x0,uint8_t y0,uint8_t x1,uint8_t y1,uint8_t BMP[])
{
	uint32_t j=0;
	uint8_t x=0,y=0;
	if(y%8==0)y=0;
	else y+=1;
	for(y=y0;y<y1;y++)
	 {
		 OLED_WR_BP(x0,y);
		 for(x=x0;x<x1;x++)
		 {
			 OLED_WR_Byte(BMP[j],OLED_DATA);
			 j++;
     }
	 }
}

//function---------------------------------------------
//·´ÏÔº¯Êý
void OLED_ColorTurn(uint8_t i)
{
	if(i==0)
		{
			OLED_WR_Byte(0xA6,OLED_CMD);//Õý³£ÏÔʾ
		}
	if(i==1)
		{
			OLED_WR_Byte(0xA7,OLED_CMD);//·´É«ÏÔʾ
		}
}

//ÆÁÄ»Ðýת180¶È
void OLED_DisplayTurn(uint8_t i)
{
	if(i==0)
		{
			OLED_WR_Byte(0xC8,OLED_CMD);//Õý³£ÏÔʾ
			OLED_WR_Byte(0xA1,OLED_CMD);
		}
	if(i==1)
		{
			OLED_WR_Byte(0xC0,OLED_CMD);//·´×ªÏÔʾ
			OLED_WR_Byte(0xA0,OLED_CMD);
		}
}

在main里面简单写了一个:

/* USER CODE BEGIN 2 */
	LED_GPIO_Init();
	LED_ON();
	
	OLED_Init();
	OLED_ColorTurn(1);//0Õý³£ÏÔʾ£¬1 ·´É«ÏÔʾ
	OLED_DisplayTurn(0);//0Õý³£ÏÔʾ 1 ÆÁÄ»·­×ªÏÔʾ
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
		OLED_ShowNum(16,16,12,2,16);
		OLED_Refresh();
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

然后就显示了一个数字12。
在这里插入图片描述

Esp8266

好了上面显示基本可以了。
下面是Esp8266这部分。
对于Esp8266其实连接也是挺简单的。
就四根线
TX_RX_GND_3.3V
所以我们需要配置一个串口。

STM32CUBE

在这里插入图片描述
我这里配了串口1(异步)

PA10Usart_Rx
PA9Usart_Tx
Baud Rate115200

在这里插入图片描述
在这里插入图片描述
没采用DMA, 主要是这方面用的少, 学业不精。

差不多了,简单配置一下优先级,可以更新软体了。

这部分其实在实际操作过程中做了些许修改。因为屏幕真的有点小,所以我其实还有用了打印的。

重新说一下引脚分配:

串口1用来做打印
PA9
PA10
波特率19200
串口三用来做通信
PB11
PB10
波特率115200
然后Wifi模块连接的时候做了修正
PB11
PB10
这两个是串口Tx,Rx,不会更改
添加PH_TD接3.3V
Vcc_Gnd不变
为了方便重构了串口三的发送函数,改用printf, 这个其实挺简单的
 	usart.c:
	int fputc(int c, FILE *stream)
	{
		HAL_UART_Transmit(&huart3,(uint8_t *)&c, 1, 1000);
		return c;
	}
	
	usart.h:
	//导包
	#include "stdlib.h"
	//或者导包
	#include "stdio.h"
	
	int fputc(int c, FILE *stream);
Keil(这部分其实不好写)
继续分析

既然我们要接收数据总要搞清数据帧格式对吧。
而不论是我们的初始化还是开启透传模式,其实都是AT指令,而往往会返回【时间戳】指令

Ok
所以,其实我们不用太在意帧头,只需要考虑帧尾的这个Ok就好了

用转串口直接在pc上试,你会很容易发现,这个结果是很好归纳的。

//AT帧尾格式…0D 0D 0A 0D 0A 4F 4B 0D 0A(九位)
所以对于这些咱们可以很简单的进行筛选。

在初代的串口三中断里面,只是设定了对于这9位的接收。

	void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
	{
		if(huart->Instance == USART3)
    {
			U3_Recieve_Buf[U3_RecPoint++] = U3_RecByte; // ½ÓÊÕµ½µÄ×Ö½Ú±£´æÔÚ½ÓÊÕ»º´æÇø?
      if(U3_RecPoint >= U3_RECIEVE_LENGTH) // ·ÀÖ¹»º´æÇøÒç³ö
      {
          U3_RecPoint = 0;
					U3_CheckPoint = 0;
      }
			HAL_UART_Receive_IT(&huart3, &U3_RecByte, 1); // ½ÓÊÕÍê³ÉÔÙ´ÎÉèÖÃ
			
			//ATÖ¸ÁȷÈÏ֡β.....0D 0D 0A 0D 0A 4F 4B 0D 0A(¾ÅλУÑé)
			switch(U3_CheckPoint)
			{
				case 0:
					if(U3_RecByte == 0x0D)//0D
					{
							U3_CheckPoint = 1;
					}else{
							U3_CheckPoint = 0;
					}
				case 1:
					if(U3_RecByte == 0x0D)//0D
					{
							U3_CheckPoint = 2;
					}else{
							U3_CheckPoint = 0;
					}
				case 2:
					if(U3_RecByte == 0x0A)//0A
					{
							U3_CheckPoint = 3;
					}else{
							U3_CheckPoint = 0;
					}
				case 3:
					if(U3_RecByte == 0x0D)//0D
					{
							U3_CheckPoint = 4;
					}else{
							U3_CheckPoint = 0;
					}
				case 4:
					if(U3_RecByte == 0x0A)//0A
					{
							U3_CheckPoint = 5;
					}else{
							U3_CheckPoint = 0;
					}
				case 5:
					if(U3_RecByte == 0x4F)//4F
					{
							U3_CheckPoint = 6;
					}else{
							U3_CheckPoint = 0;
					}
				case 6:
					if(U3_RecByte == 0x4B)//4B
					{
							U3_CheckPoint = 7;
					}else{
							U3_CheckPoint = 0;
					}
				case 7:
					if(U3_RecByte == 0x0D)//0D
					{
							U3_CheckPoint = 8;
					}else{
							U3_CheckPoint = 0;
					}
				case 8:
					if(U3_RecByte == 0x0A)//0A
					{
							U3_Rec_Success = SUCCESS; // ´®¿ÚÒ»½ÓÊÕÍê³ÉÒ»Ö¡Êý¾Ý
					}else{
							U3_CheckPoint = 0;
					}
			}
		}
	}
	

主函数里面还是要写好这几个的:

	U3_RecPoint = 0;
	U3_CheckPoint = 0;
	
	HAL_UART_Receive_IT(&huart3, &U3_RecByte, 1); //
	  while (1)
  {

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		if(U3_Rec_Success == SUCCESS) // ´®¿ÚÒ»½ÓÊÕÍê³ÉÒ»Ö¡Êý¾Ý
     {
			U3_Rec_Success = ERROR;
		 	U3_RecPoint = 0;
			U3_CheckPoint = 0;
			memset(U3_Recieve_Buf,0, U3_RECIEVE_LENGTH);
			HAL_UART_Receive_IT(&huart3, &U3_RecByte, 1); //µÈ´ý½ÓÊܵÚÒ»¸öÊý¾Ý²¢µÈ´ý½øÈëÖжÏ
     }
		 
  }
  /* USER CODE END 3 */
}

然后这部分做完,写一个初始化函数就好。

//Esp8266.h
#ifndef  __Esp8266_H__
#define  __Esp8266_H__
#include "stm32f1xx_hal.h"
#include "usart.h"

//Esp826Ä£¿é³õʼ»¯
void Esp8266_init(void);

#endif

这里用了屏幕的地方简单在调用的时候,做个显示,这部分其实我们是不需要接收的。所以初始化Esp8266的顺序在串口接收开之前或者之后都没关系。

#include "Esp8266.h"
#include "oled.h"

void Esp8266_init(void)
{
		OLED_ShowString(0,48,(unsigned char*)"WIFI_Init",16);	//ÏÔʾWifi_³õʼ»¯
		OLED_Refresh();
		
		HAL_Delay(2000);//ÑÓʱÁ½Ãë
		
		printf("AT\r\n");
		HAL_Delay(1000);
	
		printf("AT+CWMODE=3\r\n");
		HAL_Delay(1000);
	
		printf("AT+RST\r\n");
		HAL_Delay(1000);
	
		OLED_ShowString(0,48,(unsigned char*)"WIFI_CONNECTED",16);	//ÏÔʾWifi_³õʼ»¯
		OLED_Refresh();
		printf("AT+CWJAP=\"Q2020\",\"ai0406.0\"\r\n");
		HAL_Delay(1000);
	
		OLED_Clear();
}

弄好这些才是主要的。我们要开启透传模式。

而之后发送和接收其实都是需要有一定事件间隔的,所以就开始开定时器。

对于定时器,其实有一个公式来算延时时间。

大概的算法是 固有频率/(precal***+1)(period+1)

其实固有频率可以看到的,但是就我而言,之前很多次搞的时候发现对不上。让自己陷入一种对公式的迷惑中,其实还是很不划算的。

下面我们先来开一个定时器。

穿插一个定时器

在这里插入图片描述
简单一改,然后优先级一加就行。至于那个计算,其实我建议就是不算0多好,之后自己该函数。不过,改完好像下次加东西的时候还会被覆盖掉啧啧啧,是有点烦的哈。最后改,我这里简单搞一个数实测试试。

搞个Led。

6399/9999。 加一×起来差不多640000000,0.1hz, 10s(你们自己算哈)
639/9999。 加一×起来差不多64000000,1hz, 1s(你们自己算哈)
639/999。 加一×起来差不多6400000,10hz, 0.1s(你们自己算哈)

先来个定时器中断处理函数


/* USER CODE BEGIN 1 */
// ¶¨Ê±Æ÷µÄÖжϻص÷º¯Êý
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
		//¶¨Ê±Æ÷ËÄÖжϻص÷
		if(htim->Instance == TIM4)
    {
				LED_TOGGLE();
    }
}

别忘了把led.h导进去

然后到主函数里面开一下:

	HAL_TIM_Base_Start_IT(&htim4);

可以了,烧一下

哈哈哈,我发现查不多一秒啧啧啧。6399/9999

改改639/9999更快

那就63999/9999(逼我)实测00:09:91

可以开始Post和Get了

测试我们要接受的数据

Post请求理论上是不需要接收的。当然串口还是会自动接收这些数据。这并不要紧。

一开始我在想,唉,原来Post我一下Post五六行,Keil里面我写多少,哈哈,其实我也迷惑了。但是我用Pc这样测试之后我就知道了:
在这里插入图片描述
这说明可以逐行。

那么就来看看我的Post是怎么写的:

void Esp8266_Post(void)
{
		OLED_Clear();
		OLED_ShowString(16,32,(unsigned char*)"Post-ing",16);	//ÏÔʾWifi_³õʼ»¯
		OLED_Refresh();
		
		printf("POST /devices/592808742/datapoints?type=3 HTTP/1.1\r\n");
		HAL_Delay(100);
	
		printf("api-key:Jl6WGd3z9Qmms0uGX7uGm=dq8jU=\r\n");
		HAL_Delay(100);
	
		printf("Host:api.heclouds.com\r\n");
		HAL_Delay(100);
	
		printf("Content-Length:20\r\n");
		HAL_Delay(100);
	
		printf("\r\n");
		HAL_Delay(100);
	
		printf("{\"Online\":1;\"Tec\":1}\r\n");
		HAL_Delay(100);
		
		OLED_ShowString(16,32,(unsigned char*)"Post-OK",16);	//ÏÔʾWifi_³õʼ»¯
		OLED_Refresh();
}

当然这并不是我们期望的,因为这是属于死数据。我们之后要把这个Json数据变成改变的,而且还有一个需要改变,就是把Content-Length:20变成变动的。

啧啧啧啧,有点毛病,我先去解决,保存一下。
上传不上去

关于Post的Json是这样处理的:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>

const char *const b2s(bool b)
{
    return b != 0 ? "true" : "false";
}

void makePostJson(char *temp, bool Online, int Temp_z3, int Temp_z4, bool Tec, bool Warning)
{
    sprintf(temp, "{\"Online\":%s,\"Temp_z3\":%d,\"Temp_z4\":%d,\"Tec\":%s,\"Warning\":%s}",
            b2s(Online), Temp_z3, Temp_z4, b2s(Tec), b2s(Warning));
}

int main()
{
    bool Online = 1;
    int Temp_z3 = 25;
    int Temp_z4 = 25;
    bool Tec = 1;
    bool Warning = 0;
    char *temp = calloc(100 /*自己估算长度*/, sizeof(char));
    makePostJson(temp, Online, Temp_z3, Temp_z4, Tec, Warning);
    printf("%s", temp);
	printf("%d", strlen(temp));
    free(temp); //一定记得 free
}

基于这个进行修改就可以了。
这些都会在最后附上。

我先把Get调试完。

这部分我打算放第四期,有点激动。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值