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.
前前后后搞了很多,先汇总一下我有啥
开发板 | – |
---|---|
开发板 | Stm32F103C8t6小系统板 |
开发板 | Stm32F412ZG(其他项目) |
开发板 | Stm32F407**(型号不记得了) |
模块 | – |
---|---|
温度模块 | Ds18b20 |
按钮 | 自己焊了四个 |
显示 | Oled(我觉得好丑,但是打的时候用的这个,啧啧啧,一脸嫌弃) |
下载器 | J-link |
串口 | USB |
Wifi模块 | Esp8266-01 |
杜邦线 | 姆对姆若干,父对父不多 |
Tec驱动 | 还没打出来啧啧啧,又要虚构数据啧啧啧啧 |
还有啥 | 劳累的灵魂 |
还有啥 | 不多的头发 |
还有啥 | 刚熬的绿豆汤 |
工程生成 | STM32CubeMX |
---|---|
软件编译 | Keil5_MDK(破解版【啧啧啧】) |
C代码库 | HAL库(其实有段时间打算放弃改用SPL库,因为网上历程真的大部分都是SPL库,HAL库写起来有些地方令人费解) |
先来看看板子长啥样子:
其实功能还是挺够的。先不看要做啥功能的,因为功能啥的后来都可以加。
我们既然是点灯那么,我们还是需要知道那里有灯吧:
原理图:
很明显就可以发现PA15就是我要找的LED灯。
开始配置:
PA15 - GPIO_Output - Led
这个GPIO output level需要简单注意下
然后配置基础的RCC和SYS
RCC
SYS
差不多了
配置时钟频率
这个按需,因为我之后还需要用到PWM波,所以我把频率调大一点
我晶振是8.000000MHZ
仅供参考
好了可以生成了
Project Manager配置
生成:
它可以关了。
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 */
我们最初并不需要把所有东西都加进去,像PWM波,TEC驱动,甚至是键盘都不用加,那么做什么?
还记得上期是Esp8266, 所以不妨我们把Esp8266给搞了,这样搞定Wifi其他不都迎刃而解了嘛。
那么单纯的Esp8266第一期也说,我就加一个串口就好了,但是,我们怎么确定我们收到的是对的呢,或者说,我们怎么确定我们发送和接收是对的呢?
所以:
我打算先搞Oled显示屏,把函数写完,再写Esp8266的函数。写完这些,基本就项目闭环了。
先来展示一下这个丑丑的屏幕
参考资料其实是分两种的,对于这类屏幕其实就是到底选用SPI还是IIC
不过还好,我基本没怎么处理,这个模块的库网上还是很多的,并不需要自己完全按照规格书去摸索,那可太难受了。
说明 | ---- |
---|---|
GND | 接地 |
VCC | 接3.3V电源 |
D0(SCl) | (SPI1_SCK===>LCD_SCK) 串行时钟总线 |
D1(SDA) | (SPI1_MOSI===>LCD_MOSI) 串行数据线 |
RES | 硬复位OLED |
DC | 命令/数据标志(写0命令,写1数据) |
CS | 片选信号 |
先简单弄了一个:
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 */
好了上面显示基本可以了。
下面是Esp8266这部分。
对于Esp8266其实连接也是挺简单的。
就四根线
TX_RX_GND_3.3V
所以我们需要配置一个串口。
PA10 | Usart_Rx |
---|---|
PA9 | Usart_Tx |
Baud Rate | 115200 |
差不多了,简单配置一下优先级,可以更新软体了。
重新说一下引脚分配:
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);
既然我们要接收数据总要搞清数据帧格式对吧。
而不论是我们的初始化还是开启透传模式,其实都是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
#include
#include
#include
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调试完。
这部分我打算放第四期,有点激动。