当前位置: 首页 > backend >正文

7.DTH11和PWM波

目录

室内/本地温湿度检测

温湿度传感器介绍

获取手册和例程的方法

从手册中提取重要信息

传感器的分类

温度传感器类型

DHT11 的介绍

温湿度传感器的接口

温湿度传感器的时序

温湿度传感器电路介绍

IO 的配置

定时器输出 PWM 波

PWM 波介绍

PWM 波的作用:

基本定时器知识

输出 PWM 波

通用定时器输出 PWM 波

PWM 波相关的硬件

PWM 波代码实现

代码


室内/本地温湿度检测 

温湿度传感器介绍

        获取温度和湿度 -- DHT11 

获取手册和例程的方法

找厂家官网  立创商城

从手册中提取重要信息

        供电: 

                接口:常见的接口

        数字接口:串口 单总线 IIC SPI CAN 

        模拟接口:ADC 

        协议数据格式:有了物理层,如何确定能够通信上,获取数据

传感器的分类

        数字接口的传感器: 

                串口 单总线 IIC SPI CAN 这些接口一般都是数字接口的传感器 

        模拟接口的传感器: 

                电压接口或者电流接口这种叫做模拟接口传感器,采集模拟接口的传感器就需要用 ADC 

温度传感器类型

        常见的温度传感器(热敏电阻)-PT100 NTC1000

        NTC 和 PTC 一个是正温度系数,一个是负温度系数,正温度系数 温度越高,电阻越大,负温度系数,温度越高,电阻越小

DHT11 的介绍

 

温湿度传感器的接口

温湿度传感器的时序

        主从结构:主机主动发送,从机被动回复,从机不能主动发送数据 

温湿度传感器电路介绍

IO 的配置

        (1)配置成开漏输出 

                开漏只能输出低电平,通过上拉电阻实现高电平,空闲的时候(双方都不拉低的时候)就是高电平 

        (2)配置成通用推挽输出和浮空输入两种模式切换 

                主机控制部分,配置成通用推挽输出

                从机控制部分,配置成浮空输入 

定时器输出 PWM 波

PWM 波介绍

        PWM 波 -- 脉宽可调制波形 

        脉宽:指高电平持续的时间 

        占空比:一个周期内 高电平的时间占总周期的的百分比 

PWM 波的作用:

        1. 呼吸灯 

                本质上是快速的亮灭在切换,人眼有视觉暂留,区分不出来 

                相同周期内亮灭的时间不一致,人眼能察觉出来亮度不一样 

        2. 电机调速 

                和呼吸灯的原理是一样的 

                呼吸灯和电机调速都是惯性系统(不会立马停止) 

        3. 通信 -- 抗干扰能力比较强 

                电动汽车充电桩里面 和 舵机 

                27% 3.5KW 

                54% 7KW 

                舵机 不同占空比转动不同的角度 

        4. 输出 0--到 Vmax 之间的任意电压

                 面积等效原理 

                设备没有 2.5V 的电源,想实现 2.5V 的电压输出,就用上面的面积等效方法。就可以输出 0--5V 的任意电压,这个功能叫做 DAC(数字量转换模拟量)

基本定时器知识

        系统(滴答)定时器 -- systick -- 内核 ARM 公司 

        基本定时器 -- TIM6 TIM7 -- 只有基本的定时器功能

        通用定时器 -- TIM2 TIM3 TIM4 TIM5 -- 基本定时器功能+PWM+输入捕获 

        高级定时器 -- TIM1 TIM8 -- 通用定时器的基础上 + 死区 +刹车(电机使用) 

        窗口看门狗 独立看门狗 RTC --本质上都是定时器 

        看门狗防止程序跑飞 

        时基单元 

        外设时钟的频率 所有的定时器都是 F=72M 

        预分频值 PSC 

        分频之后的计数的频率(CK_CNT) f=F/PSC 

        计一次数(更新 1 次数)的时间 t=1/f 

        重装载值 ARR 

        计数的周期 T= ARR*t=ARR*PSC/F 

