stm32使用oled,温度传感器,mqtt,舵机等
点击下载:https://cloud.189.cn/t/AJzQranqIFVr
PB15→SDA
PB13→SCL
yys@yys:~/test/0.96OLED_STM32F103RC_$ tree . ├── CORE │ ├── core_cm3.c │ ├── core_cm3.h │ ├── startup_stm32f10x_hd.s │ └── startup_stm32f10x_md.s ├── HARDWARE │ └── OLED │ ├── bmp.h │ ├── oled.c │ ├── oledfont.h │ ├── oled.h │ └── __Previews │ └── oled.hPreview ├── keilkilll.bat ├── OBJ │ ├── core_cm3.crf │ ├── core_cm3.d │ ├── core_cm3.o │ ├── delay.crf │ ├── delay.d │ ├── delay.o │ ├── ExtDll.iex │ ├── key.crf │ ├── key.d │ ├── key.o │ ├── led.crf │ ├── led.d │ ├── main.crf │ ├── main.d │ ├── main.o │ ├── misc.crf │ ├── misc.d │ ├── misc.o │ ├── OLED.axf │ ├── OLED.build_log.htm │ ├── oled.crf │ ├── oled.d │ ├── OLED.hex │ ├── OLED.htm │ ├── OLED.lnp │ ├── oled.o │ ├── OLED.plg │ ├── OLED.sct │ ├── OLED_sct.Bak │ ├── OLED_Target 1.dep │ ├── startup_stm32f10x_hd.d │ ├── startup_stm32f10x_hd.o │ ├── stm32f10x_gpio.crf │ ├── stm32f10x_gpio.d │ ├── stm32f10x_gpio.o │ ├── stm32f10x_it.crf │ ├── stm32f10x_it.d │ ├── stm32f10x_it.o │ ├── stm32f10x_rcc.crf │ ├── stm32f10x_rcc.d │ ├── stm32f10x_rcc.o │ ├── stm32f10x_usart.crf │ ├── stm32f10x_usart.d │ ├── stm32f10x_usart.o │ ├── sys.crf │ ├── sys.d │ ├── sys.o │ ├── system_stm32f10x.crf │ ├── system_stm32f10x.d │ ├── system_stm32f10x.o │ ├── usart.crf │ ├── usart.d │ └── usart.o ├── STM32F10x_FWLib │ ├── inc │ │ ├── misc.h │ │ ├── stm32f10x_adc.h │ │ ├── stm32f10x_bkp.h │ │ ├── stm32f10x_can.h │ │ ├── stm32f10x_cec.h │ │ ├── stm32f10x_crc.h │ │ ├── stm32f10x_dac.h │ │ ├── stm32f10x_dbgmcu.h │ │ ├── stm32f10x_dma.h │ │ ├── stm32f10x_exti.h │ │ ├── stm32f10x_flash.h │ │ ├── stm32f10x_fsmc.h │ │ ├── stm32f10x_gpio.h │ │ ├── stm32f10x_i2c.h │ │ ├── stm32f10x_iwdg.h │ │ ├── stm32f10x_pwr.h │ │ ├── stm32f10x_rcc.h │ │ ├── stm32f10x_rtc.h │ │ ├── stm32f10x_sdio.h │ │ ├── stm32f10x_spi.h │ │ ├── stm32f10x_tim.h │ │ ├── stm32f10x_usart.h │ │ └── stm32f10x_wwdg.h │ └── src │ ├── misc.c │ ├── stm32f10x_adc.c │ ├── stm32f10x_bkp.c │ ├── stm32f10x_can.c │ ├── stm32f10x_cec.c │ ├── stm32f10x_crc.c │ ├── stm32f10x_dac.c │ ├── stm32f10x_dbgmcu.c │ ├── stm32f10x_dma.c │ ├── stm32f10x_exti.c │ ├── stm32f10x_flash.c │ ├── stm32f10x_fsmc.c │ ├── stm32f10x_gpio.c │ ├── stm32f10x_i2c.c │ ├── stm32f10x_iwdg.c │ ├── stm32f10x_pwr.c │ ├── stm32f10x_rcc.c │ ├── stm32f10x_rtc.c │ ├── stm32f10x_sdio.c │ ├── stm32f10x_spi.c │ ├── stm32f10x_tim.c │ ├── stm32f10x_usart.c │ └── stm32f10x_wwdg.c ├── SYSTEM │ ├── delay │ │ ├── delay.c │ │ └── delay.h │ ├── sys │ │ ├── sys.c │ │ └── sys.h │ └── usart │ ├── usart.c │ └── usart.h └── USER ├── JLinkLog.txt ├── JLinkSettings.ini ├── main.c ├── OLED.map ├── OLED.opt.bak ├── OLED_Target 1.dep ├── OLED.Uv2.bak ├── OLED.uvgui.Administrator ├── OLED.uvgui_Administrator.bak ├── OLED.uvgui.evk ├── OLED.uvgui_evk.bak ├── OLED.uvgui.hp ├── OLED.uvgui.yys53 ├── OLED.uvopt ├── OLED.uvproj ├── startup_stm32f10x_hd.lst ├── stm32f10x_conf.h ├── stm32f10x.h ├── stm32f10x_it.c ├── stm32f10x_it.h ├── system_stm32f10x.c └── system_stm32f10x.h 13 directories, 137 files
1.需要把oled文件夹得文件移动到led得HARDWARE文件夹
2.把 main.c得代码复制到oled文文件
3.改sys.c
D:\stm32\xbstm32\SYSTEM\sys\sys.c
void NVIC_Configuration(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
}
4.声明变量(不声明会警告)
D:\stm32\xbstm32\SYSTEM\sys\sys.h
#ifndef __SYS_H
void NVIC_Configuration(void);
#endif
5.编译标准选c99(不然报错)
c/c++→c99 mode(√)
6.output→Browse Infoemation(如果没有选择得话,这个可以调到自定义函数)
VCC——3v3
GND——GND
DATA——PA0
D:\stm32\xbstm32\HARDWARE\DHT11\dht11.c
#include "dht11.h"
#include "delay.h"
//复位DHT11
void DHT11_Rst(void)
{
DHT11_IO_OUT(); //SET OUTPUT
DHT11_DQ_OUT=0; //拉低DQ
delay_ms(20); //拉低至少18ms
DHT11_DQ_OUT=1; //DQ=1
delay_us(30); //主机拉高20~40us
}//等待DHT11的回应
//返回1:未检测到DHT11的存在
//返回0:存在
u8 DHT11_Check(void)
{
u8 retry=0;
DHT11_IO_IN();//SET INPUT
while (DHT11_DQ_IN&&retry<100)//DHT11会拉低40~80us
{
retry++;
delay_us(1);
};
if(retry>=100)return 1;
else retry=0;
while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高40~80us
{
retry++;
delay_us(1);
};
if(retry>=100)return 1;
return 0;
}
//从DHT11读取一个位
//返回值:1/0
u8 DHT11_Read_Bit(void)
{
u8 retry=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)return 1;
else return 0;
//从DHT11读取一个字节
//返回值:读到的数据
}
u8 DHT11_Read_Byte(void)
{
u8 i,dat;
dat=0;
for (i=0;i<8;i++)
{
dat<<=1;
dat|=DHT11_Read_Bit();
}
return dat;
}
//从DHT11读取一次数据
//temp:温度值(范围:0~50℃)
//humi:湿度值(范围:20%~90%)
//返回值:0,正常;1,读取失败
u8 DHT11_Read_Data(u8 *temp,u8 *humi)
{
u8 buf[5];
u8 i;
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];
}
}else return 1;
return 0;
}//初始化DHT11的IO口 DQ 同时检测DHT11的存在
//返回:1 不存在
//返回:0 存在
//配置GPIO
u8 DHT11_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //ʹÄÜPB¶Ë¿ÚʱÖÓ
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PB11¶Ë¿ÚÅäÖÃ
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);
DHT11_Rst();
return DHT11_Check();
}
D:\stm32\xbstm32\HARDWARE\DHT11\dht11.h
#ifndef __DHT11_H
#define __DHT11_H
#include "sys.h"
//IO方向设置
#define DHT11_IO_IN() {GPIOA->CRL&=0XFFFFFFF0;GPIOA->CRL|=8<<0;}
#define DHT11_IO_OUT() {GPIOA->CRL&=0XFFFFFFF0;GPIOA->CRL|=3<<0;}
//IO操作函数
#define DHT11_DQ_OUT PAout(0) //数据端口 PA0
#define DHT11_DQ_IN PAin(0) //数据端口 PA0
u8 DHT11_Init(void);//初始化DHT11
u8 DHT11_Read_Data(u8 *temp,u8 *humi);//读取温湿度
u8 DHT11_Read_Byte(void);//读出一个字节
u8 DHT11_Read_Bit(void);//读初一个位
u8 DHT11_Check(void);//检测是否存在DHT11
void DHT11_Rst(void);//复位DHT11
#endif
D:\stm32\xbstm32\USER\main.c
#include "dht11.h"
/*dht11*/
u8 temperature;
u8 humidity;
DHT11_Init();//初始化DHT11
/*温度*/
DHT11_Read_Data(&temperature,&humidity);
OLED_ShowNum(36,6,temperature,3,16); // (x, y,数字, )
OLED_ShowNum(103,6,humidity,3,16);//显示ASCII字符的码值
参考帖子:https://blog.csdn.net/ssssadw/article/details/111584510
表1 USART2重映像
复用功能 |
USART2_REMAP =0 |
USART2_ REMAP=1(1) |
USART2_CTS |
PA0 |
PD3 |
USART2_RTS |
PA1 |
PD4 |
USART2_TX |
PA2 |
PD5 |
USART2_RX |
PA3 |
PD6 |
USART2_CK |
PA4 |
PD7 |
(1)重映像只适用于100和144脚的封装
表2 USART1重映像
复用功能 |
USART1_REMAP =0 |
USART1_ REMAP=1 |
USART1_TX |
PA9 |
PB6 |
USART1_RX |
PA10 |
PB7 |
接线(arduino烧录过的stm32会出现问题):
-
ESP8266-01S(5根线,第一排stm32引脚,第二排esp)
- PA2 RX
- PA3 TX
- PA4 RST
- 3V3 VCC
- GND GND
-
DHT11(3根线)
-
PA6 DATA
-
3V3 VCC
-
GND GND
-
-
LED
- PD2 LED1
1.修改腾讯云clientid, 用户名密码,定于发布主题
D:\stm32\myMqtt\HARDWARE\inc\mqtt.h
#define PRODUCTID "864L95CSW9tem;12010126;CWWKU;1648250775" //相当于用户名 //产品ID
#define PRODUCTID_LEN strlen(PRODUCTID) //产品ID长度
#define DEVICEID "864L95CSW9tem" //设备ID 相当于clientid
#define DEVICEID_LEN strlen(DEVICEID) //设备ID长度
#define AUTHENTICATION "a20a849a17e223aa3ec724d5a550f4bed52d41676aa6df61fdd72819bc3ae684;hmacsha256" // 相当于密码 //鉴权信息
#define AUTHENTICATION_LEN strlen(AUTHENTICATION) //鉴权信息长度
#define S_TOPIC_NAME "864L95CSW9/tem/DHT" //需要订阅的主题
#define P_TOPIC_NAME "864L95CSW9/tem_mqtt/DHT"
#define Data_TOPIC_NAME "$dp"
2.修改域名和端口号
sprintf(ServerIP,"%s","864L95CSW9.iotcloud.tencentdevices.com"); //构建服务器域名
ServerPort = 1883; //服务器端口号6002
u1_printf("服 务 器:%s:%d\r\n",ServerIP,ServerPort); //串口输出调试信息
u1_printf("客户端ID:%s\r\n",ClientID); //串口输出调试信息
u1_printf("用 户 名:%s\r\n",Username); //串口输出调试信息
u1_printf("密 码:%s\r\n",Passward);
3.修改路由器wifi密码
#define SSID "yang1234" //路由器SSID名称
#define PASS "y123456789" //路由器密码
登陆腾讯云会发现tem在线
|
tem_mqtt |
离线 |
已启用 |
- |
2021-02-12 12:40:23 |
管理设备影子权限列表删除 |
|
tem |
在线 |
已启用 |
- |
2021-02-12 12:40:42 |
管理设备影子权限列表删除 |
打开MQTT.fx软件
Publish话题
864L95CSW9/tem_mqtt/DHT
命令发送LEDOFF,或LEDON
读取光敏电阻的函数
GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)
u1_printf("GPIOA0引脚数值:%d\r\n",GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0));
读取红外感应
u1_printf("GPIOA1引脚数值:%d\r\n",GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1));
源码链接:https://cloud.189.cn/t/uaq2Ir3MFZba
舵机——PWM控制
电机与舵机差不多,电机多一个驱动模块下节细讲。
此视频中的舵机型号为sg90,最大承重90克,三个接口,黄的为信号线(PWM信号传输),棕的为GND,红的为VCC。
舵机一般周期为20ms,
0.5ms--0度;
1.0ms--45度;
1.5ms--90度;
2.0ms--135度;
2.5ms--180度。
老规矩先创建原工程的副本,然后此外流程与前几讲一样,此处不再赘述。
然后注意上一讲超声波里已经用了定时器2此次舵机采用TIM3来输出PWM。
每个定时器有四个通道,打开用户手册查看通道对应的管脚。注意TIM3定时器的通道都在复用功能里,故注意
开启TIM3的时钟同时也要开启AFIO时钟——专门管复用功能的时钟。
注意此次PWM的H文件中初始化函数里边不在是空的void,而是将arr与psc放入进去(定时器中断需要用它计算溢出时间),这样的好处是可以在main函数中直接调节PWM的周期,而不用回到PWM的C文件中调节。
C文件里,首先仍旧是定义结构体,此视频中用到了三个结构体分别为GPIO、TIM定时器以及TIM-OCInitstruct定时器通道。因为既有定时器的收发又有定时器通道的收发。
然后是使能GPIO的时钟、定时器的时钟以及AFIO复用时钟。注意:舵机只需使能一个引脚 即可,为了下一讲电机的使用方便此处使能两个引脚,
然后将结构体里的变量赋值,注意——此处输出由推挽输出改为复用推挽。
先将GPIO结构体进行赋值然后对其初始化。
然后将定时器结构体内变量赋值然后对其初始化;
其中arr为自动重装载值,psc为预分频系数。本次采用向上计数。
定时器通道结构体内变量赋值。然后使能并且初始化通道一与二,之后使能预装载器,最后使能定时器3。
至此PWM的初始化C文件完成。
转到主函数调用头文件PWM.H,加入PWM初始化函数,
此处用到上讲的周期计算公式
(arr+1)(psc+1)/tick=周期
20000*72/72000000=20ms。
占空比的设置
编译0error,烧入。
烧入前介绍舵机测试仪。稳压模块插入此测试仪检测舵机是否损坏。
本文作者: 永生
本文链接: https://yys.zone/detail/?id=204
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
评论列表 (0 条评论)