感应开关垃圾桶小项目的完成及问题解决——基于STC89C52RC单片机
分为五个步骤,如下:
01代码_舵机
注意:舵机的使用不能自己用手将其旋转,可能导致舵机的损坏(本人因此弄坏一个,或许是使用的舵机太Low)
组装好后代码能够正常运行但开盖出现舵机“抽搐”的情况:
`voi`d openDusbin()`
`{
`
`char n;`
`jd = 3; //90度 1.5ms高电平`
`//舵机开盖`
`cnt = 0;`
`beep = 0;`
`for(n=0; n<2; n++)`
`Delay150ms();`
`beep = 1;`
`Delay2000ms();`
}`
在cnt重新变成0的时候“抽搐”
解决办法:
需要做一个标志位来判断,做一个变量保存上一次角度度数 **char jd_bak;**关盖同样添加jd_back=jd;
`void openDusbin()`
`{
`
`char n;`
`jd = 3; //90度 1.5ms高电平`
`//舵机开盖`
`if(jd_bak != jd) {
//如果上一次角度不等于本次角度则执行,否则不执行`
`cnt = 0;`
`beep = 0;`
`for(n=0; n<2; n++)`
`Delay150ms();`
`beep = 1;`
`Delay2000ms();`
`}`
`jd_bak = jd;`
`}`
02代码_测距开关盖-超声波测距、添加按键开盖、震动传感器
`sbit SW1 = P2^1;`
`sbit Trig = P1^5;`
`sbit Echo = P1^6;`
`sbit vibrate = P3^2;`
`void main()`
`{
`
`double dis;`
`Time0Init();`
`Time1Init();`
`EX0_Init();`
`//舵机的初始位置`
`initSG90_0();`
`while(1) {
`
`//超声波测距`
`dis = get_distance();`
`if(dis < 10 || SW1 ==0 || mark_vibrate ==1) {
//如果小于10cm,或者SW1按键被按下`
`//开盖,灯状态,D5亮`
`openStatusLight();`
`//舵机关盖`
`openDusbin();`
`mark_vibrate = 0;`
`} else {
`
`//灌溉,灯状态,D5灭`
`closeStatusLight();`
`closeDusbin();`
`}`
`}`
`}`
振动传感器不灵敏:采用的软件延时,相当于CPU数数。采用查询的方式,电平的转变有可能太急促,不稳定,倒置CPU数数的时候检测不到。振动传感器的优化:添加外部中断0,一旦发生震动,外部中断立马把标志位做好,CPU再查。
`void EX0_Init()`
`{
`
`//打开外部中断`
`EX0 = 1;`
`//低电平触发`
`IT0 = 0;`
`}`
中断处理函数
`char mark_vibrate = 0;`
`void Ex0_Handler() interrupt 0`
`{
`
`mark_vibrate = 1;`
`}`
05代码_测距开关盖-添加蜂鸣器开盖
`sbit beep = P2^0;`
`if`(jd_bak != jd) {
`
`cnt = 0;`
`beep = 0;`
`for(n=0; n<2; n++)`
`Delay150ms();`
`beep = 1;`
`Delay2000ms();`
}`
`for(n=0; n<2; n++)`
`Delay150ms();`
`beep = 1;`
`Delay2000ms();`
}`