输出 PWM 波

        (1) 定时器 + 手动 IO 翻转 

                比较值 30 

                重装载值 99 

                向上计数 

                当计数值<比较值 IO 口输出高电平 

                当计数值>比较值 IO 口输出低电平 

                注意:自己比较,IO 配置成通用推挽输出 

        (2) 带 PWM 波功能的通用定时器 

                比较值 30 

                重装载值 99 

                向上计数 

                当计数值<比较值 IO 口输出高电平 

                当计数值>比较值 IO 口输出低电平 

                注意:通过定时器的 PWM 外设自动比较,IO 配置成复用推挽输出

通用定时器输出 PWM 波

        基本定时器:没有 PWM 输出的功能,需要手动翻转 IO 口输出 PWM 

        重装载值和预分频值决定 PWM 频率和周期

        比较值和重装载值决定占空比 

        根据上图可得,每个通用(或者高级)定时器有 4 个 PWM 的输出端口,4 个通道周期是一致的,但是比较值(占空比)可以不一致 

        TIM6 和 TIM7 只有向上计数,其他定时器可以选择,向上计数,向下计数和中央对齐模式 

 

重点关注: 

        ARR 100(TIMx_ARR) 比较值 66(TIMx_CCR ) 

        PWM 模式 (TIMx_CCMRx 位 6:4)有效电平(TIMx_CCER 位 CCxP 位 1) 

PWM1 有效电平是高电平

        向上计数 0—66 输出有效电平(高电平) 66—100 输出无效电平(低电平) 占空比 CCR/ARR 

        向下计数 100—66 输出无效电平(低电平) 66—0 输出有效电平(高电平) 占空比 CCR/ARR 

PWM1 有效电平是低电平

        向上计数 0—66 输出有效电平(低电平) 66—100 输出无效电平(高电平) 占空比 (ARR-CCR)/ARR 

        向下计数 100—66 输出无效电平(高电平) 66—0 输出有效电平(低电平) 占空比 (ARR-CCR)/ARR 

PWM2 有效电平是高电平

PWM2 有效电平是低电平

        注意: CCR/ARR 并不一定是占空比,取决于 PWM 模式和有效电平,如果想 CCR/ARR 就是占空比,应该选择 PWM1,有效电平高电平或者 PWM2,有效电平低电平 

PWM 波相关的硬件

        LED1—LED4 所接的引脚,没有 TIMx_Chy 的标识,无法使用定时器的 PWM 功能,但是可以通过手动翻转 IO 控制 LED 灯亮度 

        RGB 接的引脚标识 TIMx_Chy,所以可以使用 TIM 的 PWM 功能

PWM 波代码实现

需要配置的结构体

        GPIO 模式

TIM

        决定了 PWM 波的周期和频率 

输出 PWM 有关的结构体 

        决定了 PWM 波的占空比

代码

DHT11

