STM32传感器外设集 -- 蓝牙(HC-05)+超声波(hc-sr04)
前言
前言:蓝牙外设还没有给大家安排上,今天我就给大家安排上使用蓝牙传输超声波距离的例程,会给大家附带蓝牙的上位机的测试APP
一、模块介绍
1.连接图
蓝牙模块 | 引脚 | 超声波传感器 | 引脚 |
GND | GND | GND | GND |
VCC | 3.3 | VCC | 5V |
EN | PA7 | TG | PB13 |
RST | PA5 | EG | PB12 |
TX | PB11 | ||
RX | PB10 |
2 蓝牙(HC-05)
介绍
蓝牙通讯技术是-f0短距离通讯方式,主机和从机使用相同的通讯协议,不同的应用中,可以使用不同的通讯协议,协议规范遵循开放系统互联参考模型。HC05模块是一款高性能主从一体蓝牙串口模块。支持 SPP 蓝牙串口协议,具有成本低、体积小、功耗低、收发灵敏性高等优点,它可以充当三种角色,分别是Slave(从角色)、Master(主角色)和Slave-Loop(回环角色)。
连线图
3.超声波(hc-sr04)
介绍
HC-SR04超声波距离传感器的核心是两个超声波传感器。一个用作发射器,将电信号转换为40 KHz超声波脉冲。接收器监听发射的脉冲。如果接收到它们,它将产生一个输出脉冲,其宽度可用于确定脉冲传播的距离。就是如此简单!
该传感器体积小,易于在任何机器人项目中使用,并提供2厘米至400厘米(约1英寸至13英尺)之间出色的非接触范围检测,精度为3mm。由于它的工作电压为5伏
连线图
三、 代码编写
使用到了串口三和两个定时器
usart3.c
#include "delay.h"
#include "usart3.h"
#include "stdarg.h"
#include "stdio.h"
#include "string.h"
#include "timer.h"//串口接收缓存区
u8 USART3_RX_BUF[USART3_MAX_RECV_LEN]; //接收缓冲,最大USART3_MAX_RECV_LEN个字节.
u8 USART3_TX_BUF[USART3_MAX_SEND_LEN]; //发送缓冲,最大USART3_MAX_SEND_LEN字节//通过判断接收连续2个字符之间的时间差不大于10ms来决定是不是一次连续的数据.
//如果2个字符接收间隔超过10ms,则认为不是1次连续数据.也就是超过10ms没有接收到
//任何数据,则表示此次接收完毕.
//接收到的数据状态
//[15]:0,没有接收到数据;1,接收到了一批数据.
//[14:0]:接收到的数据长度
vu16 USART3_RX_STA=0; void USART3_IRQHandler(void)
{u8 res; if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)//接收到数据{ res =USART_ReceiveData(USART3); if((USART3_RX_STA&(1<<15))==0)//接收完的一批数据,还没有被处理,则不再接收其他数据{ if(USART3_RX_STA<USART3_MAX_RECV_LEN) //还可以接收数据{TIM_SetCounter(TIM3,0);//计数器清空 //计数器清空if(USART3_RX_STA==0) //使能定时器7的中断 {TIM_Cmd(TIM3,ENABLE);//使能定时器7}USART3_RX_BUF[USART3_RX_STA++]=res; //记录接收到的值 }else {USART3_RX_STA|=1<<15; //强制标记接收完成} }}
} //初始化IO 串口3
//pclk1:PCLK1时钟频率(Mhz)
//bound:波特率
void usart3_init(u32 bound)
{ NVIC_InitTypeDef NVIC_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // GPIOB时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE); //串口3时钟使能USART_DeInit(USART3); //复位串口3//USART3_TX PB10GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PB10GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PB10//USART3_RX PB11GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PB11USART_InitStructure.USART_BaudRate = bound;//波特率一般设置为9600;USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式USART_Init(USART3, &USART_InitStructure); //初始化串口 3USART_Cmd(USART3, ENABLE); //使能串口 //使能接收中断USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启中断 //设置中断优先级NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2 ;//抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器TIM3_Init(99,7199); //10ms中断USART3_RX_STA=0; //清零TIM_Cmd(TIM3,DISABLE); //关闭定时器7}//串口3,printf 函数
//确保一次发送数据不超过USART3_MAX_SEND_LEN字节
void u3_printf(char* fmt,...)
{ u16 i,j; va_list ap; va_start(ap,fmt);vsprintf((char*)USART3_TX_BUF,fmt,ap);va_end(ap);i=strlen((const char*)USART3_TX_BUF); //此次发送数据的长度for(j=0;j<i;j++) //循环发送数据{while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕 USART_SendData(USART3,USART3_TX_BUF[j]); }
}
usart3.h
#ifndef __USART3_H
#define __USART3_H
#include "sys.h"
#define USART3_MAX_RECV_LEN 600 //最大接收缓存字节数
#define USART3_MAX_SEND_LEN 600 //最大发送缓存字节数
#define USART3_RX_EN 1 //0,不接收;1,接收.extern u8 USART3_RX_BUF[USART3_MAX_RECV_LEN]; //接收缓冲,最大USART3_MAX_RECV_LEN字节
extern u8 USART3_TX_BUF[USART3_MAX_SEND_LEN]; //发送缓冲,最大USART3_MAX_SEND_LEN字节
extern vu16 USART3_RX_STA; //接收数据状态void usart3_init(u32 bound); //串口2初始化
void u3_printf(char* fmt,...);
#endif
hc05.c
#include "delay.h"
#include "usart.h"
#include "usart3.h"
#include "hc05.h" #include "string.h"
#include "math.h"
//初始化ATK-HC05模块
//返回值:0,成功;1,失败.
u8 HC05_Init(void)
{u8 retry=10,t; u8 temp=1;GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能PORTAGPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; // 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHzGPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化A15GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; // 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHzGPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA4GPIO_SetBits(GPIOA,GPIO_Pin_7);GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);HC05_KEY=1;HC05_LED=1; usart3_init(9600); //初始化串口2为:9600,波特率.while(retry--){HC05_KEY=1; //KEY置高,进入AT模式delay_ms(10);u3_printf("AT\r\n"); //发送AT测试指令HC05_KEY=0; //KEY拉低,退出AT模式for(t=0;t<10;t++) //最长等待50ms,来接收HC05模块的回应{if(USART3_RX_STA&0X8000)break;delay_ms(5);} if(USART3_RX_STA&0X8000) //接收到一次数据了{temp=USART3_RX_STA&0X7FFF; //得到数据长度USART3_RX_STA=0; if(temp==4&&USART3_RX_BUF[0]=='O'&&USART3_RX_BUF[1]=='K'){temp=0;//接收到OK响应break;}} } if(retry==0)temp=1; //检测失败return temp;
}
//获取ATK-HC05模块的角色
//返回值:0,从机;1,主机;0XFF,获取失败.
u8 HC05_Get_Role(void)
{ u8 retry=0X0F;u8 temp,t;while(retry--){HC05_KEY=1; //KEY置高,进入AT模式delay_ms(10);u3_printf("AT+ROLE?\r\n"); //查询角色for(t=0;t<20;t++) //最长等待200ms,来接收HC05模块的回应{delay_ms(10);if(USART3_RX_STA&0X8000)break;} HC05_KEY=0; //KEY拉低,退出AT模式if(USART3_RX_STA&0X8000) //接收到一次数据了{temp=USART3_RX_STA&0X7FFF; //得到数据长度USART3_RX_STA=0; if(temp==13&&USART3_RX_BUF[0]=='+')//接收到正确的应答了{temp=USART3_RX_BUF[6]-'0';//得到主从模式值break;}} }if(retry==0)temp=0XFF;//查询失败.return temp;
}
//ATK-HC05设置命令
//此函数用于设置ATK-HC05,适用于仅返回OK应答的AT指令
//atstr:AT指令串.比如:"AT+RESET"/"AT+UART=9600,0,0"/"AT+ROLE=0"等字符串
//返回值:0,设置成功;其他,设置失败.
u8 HC05_Set_Cmd(u8* atstr)
{ u8 retry=0X0F;u8 temp,t;while(retry--){HC05_KEY=1; //KEY置高,进入AT模式delay_ms(10);u3_printf("%s\r\n",atstr); //发送AT字符串HC05_KEY=0; //KEY拉低,退出AT模式for(t=0;t<20;t++) //最长等待100ms,来接收HC05模块的回应{if(USART3_RX_STA&0X8000)break;delay_ms(5);} if(USART3_RX_STA&0X8000) //接收到一次数据了{temp=USART3_RX_STA&0X7FFF; //得到数据长度USART3_RX_STA=0; if(temp==4&&USART3_RX_BUF[0]=='O')//接收到正确的应答了{ temp=0;break; }} }if(retry==0)temp=0XFF;//设置失败.return temp;
}
///
//通过该函数,可以利用USMART,调试接在串口3上的ATK-HC05模块
//str:命令串.(这里注意不再需要再输入回车符)
void HC05_CFG_CMD(u8 *str)
{ u8 temp;u8 t; HC05_KEY=1; //KEY置高,进入AT模式delay_ms(10);u3_printf("%s\r\n",(char*)str); //发送指令for(t=0;t<50;t++) //最长等待500ms,来接收HC05模块的回应{if(USART3_RX_STA&0X8000)break;delay_ms(10);} HC05_KEY=0; //KEY拉低,退出AT模式if(USART3_RX_STA&0X8000) //接收到一次数据了{temp=USART3_RX_STA&0X7FFF; //得到数据长度USART3_RX_STA=0;USART3_RX_BUF[temp]=0; //加结束符 printf("\r\n%s",USART3_RX_BUF);//发送回应数据到串口1}
}
hc05.h
#ifndef __HC05_H
#define __HC05_H
#include "sys.h" #define HC05_KEY PAout(7) //蓝牙控制KEY信号
#define HC05_LED PAin(5) //蓝牙连接状态信号u8 HC05_Init(void);
void HC05_CFG_CMD(u8 *str);
u8 HC05_Get_Role(void);
u8 HC05_Set_Cmd(u8* atstr);
#endif
HC_SR04.c
#include "HC_SR04.h"
#include "timer.h"
#include "delay.h"// void HC_SR04_IO_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB端口时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; // 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHzGPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB.12GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; // 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHzGPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB.13}u16 TIM2_UPDATA = 0;
u32 temp = 0;
u16 Get_SR04_Distance(void)
{SR04_Trlg=1; //触发信号是高电平脉冲,宽度大于10usdelay_us(20);SR04_Trlg=0;while(!SR04_Echo); //等待高电平TIM_SetCounter(TIM2,0); //重填计数器值TIM2_UPDATA = 0; //溢出次数清零while(SR04_Echo); //等待低电平TIM_Cmd(TIM2,DISABLE); //暂时关闭定时器,保证数据正确性temp = (int)(((double)(TIM_GetCounter(TIM2) + (7200* TIM2_UPDATA)))/72/2); //得到高电平总时间,单位us(定时器的计数值加上溢出的值才是高电平的时间),除以2是计算单程的时间//(7200* TIM2_UPDATA这里为溢出的时间us,可以转换为100* TIM2_UPDATA,因为在公式后面除以了72。可最终理解为TIM2_UPDATA个100us)TIM_Cmd(TIM2,ENABLE);return temp;
}
HC_SR04.h
#ifndef __HC_SR04_H
#define __HC_SR04_H
#include "sys.h"#define SR04_Trlg PBout(12)// PB12
#define SR04_Echo PBin(13)// PB13 void HC_SR04_IO_Init(void);
u16 Get_SR04_Distance(void);#endif
timer.c
#include "timer.h"
#include "delay.h"
#include "sys.h"//通用定时器中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//这里使用的是定时器2void TIM2_Init(u16 arr,u16 psc)
{ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能TIM2时钟//初始化定时器2 TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器自动重装值 TIM_TimeBaseStructure.TIM_Prescaler =psc; //预分频器 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位//中断分组初始化NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //TIM3中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //先占优先级2级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级0级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//允许更新中断 ,TIM_Cmd(TIM2,ENABLE ); //使能定时器2}
//定时器2中断服务程序 主要记录溢出次数extern u16 TIM2_UPDATA;
extern u8 state_machine;
void TIM2_IRQHandler(void)
{ if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源 {TIM2_UPDATA++;//当回响信号很长时,记录溢出次数,每加一次代表加100usTIM_ClearITPendingBit(TIM2, TIM_IT_Update); //清除中断标志位}
}void TIM3_Init(u16 arr,u16 psc)
{ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能TIM2时钟//初始化定时器3 TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器自动重装值 TIM_TimeBaseStructure.TIM_Prescaler =psc; //预分频器 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位//中断分组初始化NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //先占优先级2级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级0级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//允许更新中断 ,TIM_Cmd(TIM3,ENABLE ); //使能定时器2}extern vu16 USART3_RX_STA;
//定时器3中断服务程序
void TIM3_IRQHandler(void)
{ if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)//是更新中断{ USART3_RX_STA|=1<<15; //标记接收完成TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除TIM7更新中断标志 TIM_Cmd(TIM3, DISABLE); //关闭TIM7 }
}
timer.h
#ifndef __TIMER_H
#define __TIMER_H
#include "sys.h"void TIM2_Init(u16 arr,u16 psc);
void TIM3_Init(u16 arr,u16 psc);#endif
main.c
#include "delay.h"
#include "sys.h"
#include "timer.h"
#include "HC_SR04.h"
#include <stdio.h>
#include <math.h>
#include "usart.h"
#include "hc05.h"
#include "usart3.h"
//STM32超声波测距
int SAFET_Distance = 300; //安全距离
float Distance = 0; //距离
//显示ATK-HC05模块的主从状态
void HC05_Role_Show(void)
{if(HC05_Get_Role()==1)printf("ROLE:Master \n"); //主机else printf("ROLE:Slave \n"); //从机
// /*4. 设置蓝牙的名称*/
// if(HC05_Set_Cmd("AT+NAME=HEATR"))printf("4 蓝牙名称设置失败!\r\n");
// else printf("4 蓝牙名称设置为 HEATR \r\n");
// /*5. 设置蓝牙配对密码*/
// if(HC05_Set_Cmd("AT+PSWD=1234"))printf("5 蓝牙配对密码设置失败!\r\n"); //密码必须是4位
// else printf("5 蓝牙配对密码设置为 1234 \r\n");
}
//显示ATK-HC05模块的连接状态
void HC05_Sta_Show(void)
{ if(HC05_LED)printf("STA:Connected \n"); //连接成功else printf("STA:Disconnect \n"); //未连接
}
int main(void)
{char displaytemp[16]; //开启字符串空间int bobao_delay;u16 time=0;u16 count = 0;u8 reclen=0;u8 key = 0;delay_init(); //延时函数初始化uart_init(115200);HC_SR04_IO_Init(); //超声波模块GPIO初始化delay_ms(500); //上电瞬间加入一定延时在初始化TIM2_Init(7199,0); //以10KHz计数,定时100usdelay_ms(1000); //等待蓝牙模块上电稳定while(HC05_Init()) //初始化ATK-HC05模块 {printf("ATK-HC05 Error!\n"); delay_ms(500);printf("Please Check!!!\n"); delay_ms(100);}HC05_Role_Show();delay_ms(100);USART3_RX_STA=0; while(1){time++ ;Distance = (Get_SR04_Distance() * 331) * 1.0/1000; //Get_SR04_Distance()返回单程声波传输时间 us,转换为秒=时间*10^(-6);331m/s等于331000mm/s,//最终换算为Distance =Get_SR04_Distance()*10^(-6)*331000=(Get_SR04_Distance() * 331) * 1.0/1000;delay_ms(10);if(time==300){u3_printf(" %.1f",Distance); //发送到蓝牙模块printf("%.1f\n",Distance);HC05_Sta_Show();time=0;} if(USART3_RX_STA&0X8000) //接收到一次数据了{reclen=USART3_RX_STA&0X7FFF; //得到数据长度USART3_RX_BUF[reclen]=0; //加入结束符printf("%s\n",USART3_RX_BUF);//显示接收到的数据USART3_RX_STA=0; } }}
四、 蓝牙APP测试工具
链接:
APP连接https://pan.baidu.com/s/1LOWmq_fsPrx7TskBymwxlQ?pwd=heru%C2%A0
提取码:heru
总结
STM32传感器外设集 -- 蓝牙(HC-05)+超声波(hc-sr04)相关推荐
- STM32传感器外设集--温湿度模块(DHT11)
目录 原理图 介绍 main.c bsp_dht11.h bsp_dht11.c core_delay.h core_delay.c 原理图 介绍 DHT11是我们最常见的一种温湿度传感器,但是精度不 ...
- STM32传感器外设集--语音模块(SYN6288)
目录 图片 SYN6288.h SYN6288.c stm32f10x_it.h main.c 图片 如何使用该模块呢,首先,SYN6288是使用串口通讯的,很多模块其实都是使用串口通讯,有助于指令的 ...
- stm32蓝牙模块和超声波测距模块
蓝牙 蓝牙概念 蓝牙技术是一种无线数据和语音通信开放的全球规范,它是基于低成本的近距离无线连接,为固定和移动设备建立通信环境的一种特殊的近距离无线技术连接. [1] 蓝牙使当前的一些便携移动设备和计算 ...
- 连接 蓝牙HC - 05 模块 读写操作
连接 蓝牙HC - 05 模块 进行读写操作 1. 开启蓝牙进行连接 //藍牙private BluetoothAdapter bluetoothAdapter;private Set<Blue ...
- B40 - 基于STM32单片机的电热蚊香蓝牙控制系统
任务 本项目进行智能电热蚊香器系统的设计与开发,将STM32开发板作为一个微控制器,结合蓝牙技术,通过手机APP软件对电热蚊香器进行灵活的控制,使电热蚊香器的功能更加人性化,更加符合当代人们对家用电器 ...
- stm32超声波扫频_基于STM32的脉冲式及扫频式超声波除垢信号源设计
基于 STM32 的脉冲式及扫频式超声波除垢信号源设计 李连通 , 张伟光 *, 李金博 [摘 要] [摘 要] 介绍了一种基于 STM32 主控芯片产生两种不同信号源的实 现 ] 脉冲信号源可以产生 ...
- STM32操控外设为什么要先使能时钟
STM32操控外设为什么要先使能时钟 STM32的新手,一般都会对一个问题很纠结.我也是,就是所谓的"时钟问题".我们在尽心STM32编程时,会痛苦地发现这样一个事实:不管你要干嘛 ...
- STM32基于WiFi和蓝牙的内外网通信
目录 通信模块选择 WiFi模块 蓝牙模块 基本框架 1.内网通信(近距离通信) 2.外网通信(远程通信) 3.关于WiFi配网以及云平台验证问题 4.关于蓝牙名称问题 模块连接图示 重要驱动开发 S ...
- STM32的外设介绍
片上资源又叫做外设,英文是peripheral,下面这个表里就是STM32F1系列的外设资源. 我们主要学习的就是STM32的外设,通过程序配置外设来完成我们想要的功能.在这个表中,前两个深颜色的是位 ...
最新文章
- 基于Redis的服务治理平台!
- spring中lazy-init详解
- 朝夕科技网络版GIS地图解决方案
- android dbflow教程,Android高性能ORM数据库DBFlow入门教程
- WebCore中的渲染机制(二):块和内嵌(Blocks and Inlines)
- visual studio 2019、2017、2015下载网址
- c语言中陶陶摘苹果while,洛谷 P1478 陶陶摘苹果(升级版) C语言实现
- java list对象按照某个属性去重
- 【LoadRunner技术讲座8】LoadRunner函数中的几个陷阱
- 大话手游时间服务器哪个最新,大话手游时间服和免费服优缺点分析!选择最适合你的...
- 【基础】CNN是靠什么线索学习到深度信息的?——一个经验性探索
- 《神经网络与深度学习》课程笔记(4)-- 浅层神经网络
- python写的监视bt.ktxp.com的rss的小脚本 updated
- [20150228]Delayed Block Cleanout 2.txt
- android 打开微信代码,3个超实用的微信隐藏代码,仅限安卓
- Python数据加密与解密相关操作(hashlib、hmac、random、base64、pycrypto)
- 2019年‘泰迪杯’数据分析职业技能大赛A题——个人代码分享
- ilog开发培训大纲
- 8、135条最全弱电智能化综合布线常用术语
- C++之重载:函数名的鱼塘
热门文章
- php 数组 打乱顺序,PHP数组随机乱序和反序的实例详解
- 100天精通Oracle-实战系列(第3天)超详细 RHEL 7 安装单机 Oracle 11GR2 数据库
- 迟来的续集--Drawable+Animator,将优雅进行到底
- 操作被占用的文件-unlocker机理分析(转)
- SAP MDG —— DRF常用工具汇总
- windows2008服务器监控管理软件
- python调用stitcher类进行图像拼接融合
- svg文件保存成svg图片并通过cairosvg库转换png图片
- 直流稳压电源的整流电路详解
- JFreeChart在Struts2中实现3D柱状图统计