织梦系统如何做网站地图,自己做的网站怎么放视频教程,太原网站建设工作室,凡科做网站需要备案吗感应开关盖垃圾桶 1、PWM开发SG901.1、怎样通过C51单片机输出PWM波#xff1f;1.2、通过定时器输出PWM波来控制SG90 2、超声波测距模块的使用3、感应开关盖垃圾桶 需要材料#xff1a; 1、SG90舵机模块 2、HC-SR04超声波模块 3、震动传感器 4、蜂鸣器 5、若干杜邦线 1、PWM开… 感应开关盖垃圾桶 1、PWM开发SG901.1、怎样通过C51单片机输出PWM波1.2、通过定时器输出PWM波来控制SG90 2、超声波测距模块的使用3、感应开关盖垃圾桶 需要材料 1、SG90舵机模块 2、HC-SR04超声波模块 3、震动传感器 4、蜂鸣器 5、若干杜邦线 1、PWM开发SG90
PWM波为脉冲宽度调制对模拟信号电平进行数字编码。通过调节占空比的变化来调节信号。占空比高电平的时间/整个信号的周期。
1.1、怎样通过C51单片机输出PWM波
如果芯片内部模块能集成输出一般观察手册或者芯片IO口都会标明这个是否是PWM口 如果没有集成PWM功能可以通过IO口软件模拟
1.2、通过定时器输出PWM波来控制SG90 如图为SG90舵机模块黄色为PWM信号控制红色和褐色分别为VCC和GND。当输入的PWM的占空比不同的时候舵机模块的摆头幅度不同。一般情况如下
PWM波的频率不能太高大约50HZ即周期1/频率1/500.02s20ms左右 0.5ms-------------0度 2.5% 对应1/40 1.0ms------------45度 5.0% 对应2/40 1.5ms------------90度 7.5% 对应3/40 2.0ms-----------135度 10.0% 对应4/40 2.5ms-----------180度 12.5% 对应5/40
接下来通过C51单片机输出PWM波控制舵机的摆头黄线连接P1.1口代码如下
#include REGX52.Hsbit sg_90 P1^1;//黄线连接P1.1口
int cnt 0; //标志位
int jd; //占空比的分子void Delay300ms() //11.0592MHz
{unsigned char i, j, k;i 3;j 26;k 223;do{do{while (--k);} while (--j);} while (--i);
}void Delay2000ms() //11.0592MHz
{unsigned char i, j, k;i 15;j 2;k 235;do{do{while (--k);} while (--j);} while (--i);
}void Timer0_Init(void)
{TMOD 0x01;//配置定时器T0为16位定时器TL0 0x33; //定时器计1个数为1.085us则当舵机为0度的时候需要0.5ms, TH0 0xFE; //则定一个0.5ms的定时器TF0 0; //清除TF0标志TR0 1; //定时器0开始计时ET0 1;EA 1;
}void main(void)
{ Delay300ms();//给硬件准备时间Timer0_Init();jd 1;//一上电开始占空比为1/40为0度cnt 0;sg_90 1;//先给输出引脚一个高电平while(1){//角度由135度到0度来回摆动jd 4;cnt 0;Delay2000ms();jd 1;cnt 0;Delay2000ms();}
}void Timer0_Handler() interrupt 1//中断函数
{cnt;TL0 0x33; TH0 0xFE;//控制PWM波的占空比if(cnt jd){sg_90 1;}else{sg_90 0;}if(cnt 40){cnt 0;sg_90 1;}
}2、超声波测距模块的使用 怎么让它发送波 Trig 给Trig端口至少10us的高电平怎么知道它开始发了 Echo信号由低电平跳转到高电平表示开始发送波怎么知道接收了返回波 Echo由高电平跳转回低电平表示波回来了怎么算时间 Echo引脚维持高电平的时间 波发出去的那一下开始启动定时器。波回来的那一下我们开始停止定时器计算出中间经过多少时间。距离 速度 340m/s* 时间/2 /*通过超声波模块控制LED1灯的亮灭当手靠近超声波模块时灯亮*/
#include REGX52.Hsbit Trig P1^5;
sbit Echo P1^6;
sbit LED1 P3^7;void Delay10us() //11.0592MHz
{unsigned char i;i 2;while (--i);
}void Timer0_Init(void)
{TMOD 0x01;TL0 0;TH0 0;//设置定时器T0从0开始数数
}void Delay200ms() //11.0592MHz
{unsigned char i, j, k;i 2;j 103;k 147;do{do{while (--k);} while (--j);} while (--i);
}void main(void)
{double time;double dis;Timer0_Init();while(1){Delay200ms();//先给单片机准备时间//1、开始发波Trig 0;Trig 1;Delay10us();Trig 0;//2、检测ECHO引脚电平while(Echo 0);TR0 1; //启动定时器while(Echo 1);TR0 0; //关闭定时器//3、计算定时开到定时关的时间(计算数的个数)//2位二进制1101。合并位1101怎么算1101为(11*2^2)0113time (TH0 * 256 TL0) * 1.085; //us为单位//34000cm/s 34cm/ms 0.034cm/usdis time * 0.017; //cm为单位if(dis 10){LED1 0;}else{LED1 1;}TL0 0;TH0 0;//定时器清零以便下次测距}
}代码优化②
/**优化将定时器0改为定时器1然后将超声波测距封装成为一个函数*/
#include REGX52.Hsbit Trig P1^5;
sbit Echo P1^6;
sbit LED1 P3^7;void Delay10us() //11.0592MHz
{unsigned char i;i 2;while (--i);
}void Delay200ms() //11.0592MHz
{unsigned char i, j, k;i 2;j 103;k 147;do{do{while (--k);} while (--j);} while (--i);
}void Timer1_Init(void)
{//使用定时器1TMOD 0x0F;TMOD | 0x10;TL1 0;TH1 0;//设置定时器T1从0开始数数
}double get_distance()//超声波获得距离的函数
{double time;TL1 0;TH1 0;//定时器清零以便下次测距//1、开始发波Trig 0;Trig 1;Delay10us();Trig 0;//2、检测ECHO引脚电平while(Echo 0);TR1 1; //启动定时器while(Echo 1);TR1 0; //关闭定时器//3、计算定时开到定时关的时间(计算数的个数)//2位二进制1101。合并位1101怎么算1101为(11*2^2)0113time (TH1 * 256 TL1) * 1.085; //us为单位//34000cm/s 34cm/ms 0.034cm/usreturn (time * 0.017); //cm为单位;
}void main(void)
{double dis;Timer1_Init();while(1){Delay200ms();//先给单片机准备时间dis get_distance();if(dis 10){LED1 0;}else{LED1 1;}}
}3、感应开关盖垃圾桶
舵机和超声波代码整合舵机用定时器0超声波用定时器1。 1、实现物体靠近后自动开盖2秒后关盖。 2、查询的方式添加按键控制 3、 查询的方式添加震动控制
#include REGX52.Hsbit SW1 P2^1;//按键SW1连接的是P2.1口
sbit Trig P1^5;
sbit Echo P1^6;
sbit LED1 P3^7;
sbit sg_90 P1^1;//黄线连接P1.1口
sbit vibrate P3^2;//震动传感器连接P3.2口使用外部中断0int cnt 0; //标志位
int jd; //占空比的分子
int vib_mark; //震动传感器的标志位void Delay10us() //11.0592MHz
{unsigned char i;i 2;while (--i);
}void Delay200ms() //11.0592MHz
{unsigned char i, j, k;i 2;j 103;k 147;do{do{while (--k);} while (--j);} while (--i);
}void Delay2000ms() //11.0592MHz
{unsigned char i, j, k;i 15;j 2;k 235;do{do{while (--k);} while (--j);} while (--i);
}void EX0_Init()//触发中断0初始化
{EX0 1;EA 1;IT0 0;//低电平触发
}void Timer0_Init(void)//定时器T0中断初始化
{TMOD 0xF0;//配置定时器T0为16位定时器TMOD | 0x01;TL0 0x33; //定时器计1个数为1.085us则当舵机为0度的时候需要0.5ms, TH0 0xFE; //则定一个0.5ms的定时器TF0 0; //清除TF0标志TR0 1; //定时器0开始计时ET0 1;EA 1;
}void Timer1_Init(void)//定时器T1初始化
{//使用定时器1TMOD 0x0F;TMOD | 0x10;TL1 0;TH1 0;//设置定时器T1从0开始数数
}double get_distance()
{double time;TL1 0;TH1 0;//定时器清零以便下次测距//1、开始发波Trig 0;Trig 1;Delay10us();Trig 0;//2、检测ECHO引脚电平while(Echo 0);TR1 1; //启动定时器while(Echo 1);TR1 0; //关闭定时器//3、计算定时开到定时关的时间(计算数的个数)//2位二进制1101。合并位1101怎么算1101为(11*2^2)0113time (TH1 * 256 TL1) * 1.085; //us为单位//34000cm/s 34cm/ms 0.034cm/usreturn (time * 0.017); //cm为单位;
}void sg90_0(void) //舵机0度
{sg_90 1;//先给输出引脚一个高电平jd 1;//一上电开始占空比为1/40为0度cnt 0;
}void sg90_90(void)//舵机90度
{sg_90 1;//先给输出引脚一个高电平jd 3;//一上电开始占空比为3/40为90度cnt 0;
}void main(void)
{double dis;Timer0_Init();Timer1_Init();EX0_Init();sg90_0();while(1){Delay200ms();//先给单片机准备时间dis get_distance();if(dis 10 || SW1 0 || vib_mark 1){vib_mark 0;LED1 0;sg90_90();Delay2000ms();}else{LED1 1;sg90_0();Delay200ms();} }
}void Timer0_Handler() interrupt 1//中断函数
{cnt;TL0 0x33; TH0 0xFE;//控制PWM波的占空比if(cnt jd){sg_90 1;}else{sg_90 0;}if(cnt 40){cnt 0;sg_90 1;}
}void EX0_Handler() interrupt 0//触发中断0函数
{vib_mark 1;
}为什么我们使用震动传感器控制的时候不直接if(dis 10 || SW1 0 || vibrate 0)喃这样判断不是跟简单吗原因因为震动传感器因为震动而发出的低电平0不仅微弱而且时间比较断。当震动传感器给出低电平的时候而单片机还在执Delay2000ms();而当进入判断的时候可能震动传感器发出的低电平已经消失了已经变成高电平了。这样就会导致震动传感器不灵敏。所以通过外部中断来改变标志位这样就会规避这个问题。当震动时触发中断标志位变为1等待判断。只有进入判断后标志位才变回0。