void DHT11_Config(void)
{//1.开G端口时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE);//2.定义结构体 xxx需要传递结构体地址GPIO_InitTypeDef GPIO_InitStruct = {0};//3.给结构体赋值GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;//代配置引脚GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;//通用开漏GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;//引脚速率GPIO_Init(GPIOG, &GPIO_InitStruct);//先释放总线,因为刚开始就是高电平,不拉低GPIO_SetBits(GPIOG,GPIO_Pin_11);
}uint8_t DHT11_Handle(void)
{uint8_t Time_out = 0;uint8_t i,j;uint8_t Buff[5]={0};uint8_t Data_Cs=0;//和校验//主机先拉低 位置1GPIO_ResetBits(GPIOG,GPIO_Pin_11);Delay_ms(18);//释放总线 位置2GPIO_SetBits(GPIOG,GPIO_Pin_11);//等待响应信号的低电平部分,低电平没到来之前一直是高电平while(GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_11)==Bit_SET){//还未等到响应信号的低电平Time_out++;Delay_us(1);if(Time_out>=100){//设备异常,响应失败,应答失败return 0;}}//等到响应信号低电平,然后时序到拉高准备输出,高电平没到来前一直是低电平 位置3Time_out=0;while(GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_11)==Bit_RESET){//还未等到响应信号的高电平Time_out++;Delay_us(1);if(Time_out>=100)//传感器总线先拉低{//100us中有83us是响应信号的低电平,剩下17us等待响应信号高电平,如果17秒没等到,设备异常返回return 0;}}for(i=0;i<5;i++){//5次for(j=0;j<8;j++){//一次8位Time_out=0;//刚等到响应信号的高电平,等待数据位的低电平部分,数据位低电平没有到来之前,一直是高电平,位置4while(GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_11)==Bit_SET){//还未等到响应信号的高电平Time_out++;Delay_us(1);if(Time_out>=100)//在拉高以 响应主机的起始信号{//100us中有87us是响应信号的高电平,剩下13us等待响应信号低电平,如果13秒没等到,设备异常返回return 0;}}Time_out=0;//刚等到数据位的低电平,等待数据位的高电平部分,数据位高电平没有到来之前,一直是低电平,位置5while(GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_11)==Bit_RESET){//还未等到响应信号的高电平Time_out++;Delay_us(1);if(Time_out>=100){//100us中有54us是响应信号的低电平,剩下46us等待响应信号高电平,如果46秒没等到,设备异常返回return 0;}}//刚等到数据位的高电平,延时30us,去区分收到的数据是0还是1,到位置6Delay_us(30);if((GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_11)==Bit_RESET)){//数据0,高位先发Buff[i] &= ~(0x01<<(7-j));		}else{//数据1,高位先发Buff[i] |= (0x01<<(7-j));}}}Data_Cs=Buff[0]+Buff[1]+Buff[2]+Buff[3];if(Data_Cs==Buff[4]){//校验正确if((Buff[3] & 0x80) == 0) //0001 1000{//正温Dht.Tem = (Buff[2]+(Buff[3] & 0x7F) * 0.1);}else{//负温Dht.Tem = - (Buff[2]+(Buff[3] & 0x7F) * 0.1);}Dht.Hum = Buff[0];printf("温度=%.1f ,湿度=%d\r\n", Dht.Tem, Dht.Hum);return 1;}else{printf("DHT11校验不正确\r\n");return 0;}return 0;
}

PWM

