【毕业设计】基于超声波与红外的自动调速风扇系统(代码开源) -物联网 嵌入式 stm32
文章目录
- 1 简介
- 1 设计概要
- 2 系统设计
- 2.1 系统供电问题
- 2.2 自动/手动模式的切换
- 2.3 PWM信号的产生
- 2.4 单片机内部资源的分配
- 三、硬件搭建
- 3.1 单片机最小系统
- 3.2 电机驱动模块
- 3.3 超声波测距模块
- 3.4 红外遥控模块
- 3.5 液晶显示模块
- 3.6 供电模块
- 4 工程代码(全开源)
- 4.1 总头文件
- 4.2 电机驱动及头文件
- 4.3 超声波驱动及头文件
- 4.4 红外遥控驱动及头文件
- 4.5 液晶显示驱动及头文件
- 4.6 延时函数及头文件
- 4.7 主函数
- 5 最后
1 简介
Hi,大家好,这里是丹成学长,今天向大家介绍一个 单片机项目,大家可用于 课程设计 或 毕业设计
基于超声波与红外的自动调速风扇系统
单片机-嵌入式毕设选题大全及项目分享:
https://blog.csdn.net/m0_71572576/article/details/125409052
1 设计概要
本系统为基于红外和超声波的手动/自动调速风扇系统,风扇转速的调节模式可分为自动模式与手动模式:在自动模式下,由超声波检测人与风扇的距离,根据距离调节风扇转速;在手动模式下,可通过红外遥控的按键调节风扇转速。相应参数信息通过LCD液晶显示屏显示。本系统的主控芯片采用STC89C52单片机,测距采用HC-SR04超声波模块,风扇电机由L298N电机驱动模块驱动,遥控部分用传统的红外遥控器,显示部分用LCD1602液晶显示屏。电机驱动模块采用12V供电,单片机及其他各部分采用5V供电。
2 系统设计
2.1 系统供电问题
STC89C52单片机及超声波传感器、红外遥控接收头、液晶显示屏均为+5V标准供电,可以直接使用电脑USB接口引出电压。但考虑到电机用到PWM调速,需要大电压和大电流,因此决定使用电池盒额外供电。
2.2 自动/手动模式的切换
主函数内部用一个while大循环,超声波数据采集及电机驱动等程序均放在循环内部。在while内部有两段程序,一段为手动模式,一段为自动模式,分别放在if…else…的两个分支内。定义全局变量flag,在红外遥控中断内部可改变flag的值,通过flag的值控制if…else…选择结构的走向,进而实现两种模式的切换。
2.3 PWM信号的产生
电机转速调节需用到PWM信号,需由单片机内部产生。有两种可行方案:其一为通过软件延时,不断地改变某一引脚电平的高低,由该引脚向外输出PWM信号;其二为通过中断计时,计满后进入中断服务程序,在中断服务程序中改变某一引脚电平的高低,由该引脚向外输出PWM信号。考虑到系统较为复杂,用方案一在时间上会占用单片机的大量资源,影响到系统的稳定性和实时性,因此采用方案二。
2.4 单片机内部资源的分配
在本系统中,用到两个定时器和两个中断:超声波测距时等待返回波用到一个定时器,控制PWM信号的发生用到一个定时器;红外遥控的响应用到一个外部中断,PWM信号的发生用到定时器中断。考虑到系统的实时性,给红外遥控分配优先级最高的外部中断0,PWM信号发生使用定时器T0并开中断,超声波测距使用定时器T1,不开中断。
三、硬件搭建
由于硬件部分中的很多模块在仿真软件中都没有,且各模块之间的连接关系比较简单,因此在这里不提供电路图,仅用语言描述各引脚之间的连接关系。
3.1 单片机最小系统
对51 系列单片机来说, 最小系统一般应该包括: 单片机、时钟电路、复位电路、输入/ 输出设备等。最小系统的焊接有一套标准的流程,为基本功,这里不做赘述。
3.2 电机驱动模块
本系统电机驱动模块使用常见的L298N电机驱动模块。L298N芯片可以驱动两个二相电机,也可以驱动一个四相电机,输出电压最高可达50V,可以直接通过电源来调节输出电压;可以直接用单片机的IO口提供信号;而且电路简单,使用比较方便。
在本系统中,只使能了EnA来驱动一个电机,其中EnA接单片机引脚P20,IN1接P21,IN2接P22。L298N电机驱动模块实物图如下所示:
3.3 超声波测距模块
在自动调速模式下,需用到超声波模块采集距离信息。本系统采用HC-SR04超声波模块, HC-SR04超声波测距模块可提供2cm-400cm的非接触式距离感测功能,测距精度可达高到3mm;模块包括超声波发射器、接收器与控制电路。基本工作原理:
(1)采用I0口TRIG触发测距,给至少10us的高电平信号;
(2)模块自动发送8个40khz的方波,自动检测是否有信号返回;
(3)有信号返回,通过I0口ECHO输出一个高电平,高电平持续的时间就是超声往返所用的时间。
(4)根据声音在空气中的速度为344米/秒,即可计算出所测的距离。
在本系统中,超声波模块的Trig脚接单片机引脚P36,Echo脚接单片机引脚P22。HC-SR04工作时序图如下所示:
3.4 红外遥控模块
根据使用的编码芯片不同,红外遥控编码的格式也不同,较普遍的有NEC标准和PHILIPS标准。最常用的是NEC标准,本系统采用的也是NEC标准。
NEC标准:遥控载波的频率为38KHz(占空比1:3)当某个键按下时,发射端首先发射一个完整的全码,如果按键超过108ms仍未松开,接下来发射的代码(连发代码)将由起始码(9ms)和结束码(2.5ms)组成,并每隔108ms重复。
一个完整的全码由引导码、用户码、用户码、数据码、数据码以及数据反码共同组成。其中,引导码高电平9ms,低电平4.5ms;系统码8位,数据码8位,共32位;其中前16位为用户识别码,能区别不同的红外遥控设备,以防止不同的机种遥控码互相干扰。后16位为8位的操作码和8位的操作反码,用于核对数据是否接收准确。收端根据数据码做出应该执行上面动作的判断。连发代码是在持续按键时发送的码。它告知接收端。某键是在被连续的按着。
NEC标准下的发射码表示:发射数据0时用“0.56ms高电平 + 0.565ms低电平 = 1.125ms”表示;发射数据1用“0.56ms高电平 + 1.69ms低电平 = 2.25ms”表示。
在本系统中,红外接收器的INIR脚接单片机引脚P32。NEC标准完整码组成及NEC标准发射码如下所示:
3.5 液晶显示模块
本系统的液晶显示部分采用LCD1602液晶显示屏。1602液晶也叫1602字符型液晶,它是一种专门用来显示字母、数字、符号等的点阵型液晶模块 它有若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符。每位之间有一个点距的间隔,每行之间也有也有间隔,起到了字符间距和行间距的作用。
LCD1602是指显示的内容为16X2,即可以显示两行,每行16个字符液晶模块(显示字符和数字)。目前市面上字符液晶绝大多数是基于HD44780液晶芯片的,控制原理是完全相同的,因此基于HD44780写的控制程序可以很方便地应用于市面上大部分的字符型液晶。
在本系统中,液晶显示屏接法如下所示:
3.6 供电模块
为了驱动电机,需采用+12V供电,结合手上现有资源,决定采用4节3.7V的锂电池串联供电。串联后的输出电压在+15V左右,使用LM2596S直流降压模块,将电压降至+12V后提供给电机驱动模块L298N,单片机所需的+5V电可直接从电机驱动模块中引出。
4 工程代码(全开源)
代码用C语言编写,在Keil5环境下开发的。给每个模块都写了驱动,每个模块的驱动拿出后略加改动,都能单独使用。代码工程结构如下所示:
4.1 总头文件
把常用的宏定义和硬件的引脚连接定义到了reg52.h里面,更名为my52.h。所以整个工程代码中每个文件都#include "my52.h"而不是 #include “reg52.h”。
#ifndef __MY52_H__
#define __MY52_H__/* BYTE Registers */
sfr P0 = 0x80;
sfr P1 = 0x90;
sfr P2 = 0xA0;
sfr P3 = 0xB0;
sfr PSW = 0xD0;
sfr ACC = 0xE0;
sfr B = 0xF0;
sfr SP = 0x81;
sfr DPL = 0x82;
sfr DPH = 0x83;
sfr PCON = 0x87;
sfr TCON = 0x88;
sfr TMOD = 0x89;
sfr TL0 = 0x8A;
sfr TL1 = 0x8B;
sfr TH0 = 0x8C;
sfr TH1 = 0x8D;
sfr IE = 0xA8;
sfr IP = 0xB8;
sfr SCON = 0x98;
sfr SBUF = 0x99;/* 8052 Extensions */
sfr T2CON = 0xC8;
sfr RCAP2L = 0xCA;
sfr RCAP2H = 0xCB;
sfr TL2 = 0xCC;
sfr TH2 = 0xCD;/* BIT Registers */
/* PSW */
sbit CY = PSW^7;
sbit AC = PSW^6;
sbit F0 = PSW^5;
sbit RS1 = PSW^4;
sbit RS0 = PSW^3;
sbit OV = PSW^2;
sbit P = PSW^0; //8052 only/* TCON */
sbit TF1 = TCON^7;
sbit TR1 = TCON^6;
sbit TF0 = TCON^5;
sbit TR0 = TCON^4;
sbit IE1 = TCON^3;
sbit IT1 = TCON^2;
sbit IE0 = TCON^1;
sbit IT0 = TCON^0;/* IE */
sbit EA = IE^7;
sbit ET2 = IE^5; //8052 only
sbit ES = IE^4;
sbit ET1 = IE^3;
sbit EX1 = IE^2;
sbit ET0 = IE^1;
sbit EX0 = IE^0;/* IP */
sbit PT2 = IP^5;
sbit PS = IP^4;
sbit PT1 = IP^3;
sbit PX1 = IP^2;
sbit PT0 = IP^1;
sbit PX0 = IP^0;/* P3 */
sbit RD = P3^7;
sbit WR = P3^6;
sbit T1 = P3^5;
sbit T0 = P3^4;
sbit INT1 = P3^3;
sbit INT0 = P3^2;
sbit TXD = P3^1;
sbit RXD = P3^0;/* SCON */
sbit SM0 = SCON^7;
sbit SM1 = SCON^6;
sbit SM2 = SCON^5;
sbit REN = SCON^4;
sbit TB8 = SCON^3;
sbit RB8 = SCON^2;
sbit TI = SCON^1;
sbit RI = SCON^0;/* P1 */
sbit T2EX = P1^1; // 8052 only
sbit T2 = P1^0; // 8052 only/* T2CON */
sbit TF2 = T2CON^7;
sbit EXF2 = T2CON^6;
sbit RCLK = T2CON^5;
sbit TCLK = T2CON^4;
sbit EXEN2 = T2CON^3;
sbit TR2 = T2CON^2;
sbit C_T2 = T2CON^1;
sbit CP_RL2 = T2CON^0;/*------------------一下为添加部分---------------------*/#define uint unsigned int
#define uchar unsigned char#define HighGear 4
#define MiddleGear 3
#define LowGear 2//电机驱动
sbit ENA = P2^0; //PWM输入端口
sbit IN1 = P2^1; //0
sbit IN2 = P2^2; //1//超声波
sbit Trig=P3^6;
sbit Echo=P3^7;//LCD1602
sbit RS=P1^2; // 数据/命令选择端(H/L)
sbit RW=P1^1; //读写选择端(H/L)
sbit E=P1^0; //使能信号//红外遥控
sbit IRIN=P3^2;// 红外接收器端口定义,外部中断0优先级最高#endif
4.2 电机驱动及头文件
电机驱动文件motor_driver.c:
#include "my52.h"uchar motor_gear,pwm_num;void motor_run(uchar gear)
{motor_gear = gear; //挡位设置,分2,3,4档TMOD = 0x11; //设置定时器1为工作方式1TH1 = (65536-100)/256; //装初值,每0.1ms中断一次TL1 = (65536-100)%256;ET1 = 1; //开定时器1中断TR1 = 1; //启动定时器1
}void T1_PWM() interrupt 3
{TH1 = (65536-100)/256; //装初值TL1 = (65536-100)%256;pwm_num++;if(pwm_num == 5)pwm_num = 0;if(pwm_num <= motor_gear)ENA = 1;elseENA = 0;
}
电机驱动头文件motor_driver.h
1 #ifndef __MOTOR_DRIVER_C__
2 #define __MOTOR_DRIVER_C__
3 extern motor_run(uchar gear); //可填2,3,4,占空比分别为0.6,0.8,1
4 #endif
4.3 超声波驱动及头文件
超声波驱动文件sr04_driver.c:
#include "my52.h"
#include "motor_driver.h"
#include <intrins.h> // _nop_()延时extern uchar InfraredGear;uint distance() //HC-SR04超声波测距模块工作函数
{uint dis = 0;uint time = 0;uchar i = 10;Trig = 0;//初始化Echo = 0;TMOD = 0x11;TH0=0;//给T0装初值0TL0=0;Trig = 1;while(i--)_nop_();while(Echo==0);TR0=1;//启动T0while(Echo==1);//等待返回信号的接收完毕time=TH0*256+TL0;//微秒dis=(time*1.7+5)/10;//340米每秒即0.34毫米每微秒,1.7=0.34/2×10,来回除2,四舍五入先乘10TR0=0;//关闭T0return dis;
}void sr04_motor(uint dist)
{if(dist <= 300)InfraredGear = LowGear;else if(dist > 600)InfraredGear = HighGear;elseInfraredGear = MiddleGear;
}
超声波驱动头文件sr04_driver.h:
4.4 红外遥控驱动及头文件
红外遥控驱动文件infrared_driver.c:
#include "my52.h"
#include "delay.h"extern uchar InfraredGear;
extern uchar Flag ;uchar IrValue[4];//两位用户码,一位数据码,一位数据反码
uchar num;void read() interrupt 0{//红外中断读取档位数据uchar j,k,t;uint i;num=0;t=IrValue[2];delay_ms(7);//起始码前9ms为低电平,在这里等待7msif(IRIN==0){//确认真的收到信号后执行以下程序i=1000; //如果出错利用i跳出以下等待,以免程序在这里死循环while((IRIN==0)&&(i>0)){ //等待前9ms结束delay_10us(1);i--;}if(IRIN==1){//起始码前9ms结束,后4.5ms为高电平i=500; //用i防止死循环while((IRIN==1)&&(i>0)){//等待起始码的后4.5ms高电平delay_10us(1);i--;}for(k=0;k<4;k++){//2个用户码,1个数据码,1个数据反码,共4个字节for(j=0;j<8;j++){ //每个字节8位,以下程序用于确定每位电平的高低i=60;while((IRIN==0)&&(i>0)){//等待0.56ms的低电平,每位前面都有0.56ms的低电平delay_10us(1); //后面高电平0.565ms(565us)为0, 1.69ms(1690us)为1i--;}i=500;while((IRIN==1)&&(i>0)){//低电平结束,高电平到来后进入,用于计算高电平持续时间delay_10us(10);//延时100usnum++;i--;if(num>30){//超出3000us(3ms),本程序出错(最大不能超过2.25ms),返回主调函数return;}}IrValue[k]>>=1;//腾出最高位用于接收本位数据if(num>=8){//高电平持续时间大于800us,该位为1IrValue[k]|=0x80; //给最高位写1}num=0; //计数变量清零}}}if(IrValue[2]!=~IrValue[3]){//数据位校验IrValue[2]=t;return;}}if(IrValue[2]==69)InfraredGear=LowGear;else if(IrValue[2]==70)InfraredGear=MiddleGear;else if(IrValue[2]==71)InfraredGear=HighGear;else if(IrValue[2]==68) //切换自动模式Flag = 0;else if(IrValue[2]==67) //切换手动模式Flag = 1;else if(IrValue[2]==64) //急停IN1 = 1;else if(IrValue[2]==21)IN1 = 0;
}
红外遥控驱动头文件infrared_driver.h
1 #ifndef __INFRARED_DRIVER_C__
2 #define __INFRARED_DRIVER_C__
3
4 #endif
4.5 液晶显示驱动及头文件
液晶显示驱动文件lcd1602_driver.c:
#include "my52.h"extern uchar InfraredGear;void delays(uint i)
{uchar j;while(i--)for(j=50;j>0;j--);
}
void write_com(uchar com)
{RS=0;P0=com;delays(1);E=1;delays(1);E=0;
}
void write_date(uchar date)
{RS=1;P0=date;delays(1);E=1;delays(1);E=0;
}
void lcdinit()
{RW=0;E=0;write_com(0x38); //设置16X2显示,5X7点阵,8位数据接口write_com(0x0c); //设置开显示,不显示光标write_com(0x06); //写一个字符后地址指针加1write_com(0x01); //显示清零,数据指针清零
}void display0(uint dis) //手动调速下1602显示
{uchar g1,g2,g3,g4;g1=dis%10;g2=(dis/10)%10;g3=(dis/100)%10;g4=dis/1000;lcdinit();write_com(0x80);write_date('M');write_date('o');write_date('d');write_date('e');write_date('l');write_date(':');write_date('A');write_date('U');write_date('T');write_date('O');write_date(' ');//挡位显示write_date(0x30+InfraredGear-1);write_com(0x80+0x40);//换行显示write_date('D');//距离显示write_date('i');write_date('s');write_date(':');write_date(0x30+g4);write_date(0x30+g3);write_date(0x30+g2);write_date(0x30+g1);write_date('m');write_date('m');
}void display1()
{lcdinit();write_com(0x80);write_date('M');write_date('o');write_date('d');write_date('e');write_date('l');write_date(':');write_date('M');write_date('A');write_date('N');write_date('U');write_date(' ');//挡位显示write_date(0x30+InfraredGear-1);
}
液晶显示驱动头文件lcd1602_driver.h:
#ifndef __LCD1602_DRIVER_C__
#define __LCD1602_DRIVER_C__
extern void delays(uint i);
extern void write_com(uchar com);
extern void write_date(uchar date);
extern void lcdinit();
extern void display0(uint dis);
extern void display1();
#endif
4.6 延时函数及头文件
延时函数所在文件delay.c:
#include "my52.h"void delay_ms(uint t)
{uint i,j;for(i=0;i<t;i++)for(j=0;j<114;j++);
}void delay_10us(uint t) //延时函数,t=1延时10us
{while(t--);
}
4.7 主函数
#include "my52.h"
#include "motor_driver.h"
#include "sr04_driver.h"
#include "delay.h"
#include "lcd1602_driver.h"
#include "infrared_driver.h"uchar InfraredGear = LowGear;//手动调节挡位,红外驱动文件中改变该值
uchar Flag = 0;//自动0/手动1模式void main()
{uint dis;ENA = 1;IN1 = 0;IN2 = 1;EA = 1;//开总中断EX0 = 1; //开外部中断0,接收红外信号while(1){if(Flag == 0) //自动{dis = distance(); //超声波测距sr04_motor(dis); //根据距离调节挡位motor_run(InfraredGear);display0(dis); //液晶显示delay_ms(100); //延时,每100ms更新一次数据}else{motor_run(InfraredGear); //手动调节转速display1(); //液晶显示delay_ms(100); //延时,每100ms更新一次液晶内容}}
}
单片机-嵌入式毕设选题大全及项目分享:
https://blog.csdn.net/m0_71572576/article/details/125409052
5 最后
【毕业设计】基于超声波与红外的自动调速风扇系统(代码开源) -物联网 嵌入式 stm32相关推荐
- 毕业设计 超声波红外自动调速风扇系统
文章目录 1 简介 1 设计概要 2 系统设计 2.1 系统供电问题 2.2 自动/手动模式的切换 2.3 PWM信号的产生 2.4 单片机内部资源的分配 三.硬件搭建 3.1 单片机最小系统 3.2 ...
- 基于Arduino的自动调速风扇
好久没有更新了,家里实在太乱,最近趁着618活动,买了一堆收纳抽屉和置物架,把家里彻底收拾了一下,然后客厅就成了这个奇葩样子,注孤生的节奏了. 话不多说,夏天到了,天气逐渐热起来,风扇成了必不可少的消 ...
- 单片机毕设 人体定位智能调速风扇系统
文章目录 0 前言 1 主要功能 2 硬件设计 3 核心软件设计 4 实现效果 5 最后 0 前言
- 物联网毕设 人体定位智能调速风扇系统
文章目录 0 前言 1 主要功能 2 硬件设计 3 核心软件设计 4 实现效果 5 最后 0 前言
- 嵌入式毕设分享 人体定位智能调速风扇系统
文章目录 0 前言 1 主要功能 2 硬件设计 3 核心软件设计 4 实现效果 5 最后 0 前言
- stm32毕设分享 人体定位智能调速风扇系统
文章目录 0 前言 1 主要功能 2 硬件设计 3 核心软件设计 4 实现效果 5 最后 0 前言
- matlab建模电风扇,关于matlab调速风扇
关于matlab调速风扇0 代码如下 clear speed = 100; t = 0; Y_a = 4;Y_b = 4;Y_c = 4; y0 = figure; axis equal;axis o ...
- 基于51的多功能小风扇,可以实现定时,摇头,超声波自动调速等功能
最近也是想加入一个实验室,考核题目就是写一个小风扇!下面是题目要求 由于我也是大一新生,也就自学了一点51和c语言知识,代码写的可能有点拙,还请多多指教! #include <REGX52.H& ...
- 电机调速设计并用matlab仿真,终稿毕业论文设计_基于PWM控制的直流电动机调速系统设计及MATLAB仿真.doc最终版(备份存档)...
<毕业论文_基于PWM控制的直流电动机调速系统设计及MATLAB仿真.doc>由会员分享,可免费在线阅读全文,更多与<(终稿)毕业论文设计_基于PWM控制的直流电动机调速系统设计及M ...
最新文章
- 作弊阴影罩棋盘,人工智能咋避嫌?
- PHP安装zip拓展,以及libzip安装问题
- php memcached mysql_PHP Memcached使用详解
- 系统架构师学习笔记_第十四章_连载
- 谁知道这个代码片段干嘛的
- 文件已经上传到服务器翻译,服务器接受上传的优化 翻译+源码分析
- xml能存图片吗_如何Get大量的图片搜索流量?(分享几大Image SEO技巧!)
- 阿里小蜜多模态知识图谱的构建及应用
- [设计模式-行为型]中介者模式(Mediator)
- 押错宝!一次性将百万行代码从 Flow 迁移至 TypeScript
- 无约束最优化(三) 拟Newton法
- vue轮播插件vue-awesome-swiper
- php算法复杂度,php的几个经典排序算法及时间复杂度和耗时​
- 2018年wine QQ最完美解决方案(多Linux发行版通过测试并稳定运行)
- KL散度、JS散度和交叉熵
- SecureCRT创建串口连接
- 4G物联网卡使用记录——使用方法及被锁卡处理
- 用Python统计字符串个数
- 最小圆覆盖问题 算法步骤与证明+代码模板
- 英语 译林 2019 单词表
热门文章
- Scratch软件编程等级考试四级——20210626
- 获取滑动条位置,动态调整对话框显示位置;为动态添加的button添加click事件
- AR行业报告:甩掉VR,5年内AR将迎来大爆发 | 报告
- 人工与软件刷流量有什么区别,如何做刷流量效果才最好?
- pycharm设置字体样式_Pycharm IDE设置系列教程(三):配置颜色和字体
- php调试加密代码,使用bcompiler对PHP文件进行加密的代码
- 魔改车钥匙实现远程控车:(1)整体思路及控制方案实现
- asp html表单没有csrf保护,ASP.NET MVC 和网页中的 XSRF/CSRF 防护
- Linux 如何给新加的硬盘重新添加分区(纯新手)
- 【DP】西北大学集训队选拔赛(重现赛) B 饱和式救援