void PWM_Config(void)
{//1.开A端口时钟  //方法1:中文固件库手册 15.2.22  路径:授课大纲资料\1.项目分析与环境搭建\资料\芯片相关资料//方法2:找到对应的.h文件最下面   stm32f10x.h 693行RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//2.定义结构体  XXX_init需要传递结构体变量地址GPIO_InitTypeDef GPIO_InitStruct={0};//3.给结构体赋值  中文固件库手册,Table 182--Table 185GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//浮空输入GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_7|GPIO_Pin_6;//待配置的引脚GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;//引脚速率//4.调用XXX_Init函数,将参数写入到寄存器中//void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);	//中文固件库手册:10.2.3//stm32f10x_gpio.h  351行GPIO_Init(GPIOA,&GPIO_InitStruct);	//5.开TIM3的时钟//void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); stm32f10x_rcc.h  693行//void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);//6.定义结构体   XXX_Init函数    void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct={0};//7.给结构体赋值
//	TIM_TimeBaseInitStruct.TIM_ClockDivision = //时钟分割 输入捕获才使用TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; //计数模式,向上或者向下TIM_TimeBaseInitStruct.TIM_Period = TIM_ARR_Value-1;//重装载值TIM_TimeBaseInitStruct.TIM_Prescaler = 720-1;//预分频值
//	TIM_TimeBaseInitStruct.TIM_RepetitionCounter	//该参数只用在高级定时器,晚上作业也不用配置//8.调用XXX_Init函数将参数写入到寄存器中TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);	TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStruct);			//9.使能定时器   参考手册15.4.1  的位0置1
//void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);	 stm32f10x_tim.h 1067行TIM_Cmd(TIM3,ENABLE);	TIM_Cmd(TIM1,ENABLE);//10.定义PWM波相关的结构体
//具体用哪个函数,取决于CHx编号
//void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);	TIMx_CH1	 stm32f10x_tim.h 1057行 
//void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); TIMx_CH2
//void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); TIMx_CH3
//void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); TIMx_CH4TIM_OCInitTypeDef TIM_OCInitStruct={0};//11.给结构体赋值TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;  //PWM模式1TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; //有效电平高电平TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;  //输出使能TIM_OCInitStruct.TIM_Pulse = 66;//比较值 范围0--ARR之间
//	TIM_OCInitStruct.TIM_OCIdleState	//只用在高级定时器 TIM1 TIM8
//	TIM_OCInitStruct.TIM_OutputNState	//只用在高级定时器 TIM1 TIM8
//	TIM_OCInitStruct.TIM_OCNIdleState //只用在高级定时器 TIM1 TIM8
//	TIM_OCInitStruct.TIM_OCNPolarity	//只用在高级定时器 TIM1 TIM8//12.根据要设置的通道,调用对应的init函数,将参数写入寄存器TIM_OC1Init(TIM3,&TIM_OCInitStruct);TIM_OC2Init(TIM3,&TIM_OCInitStruct);	TIM_OC1Init(TIM1,&TIM_OCInitStruct);//13.使能ARR预装载功能
//void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);	 stm32f10x_tim.h 1092行 TIM_ARRPreloadConfig(TIM3,ENABLE);TIM_ARRPreloadConfig(TIM1,ENABLE);//14.使能比较值的预装载功能
//void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);  stm32f10x_tim.h 1096行 TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable);TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);//15.高级定时器的PWM波功能加上这句话
//void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState);  stm32f10x_tim.h 1068行 TIM_CtrlPWMOutputs(TIM1,ENABLE);
}
http://www.xdnf.cn/news/6125.html

相关文章:

  • React系列——nvm、node、npm、yarn(MAC)
  • 机器学习第十讲:异常值检测 → 发现身高填3米的不合理数据
  • Spring 事件监听机制的使用
  • flatbuffer实践
  • 操作系统实验 实验3 存储器分配与回收
  • 设计模式-中介者模式
  • Docker使用经验-从Image导出dockerfile并进行修改
  • 【Elasticsearch】DSL 篇
  • 什么是alpaca 或 sharegpt 格式的数据集?
  • Windows电脑端高效记事提醒工具推荐
  • 【ios越狱包安装失败?uniapp导出ipa文件如何安装到苹果手机】苹果IOS直接安装IPA文件
  • SCDN能够运用在物联网加速当中吗?
  • Spring Web MVC————入门(2)
  • Spark处理过程--案例数据清洗
  • 大模型越狱:技术漏洞与安全挑战——从原理到防御
  • 正向代理与反向代理区别及应用
  • 威廉・巴拉德与格理集团:在高科技浪潮中的洞察与前行
  • 【极兔快递Java社招】一面复盘|数据库+线程池+AQS+中间件面面俱到
  • 【Linux网络】————详解TCP三次握手四次挥手
  • vue3:十三、分类管理-表格--slot插槽详细说明---表格内拼接字段、tag标签
  • 怎么查看当前vue项目,要求的node.js版本
  • Oracle — PL-SQL
  • JT/T 808 各版本协议字段级别对比与解析适配建议
  • NACOS基于长链接的⼀致性模型
  • 将navicat与parcharm链接
  • 2025年中国DevOps工具选型指南:主流平台能力横向对比
  • Go语言空白导入的作用与用途
  • 【SSL部署与优化​】​​如何为网站启用HTTPS:从Let‘s Encrypt免费证书到Nginx配置​​
  • 城市生命线综合管控系统解决方案-守护城市生命线安全
  • AWS CloudTrail日志跟踪启用